前端面試5:原型鏈

明易發表於2018-12-05

課程思維導圖

原型鏈結構圖.png

Q:JavaScript如何建立物件?

// 字面量建立物件
var o1 = {name = "o1"};
var o2 = new Object({name : "o2"});
------------------------------------------
// 建構函式建立物件
var M = function () {
    this.name = "o3";
}
var o3 = new M();
------------------------------------------
// Object.create建立物件
var p = {name : 'o4'};
var o4 = Object.create(p);
複製程式碼

Q:原型、建構函式、例項、原型鏈的關係如何?

前端面試5:原型鏈

  1. javascript中的繼承是通過原型鏈來體現的。
  2. 每個物件都有一個__proto__屬性,指向建構函式的prototype。
  3. 訪問一個物件的屬性時,先在基本屬性中查詢,如果沒有,再沿著__proto__這條鏈向上找,這就是原型鏈。

注:我們可以通過hasOwnProperty方法來判斷一個屬性是否從原型鏈中繼承而來。

Q:instanceof的原理是怎樣的?

前端面試5:原型鏈

instanceof是原型鏈繼承中的重要環節,對instanceof的理解有利於理解原型鏈繼承的機制。

以A instanceof B為例

  1. instanceof的普通的用法,檢測B.prototype是否存在於引數A的原型鏈上。
  2. 繼承中判斷例項是否屬於它的父類

簡單理解就是沿著A的__proto__跟B的prototype尋找,如果能找到同一引用,返回true,否則返回false。

以下是一些示例:

// 由於函式也是物件,物件是函式建立的,所以有:
fn.__proto__ === Function.prototype
Object.__proto__ === Function.prototype
------------------------------------------
// Function是自身建立的,所以有:
Function.__proto__ === Function.prototype
------------------------------------------
// Function.prototype也是物件,所以有:
Function.prototype.__proto__ === Object.prototype
------------------------------------------
function Person() {}
console.log(Object instanceof Object);     //true

//第一個Object的原型鏈:Object=>Object.__proto__ => Function.prototype=>Function.prototype.__proto__=>Object.prototype
//第二個Object的原型:Object=> Object.prototype

console.log(Function instanceof Function); //true
//第一個Function的原型鏈:Function=>Function.__proto__ => Function.prototype
//第二個Function的原型:Function=>Function.prototype

console.log(Function instanceof Object);   //true
//Function=>
//Function.__proto__=>Function.prototype=>Function.prototype.__proto__=>Object.prototype
//Object => Object.prototype

console.log(Person instanceof Function);      //true
//Person=>Person.__proto__=>Function.prototype
//Function=>Function.prototype

console.log(String instanceof String);   //false
//第一個String的原型鏈:String=>
//String.__proto__=>Function.prototype=>Function.prototype.__proto__=>Object.prototype
//第二個String的原型鏈:String=>String.prototype

console.log(Boolean instanceof Boolean); //false
//第一個Boolean的原型鏈:
Boolean=>Boolean.__proto__=>Function.prototype=>Function.prototype.__proto__=>Object.prototype
//第二個Boolean的原型鏈:Boolean=>Boolean.prototype

console.log(Person instanceof Person); //false
//第一個Person的原型鏈:
Person=>Person.__proto__=>Function.prototype=>Function.prototype.__proto__=>Object.prototype
//第二個Person的原型鏈:Person=>Person.prototype
複製程式碼

Q:new運算子的實現機制?

var new2 = function (func) {
    var o = Object.create(func.prototype);
    var k = func.call(o);
    if (typeof k === 'object') {
        return k;
    } else {
        return o;
    }
}
複製程式碼
  1. 建立一個新物件,繼承自func.prototype
  2. 執行建構函式,this會指向新建立的物件
  3. 如果建構函式返回一個物件,則該物件便是new出來的結果,如果建構函式沒有返回物件,那麼new出來的結果為步驟1建立的物件。

相關文章