圖說原型鏈

前言

說到原型鏈,javascript 中,萬物皆對象,而 javascript 規定,全部對象都有本身的原型對象(prototype) ,一方面,任何對象均可以充當其餘對象的原型,另外一方面,原型(prototype)也是對象,也擁有本身的原型,所以造成的鏈就是原型鏈。到這裏我就囉嗦幾句,javascript 的設計者Brendan Eich在設計這門語言之初,只是想它在網頁上實現簡單的交互,好比表單提交前進行簡單的校驗,因此沒有設計類與繼承的概念,由於以爲這樣的話太正式了,可是受時代的影響,javascript裏面都是對象,雖然沒有繼承,可是也要一種機制,把這些對象聯繫起來,這種機制就是原型鏈。話很少說,上圖javascript

圖解

  • 假設有一個內存空間(正方形表示),這片內存裏放了一個構造函數Dog(用三角形表示)
function Dog () {
    this.leg = 4;
    this.bray = function () {
        alert('wangwang');
    }
}

圖片描述

  • 設置構造函數的原型函數(prototype)
Dog.prototype = {
    spacies: 'dog'
}
console.log(Dog.prototype)    // {spacies: 'dog'}

那麼,就會在另一個內存中存儲 Dog 的 prototype 對象(用橢圓形表示),如圖所示,構造函數的protype指向它的原型
圖片描述html

  • 如今咱們用 構造函數 Dog 來建立對象 dog1, dog2, ...
var dog1 = new Dog();
dog1.name = '大黃';
dog1.color = 'yellow';

var dog2 = new Dog();
dog2.name = '小黑';
dog2.color = 'black';

console.log(dog1.name)     // 大黃
console.log(dog2.name)     // 小黑
console.log(dog1.spacies)  // dog
console.log(dog2.spacies)  // dog
console.log(dog1.constructor === Dog)   // true

圖片描述

能夠看到由構造函數創造的對象dog1,dog2,他們的constructor指向構造函數Dog,而他們的__proto__指向Dog的prototype,並且當調用對象的一個屬性或方法時,首先會找對象自己的屬性或方法,找不到時,會找該對象的__proto__對象(也就是構造函數的prototype對象),以此類推,會找原型鏈上全部對象有沒有該屬性,若是找到則返回該屬性的值,若是仍是找不到則返回undefined
另外能夠看出來dog1,dog2,...的__proto__指向同一塊內存地址,這樣設計是爲了節省內存資源,不用每次建立都存儲他們相同的屬性,當修改dog1的__proto__時,dog2的__proto__也會改變java

dog1.__proto__.spacies = 'animal'; // 或者Dog.prototype.spacies = 'animal'
console.log(dog2.spacies)    // animal
  • 上面也說到了,每個對象都有本身的__proto__,而做爲構造函數Dog的prototype對象,也會有本身的對象原型,以此類推,原型鏈的頂端是一個null,如圖的紅線串起來的鏈就是原型鏈

圖片描述

額,來一個句話收尾吧,這是我本身對原型連的理解,歡迎探討ide

參考

Javascript繼承機制的設計思想
prototype 對象函數

相關文章
相關標籤/搜索