原型对象(prototype)概念
在构造函数创建出来的时候,系统会默认帮构造函数创建并关联的一个新对象
自定义构造函数的原型对象默认是一个空对象。
原型对象(prototype)作用
构造函数中的原型对象中的属性和方法可以被使用该构造函数创建出来的对象共享使用。
即以自定义构造函数方式创建出来的所有对象,自动拥有和共享该构造函数的原型对象中的所有属性和方法。
访问原型对象的方法
- 构造函数.prototype
- 对象._proto_ (不推荐)
- Object.getPrototypeOf(对象)
设置原型对象的属性和方法
- 利用对象的动态特性来为构造函数的原型对象添加属性和方法
- 替换原型对象
原型对象的使用方法
- 利用对象的动态特性给原型添加属性|方法(如果要添加的方法过多,则有大量重复代码)
- 直接替换原型对象
- 替换前后创建的对象所指向的原型对象不一致
- 替换原型对象会切断和之前的原型对象之间的关系
原型对象的使用注意
- 访问属性:构造函数创建出来的对象在访问属性的时候,会先在实例内查找,如果没有找到则进一步到对应的原型对象中查找
- 设置属性:在使用点语法进行赋值的时候,无法操作到对应的原型对象
- 如果该属性在对象中已经存在,则修改该属性的值
- 如果该属性在对象中尚未存在,则新增该属性
- 设置原型对象的属性
- 设置原型对象的属性,只能通过构造函数.Prototype的方式|替换原型对象的方式设置
- 如果原型对象的属性是值类型,那么只能通过Person.prototype.属性的方式修改其值
- 如果原型对象的属性是引用类型,那么可以通过对象名.引用对象.属性名的方式设置|修改
- 使用构造函数创建出来的多个对象的原型对象中的该属性指向的是同一块数据
- 某个对象对该原型对象属性进行了修改会影响到其他的对象
示例代码
function Car(color,wheel){
this.color = color;
this.wheel = wheel;
}
//instanceOf 判断构造函数的原型对象是否在当前对象的原型链上面
var car1 = new Car('white',4);
console.log(car1 instanceof Car); //true
Car.prototype = {
constructor:Car,
run: function () {
console.log("running");
},
stop: function () {
console.log("stop");
},
owner:'洋洋'
};
console.log(car1 instanceof Car); //false
// car1.run(); //报错
var car2 = new Car('black',4);
var car3 = new Car('green',4);
注意:
- car1这个对象是在该构造函数的原型对象前创建的,当Car没有通过字面量方式声明原型对象时,car1 instanceof Car为true;当Car通过字面量方式新声明原型对象时,car1 instanceof Car为false;
A instanceof B,当且仅当B在A的原型链上时,结果才为true,否则为false
instanceof注意点.png
如上图,也因此car1访问不到新的原型对象,一旦访问自身没有而原型对象中存在的属性或者方法,则报错。 - 当在新的原型对象中没有定义属性constructor:Car时,该原型对象的constructor指向Object。因此如下:
console.log(Car.prototype.constructor == Car); //false
console.log(Car.prototype); //Object
console.log(car2.__proto__); //Object
console.log(Object.getPrototypeOf(car2)); //Object
console.log(Car.prototype.constructor); //Object
console.log(car2.__proto__.constructor); //Object
console.log(Object.getPrototypeOf(car2).constructor); //Object
- 当car2修改owner属性为乔乔时,此时并没有修改原型对象中的owner属性,只是给car2自身增加owner属性,故car3的owner依旧是原型对象中的owner,为洋洋。
car2.owner = '乔乔';
console.log(car2.owner); //乔乔
console.log(car3.owner); //洋洋
console.log(car2.hasOwnProperty('owner')); //true
console.log(car3.hasOwnProperty('owner')); //false
- 当其中一个实例修改原型对象中的引用类型的值时,则共享数据的所有实例访问原型对象中该值时,均会改变。
网友评论