一直致力於使用ES6寫ReactNative,對之前的Javascript瞭解較層面。所以,趁疫情機會抽出時間來對JavaScript 解釋原型鏈(原型繼承)
深入理解下。
·原型(prototype):
一個簡單的對象,用於實現對象的屬性與能力的繼承。在 Firefox 和 Chrome 中,每個JavaScript對象中都包含一個__proto__ (非標準)的屬性指向它的父親(該對象的原型),以obj.__proto__進行訪問。
·構造函數:
可以通過new來 新建一個對象 的函數。
·實例:
通過構造函數和new創建出來的對象,便是實例。 實例通過__proto__指向原型,通過constructor指向構造函數。
上面的這張圖我覺得是具有非凡意義的,能夠系統直觀的給我們展示JS原型繼承系統的模式。
遵照上圖手動編寫對應的代碼,並執行來驗證上面的圖所帶給我們的意義!
圖示有表示:對象實例 f1 的原型指針(_proto) 指向原型對象
在VSCode 終端(node環境下)執行命令:node .\JS-Test\js-test.js
可以看到,圖示和編碼驗證是一致的。
圖示有表示:每個構造函數(Foo)都有一個原型對象(prototype
),原型對象(Foo.prototype)都包含一個指向構造函數的指針(constructor
)
承接上面的驗證,繼續編寫代碼第8、9行 ~
在VSCode 終端(node環境下)執行命令:node .\JS-Test\js-test.js
可以看到,圖示和編碼驗證依然是一致的。
圖示上來看,Foo.prototype 是 Object 的對象實例
即 Foo.prototype的原型指針 指向 Object.prototype
承接上面的驗證,繼續編寫代碼第11、12和13行 ~
在VSCode 終端(node環境下)執行命令:node .\JS-Test\js-test.js
可以看到,圖示和編碼驗證依然是一致的。
圖示上來看,JavaScript中的對象,追根溯源都是來自一個Null對象 ?
即Object.prototype 是 Null的對象實例[Object繼承自Null]
承接上面的驗證,繼續編寫代碼第15、16和17行 ~
在VSCode 終端(node環境下)執行命令:node .\JS-Test\js-test.js
可以看到,圖示和編碼驗證依然是一致的!
結合上圖以及手動編碼,突然產生了疑惑並在這裏再次編碼驗證解疑:
什麼疑惑?f1.prototype 和 Foo.prototype 有什麼關係、區別!
在VSCode 終端(node環境下)執行命令:node .\JS-Test\js-test.js
由下面結果可以看到 f1.prototype 不存在,則f1.prototype.constructor也是不存在的!
function Foo() {}
let f1 = new Foo();
function MyFunction() {}
let mf1 = new MyFunction();
f1.prototype = mf1;
//MyFunction 隱式的 繼承(extends) 了Object
從上面編碼的驗證,可知我們通過
__proto__
可以訪問到它所繼承的原型對象。
從上面的代碼塊,可知:
** 解釋原型鏈 **
如果我們讓Foo的原型對象(f1.prtotype)等於MyFunction的對象實例,那麼
一個函數(Foo)的原型對象(f1.prototype)將會包含(擁有)一個指向某函數原型(MyFunction.prototype)的原型指針(__proto__
),即f1.prototype.__proto__ === MyFunction.prototype
。相應的某函數原型(MyFunction.prototype)中也會有一個指向另外一個函數原型(Object.prototype)的指針(__proto__
); 此時如果MyFuction的原型對象(MyFunction.prototype)又變成另外一個函數的對象實例,那麼這個原型鏈就被銜接住啦
參考文章:
參考https://juejin.im/entry
參考https://juejin.im/post
參考https://juejin.im/post