原型概念:
所有对象都有一个私有的 _proto_ 属性,而这个属性所对应的就是自身的原型;
原型链概念:
所有对像都有一个私有的 _proto_ 属性,而这个属性所指向的就是原型对象,它的原型对象又会有自身的原型对象,层层向上直至原型对象为null,那么这一过程就形成原型链;
我们通常比较容易混淆 prototype 和 _proto_,那么他们有什么区别呢?
prototype 属性:是函数所特有的,它是从一个函数指向一个对象,属于函数的原型对象,也就是这个函数(其实所有函数都可以作为构造函数)所创建的实例的原型对象; 这个属性是一个指针,指向一个对象,这个对象的用途就是包含所有实例共享的属性和方法(我们把这个对象叫做原型对象);
_proto_属性:这是每个对象(除null外)都会有的属性,是原型链查询中实际用到的,指向prototype(即指向构造函数的原型对象),是对象所特有的。注意,为什么Foo构造也有这个属性呢,因为在js的宇宙里万物皆对象,包括函数;
总结:
- __proto__ 是原型链查询中实际用到的,它总是指向 prototype;
- prototype 是函数所独有的,在定义构造函数时自动创建,它总是被 __proto__ 所指。
原型链继承:
- 创建一个父构造函数;
- 创建一个子构造函数;
- 设置子构造函数的原型对象是父构造函数的实例 --- 实现原型链继承;
function A() {this.name = "默认";this.showName = function () {console.log(this.name);} } A.prototype.logDes = function () {console.log("des"); }function B() {}// 实现了原型链继承 B.prototype = new A();var b1 = new B();console.log(b1.name); b1.showName();
原型链继承注意:
- 修正构造器属性要在:设置原型链继承之后;
- 设置原型对象的属性要在:设置原型链继承之后;
- 设置原型链继承后,只能利用对象的动态特性设置原型对象,不能使用字面量的方式;