【Javascript 基礎】原型鏈

93發表於2018-06-14

原文:【Javascript 基礎】原型鏈(你的 star 是對我寫作的「正反饋」)。

一、當初,為什麼要為 JS 設計原型鏈?

當初,設計 Javascript這門語言時,作者既想該語言擁有「萬物皆物件」的優點,又不想加入類的概念來增加語言的複雜度。

因此,作者提出了原型鏈(prototype chain)的概念,用來「連線」多個物件,使多個物件可以共享同一份變數,讓「繼承」成為了可能。

二、__proto__、prototype、constructor 各自代表了什麼?

  • __proto__: 通常指向當前物件對應的建構函式中的 prototype ,所有的物件都會有這個屬性。

這裡的「通常」指的是「非JS內建的物件」。而對於「JS內建的物件」,我建議:「硬記」~

  • prototype: 這就是所謂的原型,只有建構函式才有該屬性。

  • constructor: 生成當前物件的建構函式,所有物件都有建構函式。

相較於那些枯燥的等式,結合下圖,或許能夠更快的理清各種的連線關係。

js_prototype_chain

三、JS 物件的尋值邏輯

js_prototype_chain_2

四、幾個衍生出來的面試題

  1. 能否寫一個與 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); // 旺財
複製程式碼
  1. 如下程式碼,輸出什麼?
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

相關文章