概念
原型链查找就是通过 __proto__
查找,查找至值为 null ( Object.prototype
)时结束。
__proto__
是原型链查找中用到的,它总是指向 prototype
;
prototype
在定义构造函数时自动创建,它总是被 __proto__
所指。
prototype
与__proto__
的区别
prototype
只有构造函数才有的属性,__proto__
是任何一个对象都有的属性
结合一个很简单的小例子来看看:
var o1 = {
o2: { a: 1, b: 2}
};
console.log(o1);
var o4 = {
msg: '我是o4',
bar: function () {
console.log(this.msg);//此时this指向的是o4
// console.log(o4.msg);
}
};
var o2 = {
fn: function () { console.log('我是o2的fn方法') }
};
var o3 = {
msg: '我是o3'
};
o2.__proto__ = o4;
o3.__proto__ = o2;
// o3 ---> o2 ---> o4 原型链 【对象的属性(方法) 的查找】
o4.bar(); // '我是o4'
o3.bar(); // '我是o3'
o2.bar(); // '我是o4'
从这个例子可看出,o3—>o2—>o4这里就形成了一个原型链,首先o3在自己那里找没找到之后,就去o2原型那儿去找,因为在前面将o2给了o3的原型,之后就再去找o4的,直到找到Object.prototype.
原型链存在的不足
- 当原型链中包含引用类型值的原型时,该引用类型值会被所有实例共享;
- 在创建子类时,不能向父类(也叫超类型)的构造函数中传递参数。
解决办法:借用构造函数,也就是在子类构造函数的内部调用父类构造函数。
function Father(){
this.num= [1, 3, 4, 5, 6];
}
function Son(){
Father.call(this);//继承了Father,并且向父类型传递参数
}
var number = new Son();
number.num.push(2);
console.log(number.num);//1, 3, 4, 5, 6, 2
var number1= new Son();
console.log(number1.num);//1, 3, 4, 5, 6
这个例子中call借调了父类,并继承了,解决了引用类型值会被共享这个问题,同时也给父类中传入了参数。
整理的就这么多,主要靠自己的理解,如有错误,请指出一下,谢谢