原型对象
原型对象的使用方法
- 利用对象的动态特性给原型对象添加成员
- 直接替换原型对象
注意:在替换原型之前创建的对象的原型和在替换原型对象之后创建的对象的原型不是同一个
使用原型的注意事项:
- 使用对象访问属性的时候,如果本身内找不到就会去原型中查找。但是使用点语法进行赋值的时候,并不会去原型中进行查找。使用点语法进行赋值的时候,对象中不存在该属性,就会给该对象新增属性,而不会去修改原型中的属性。
- 如果在原型对象中的属性是引用类型的属性,那么所有的独享共享该属性,并且任何一个对象修改了该引用类型属性的成员,其他对象也会受到影响,这种操作可以被认为是一种地址传递修改值的操作。
- 一般情况下不会将属性放到原型对象中。一般情况下原型里只会放共享的方法。
访问原型的方法:
- 通过构造函数访问原型对象
1 function Person(name.age){ 2 this.name=name; 3 this.age=age; 4 }
Person.prototype,通过这种方式可以访问原型对象
- 通过对象(实例)访问原型对象
var p = new Person("曹操",45);
p.__proto__(一边是连个英文下划线),__proto__是一个非标准属性,这个属性不推荐使用,主要用来调试
新的原型对象替换默认的原型对象的问题:
新的原型对象替换默认的原型对象的之后,原型对象中的constructor属性会变成Object,为了保证整个 构造函数---原型---对象之间的关系的合理性,应做这样的操作:在替换原型对象的时候,在新的原型对象中手动添加constructor属性。
什么是constructor属性?
原型对象在创建的时候,默认会有一个constructor属性,这个属性实际上是以一个指针,指向了对应的构造函数。
我们借助一个案例来理解,构造函数---原型对象---实例这三者之间的关系,首先看如下程序:
1 function Person(){//构造函数 2 3 } 4 Person.prototype.name = "曹操";//通过原型对象给属性赋值 5 Person.prototype.age = 45; 6 Person.prototype.job = "老大"; 7 Person.prototype.sayName = function(){ 8 alert(this.name); 9 } 10 var person1 = new Person();//创建对象实例 11 var person2 = new Person();
画图解释三者之间的关系如下:
从图中可以得知构造函数有一个属性prototype,指向了构造函数的原型对象。构造器函数的原型对象有一个constructor属性,指向了原型对象的构造函数。通过实例化得到的对象实例有一个属性[[prototype]]指向构造函数的原型对象。
它们之间的访问关系可以用下图表示: