function Rectangle(width, height){
this.width = width;
this.height = height;
this.getArea = function(){
return '矩形的面积为' + (width * height);
}
}
var rect1 = new Rectangle(40, 20);
var rect2 = new Rectangle(50, 20);
var rect3 = new Rectangle(60, 20);
console.log(rect1.getArea());
console.log(rect2.getArea());
console.log(rect3.getArea());
如上代码,每次实例化出一个对象,都会添加getArea这个属性,它是三个对象共有且不变的,因此将getArea放在构造函数中就会在创建对象时被多次添加,浪费内存!
因此我们将getArea属性添加到原型对象上就减少了多次添加,实例化对象会沿着原型链查找到此属性
实现了共享该属性:
function Rectangle(width, height){
this.width = width;
this.height = height;
}
/*
将此getArea属性定义在构造函数的原型对象中,就不会被重复添加了
实例化对象会沿着原型链查找到此属性
*/
Rectangle.prototype.getArea = function(){
return '矩形的面积为' + (this.width * this.height);
}
var rect1 = new Rectangle(40, 20);
var rect2 = new Rectangle(50, 20);
var rect3 = new Rectangle(60, 20);
console.log(rect1.getArea());
console.log(rect2.getArea());
console.log(rect3.getArea());
console.log(rect1);
// 但是添加到原型对象上的getArea属性的特性是可遍历的,所有使用in遍历时,会被遍历出
for(var key in rect1){
console.log(key); // width, height, getArea
}
// 所以更改属性设置
Object.defineProperty(Rectangle.prototype, 'getArea', {
enumerable: false,
writable: false,
configurable: false
});
for(var key in rect1){
console.log(key); // width, height
}
第二种添加到原型对象上的方式:
// 第二种方式
function Rectangle(width, height){
this.width = width;
this.height = height;
}
// 直接替换原型对象,但是要记得添加上构造函数属性
Rectangle.prototype = {
constructor: Rectangle,
getArea: function(){
return '矩形的面积为' + (this.width * this.height);
}
}
// 修改特性
Object.defineProperties(Rectangle.prototype, {
constructor: {
enumerable: false,
configurable: false,
writable: false
},
getArea: {
enumerable: false,
configurable: false,
writable: false
}
})
var rect1 = new Rectangle(40, 20);
var rect2 = new Rectangle(50, 20);
var rect3 = new Rectangle(60, 20);
console.log(rect1.getArea());
console.log(rect2.getArea());
console.log(rect3.getArea());
console.log(rect1);