从上一篇日志中我们注意到,每添加一个属性和方法就要敲一遍Person.prototype.为了减少不必要的输入。更常见的一种做法是用
一个包含所有属性和方法的对象字面量来重写整个原型对象。如下:
function Person(){
}
Person.prototype={
name:"windy",
age:"19",
act:function(){console.log(this.name)}
};
var friend=new Person()
console.log(friend instanceof Object); //true
console.log(friend instanceof Person); //true
console.log(friend.constructor==Person);//false
console.log(friend.constructor==Object);//true
如上代码,将Person.prototype设置为等于一个以对象字面量形式创建的对象。最终结果也相同。但是有一个例外:constructor属性不再指向Person。
每创建一个函数,就会同时创建它的prototype对象。这个对象也会自动获得constructor属性。而我们在这里使用的语法,本质上完全重写了默认的prototype对象,
因此constructor属性也就变成了新对象的constructor属性(指向Object),而不再指向Person.
修改如下:
function Person(){
}
Person.prototype={
constructor:Person,
name:"windy",
age:"19",
act:function(){console.log(this.name)}
};
var friend=new Person()
console.log(friend instanceof Object); //true
console.log(friend instanceof Person); //true
console.log(friend.constructor==Person);//true
console.log(friend.constructor==Object);//false
以上代码特意包含了一个constructor属性,并将它的值设置为Person,从而确保了通过该属性能够访问到适当的值。
原型对象的问题:
例子:
function Person(){
}
Person.prototype={
constructor:Person,
name:"windy",
age:"19",
friend:["justin","ben"],
act:function(){console.log(this.name)}
};
var person1=new Person();
var person2=new Person();
person1.friend.push("VAN");
console.log(person1.friend);//["justin","ben","WAN"]
console.log(person2.friend);//["justin","ben","WAN"]
我们给person1的friend属性新增“VAN”,但是打印之后可以看到,根本没有新增到数组中去。解决办法:组合使用构造函数与原型
构造函数用于定义实例属性,而原型用于定义共享的属性。结果,每个实例都会有自己的一份实例属性的副本,但同时又共享着对方的方法的引用,最大
限度的节省内存。
优化后代码:
function Person(name,age,friend){
this.name=name;
this.age=age;
this.friend=["justin","ben"];
}
Person.prototype={
constructor:Person,
act:function(){console.log(this.name)}
};
var person1=new Person();
var person2=new Person();
person1.friend.push("VAN");
console.log(person1.friend);//["justin","ben","WAN"]
console.log(person2.friend);//["justin","ben"]