说到原型链,想到前几年刚学习的时候看到的图,相信大家不陌生,现在想起来,这图确实有点画蛇添足了。
当初也是反反复复才搞懂原型链,走了不少弯路,希望看到这篇文章的你,能一次搞懂。
如果你不理解原型,熟记3句话
函数可以认为是一个对象,它有一个属性叫prototype;(假设函数名是Test)
prototype是一个对象,它有一个属性叫constructor,constructor就是函数Test
new Test()生成一个对象,该对象有个属性叫__proto__,和函数Test的prototype是同一个对象
用代码帮助理解就是
function Test() {
this.id = 0;
}
// 可认为Test是下面这个对象
// {
// prototype: {
// construtor:Test
// }
// }
let test= new Test();
// test就是下面这样的
// {
// id: 0
// __proto__: Test.prototype,
// }
Test.prototype.constructor===Test; // true
test.__proto__=== Test.prototype; // true
上面这两个判断就不言而喻了。
那么原型链又是什么呢?一句话解释
访问一个对象的属性,如obj.id,如果找不到,就找obj.__proto__.id,再找不到就去obj.__proto__.__proto__.id...直到__proto__为null
看这样一段代码
function A() {
this.id = 1
}
function B() {
}
let a = new A();
let b = new B();
如果我们想让b有a的id,会怎么做?
我们知道a是{id:1},结合原型链的解释,让 b.__proto__=a 。因为访问b.id,没有,就会访问b.__proto__,发现为{id:1},找到了!
//b.__proto__=a可转换为
//B.prototype =new A();
//因为b.__proto__===B.prototype
//a = new A();
好了,如果不考虑其他问题,让B.prototype=new A(),就实现了继承。
但是现在有点小问题,B.prototype.constructor变成A了,所以会有一个修正的操作
B.prototype.constructor = B
好了,现在就实现了一个简单的继承
function A() {
this.id = 1
}
function B() {
}
B.prototype = new A();
B.prototype.constructor =B;
let b = new B();
相信你现在对原型和原型链已了如指掌了!可以快乐地 js 的知识海洋中遨游