(自己的老博客搬运)createdAt:2017-01-26 23:18:03
构造器
其实构造器就是方法,只是当你用new调用它的时候它就是构造器了(new的作用参见javascript关键字new)。
var Person=function (name,age){//这就是个Person的构造器
this.name=name;
this.age=age;
this.hobbies=['Drawing','Music'];
};
Person.prototype={//这是Person的原型
constructor:Person,
sex:'Male',
friends:['Lihua','Oliver'],
getName:function () {
return this.name;
}
};
原型不大清楚的可以参考这篇 javascript 原型与构造器之‘原型’ ^ ^~
创建对象本身的属性
上面的构造器里形如this.name=name的代码,都是在给 对象自身 添加属性,
于是通过该构造器创建的 实例本身 也就拥有了相应的属性。
与原型的属性不同,原型的属性是实例共享的,而构造器创建的属性,是每个实例独自拥有的。
代码示例
下面的代码基于上面Person的构造器和原型
var person1=new Person('Lily',18);
var person2=new Person('Amy',24);
person1.sex='Female';
console.log(person1.sex);//Female
console.log(person2.sex);//Male
person1.friends.push('Selena');
console.log(person1.friends);//Lihua,Oliver,Selena
console.log(person2.friends);//Lihua,Oliver,Selena
person1.friends=['Lihua'];
console.log(person1.friends);//Lihua
console.log(person2.friends);//Lihua,Oliver,Selena
person1.hobbies.push('Movie');
console.log(person1.hobbies);//Drawing,Music,Movie
console.log(person2.hobbies);//Drawing,Music
比较两个push的不同~
(除这4行输出外不理解的话可以看下我的上一篇博客~)javascript 原型与构造器之‘原型’
- person1.friends的push,对两个实例都产生了影响;
- person1.hobbies的push仅对person1产生了影响。
- 因为friends是原型的属性,实例共享;而hobbies是实例的属性,每个实例都有自己独立的。
避免实例间属性干扰
所以~要解决,像代码中‘改变person1的friends时,无意中也把person2的friends改了’这种情况,
可以把该属性从原型中转移到构造器里~就好啦~
原型 vs 构造器
下面这些结论都是我看书啊听课啊学到的+自己总结的~~不是那么绝对~~欢迎讨论~~
- 实例独立的属性都放在构造器里:
- 相当于java里面类的成员变量。
- 为了避免上述‘friends’的类似情况。
- 但是又会有疑问,如果不是数组类型呢,比如String类型的name,
- 上一篇不是说赋值的时候解释器会自动在实例上创建属性吗。
- 确实,从实现的角度看确实不会产生实例间的干扰了。但是自动创建属性的话,实例和原型就都拥有了该属性,而原型的该属性就会永远被屏蔽,占着空间却没卵用的数据,会对性能造成影响的。
- ‘静态属性’放在原型里:
- ‘静态属性’是指基于同一个原型的实例们都一样的属性。
- 这种属性如果在构造器里,每个实例各自有一个,反而白占了很多空间
- 方法放在原型里:
- 这个跟上一条是一样的道理,就像java里面,类的方法一样,每个对象都是一样的呀~
- 也就没有每个实例都独自持有一份的必要啦。
本文涉及的源码可以戳这里^ ^(还包含javascript系列的其他部分的源码哦)
参考