1、JS中的继承
当谈到继承时,JavaScript 只有一种构造:对象。每个实例对象(object)都有一个公有属性(称之为 proto )指向它的构造函数的原型对象(prototype)。
该原型对象也有一个本人的原型对象(__proto__),层层向上直到一个对象的原型对象为null
。依据定义,null
没有原型,并作为这个原型链中的最初一个环节。
2、继承属性
JavaScript 对象是动静的属性“包”(指其本人的属性)。JavaScript 对象有一个指向一个原型对象的链。
当试图拜访一个对象的属性时,它不仅仅在该对象上搜查,还会搜查该对象的原型,以及该对象的原型的原型,顺次层层向上搜寻,直到找到一个名字匹配的属性或达到原型链的开端。
3、创立原型链的Demo
// 让咱们从一个函数里创立一个对象o,它本身领有属性a和b的:let f = function () { this.a = 1; this.b = 2;}/* 这么写也一样function f() { this.a = 1; this.b = 2;}*/let o = new f(); // {a: 1, b: 2}// 在f函数的原型上定义属性f.prototype.b = 3;f.prototype.c = 4;// 不要在 f 函数的原型上间接定义 f.prototype = {b:3,c:4};这样会间接突破原型链// o.[[Prototype]] 有属性 b 和 c// (其实就是 o.__proto__ 或者 o.constructor.prototype)// o.[[Prototype]].[[Prototype]] 是 Object.prototype.// 最初o.[[Prototype]].[[Prototype]].[[Prototype]]是null// 这就是原型链的开端,即 null,// 依据定义,null 就是没有 [[Prototype]]。// 综上,整个原型链如下:// {a:1, b:2} ---> {b:3, c:4} ---> Object.prototype---> nullconsole.log(o.a); // 1// a是o的本身属性吗?是的,该属性的值为 1console.log(o.b); // 2// b是o的本身属性吗?是的,该属性的值为 2// 原型上也有一个'b'属性,然而它不会被拜访到。// 这种状况被称为"属性遮蔽 (property shadowing)"console.log(o.c); // 4// c是o的本身属性吗?不是,那看看它的原型上有没有// c是o.[[Prototype]]的属性吗?是的,该属性的值为 4console.log(o.d); // undefined// d 是 o 的本身属性吗?不是,那看看它的原型上有没有// d 是 o.[[Prototype]] 的属性吗?不是,那看看它的原型上有没有// o.[[Prototype]].[[Prototype]] 为 null,进行搜寻// 找不到 d 属性,返回 undefined