原文:【Javascript 基础】原型链(你的 star 是对我写作的「正反馈」)。
一、当初,为什么要为 JS 设计原型链?
当初,设计 Javascript这门语言时,作者既想该语言拥有「万物皆对象」的优点,又不想加入类的概念来增加语言的复杂度。
因此,作者提出了原型链(prototype chain)的概念,用来「连接」多个对象,使多个对象可以共享同一份变量,让「继承」成为了可能。
二、__proto__、prototype、constructor 各自代表了什么?
__proto__
: 通常指向当前对象对应的构造函数中的prototype
,所有的对象都会有这个属性。
这里的「通常」指的是「非JS内置的对象」。而对于「JS内置的对象」,我建议:「硬记」~
-
prototype
: 这就是所谓的原型,只有构造函数才有该属性。 -
constructor
: 生成当前对象的构造函数,所有对象都有构造函数。
相较于那些枯燥的等式,结合下图,或许能够更快的理清各种的连接关系。
三、JS 对象的寻值逻辑
四、几个衍生出来的面试题
- 能否写一个与
New
关键字功能类似的NEW
方法 ?
function NEW(fn) {
if (!fn.prototype) {
throw('不是构造函数');
return;
}
var obj = {};
var args = Array.prototype.slice.call(arguments, 1);
obj.__proto__ = fn.prototype;
obj.constructor = fn;
fn.apply(obj, args);
return obj;
}
function Dog(name) {
this.name = name;
}
Dog.prototype.species = 'animal';
var dog = NEW(Dog, '旺财');
console.log(dog.name); // 旺财
复制代码
- 如下代码,输出什么?
function Aoo() {}
function Foo() {}
Foo.prototype = new Aoo();
var foo = new Foo();
console.log(foo instanceof Foo);
console.log(foo instanceof Aoo);
复制代码
解释:instanceof
除了会判断对象本身的类型,还会判断对象的 __proto__
的类型,其伪码大致如下:
function instance_of(L, R) {//L 表示左表达式,R 表示右表达式
var O = R.prototype;// 取 R 的显示原型
L = L.__proto__;// 取 L 的隐式原型
while (true) {
if (L === null)
return false;
if (O === L)// 这里重点:当 O 严格等于 L 时,返回 true
return true;
L = L.__proto__;
}
}
复制代码
答案:true true