JavaScript Prototypal Inheritance 的原理

本文源自 @NoteCode 引用的 Vjeux 文章 Javascript – How Prototypal Inheritance really works,闡述了 原型編程 的工作原理,這里記錄一下理解要點(diǎn)。

下面這個代碼片段說明了 JS 引擎是如何獲取一個屬性的:

function getProperty(obj, prop) {
    if (obj.hasOwnProperty(prop)) 
        return obj[prop]  
    else if (obj.__proto__ !== null) 
        return getProperty(obj.__proto__, prop)  
    else 
        return undefined
}
原型繼承的寫法
var Point = {
  x: 0,
  y: 0,
  print: function () { console.log(this.x, this.y); }
};
 
var p = {x: 10, y: 20, __proto__: Point};
p.print(); // 10 20
大部分教科書的寫法
function Point(x, y) {
  this.x = x;
  this.y = y;
}
Point.prototype = {
  print: function () { console.log(this.x, this.y); }
};
 
var p = new Point(10, 20);
p.print(); // 10 20

這是什么鬼東西嘛!和原型繼承完全不同! Point 成了函數(shù),prototype 成了 Point 的一個屬性!

new 運(yùn)算符做了些什么?

原來 Brendan_Eich 在實(shí)現(xiàn) JS 時,為了效仿 JAVA,寫了 new 運(yùn)算符。
new 運(yùn)算符 函數(shù) F 和其參數(shù) arguments:new F(arguments...),三步:
1. 創(chuàng)建類實(shí)例
這里的類就是 function F,創(chuàng)建了一個空對象,其屬性 __proto__ 賦值為 F.prototype。
要注意破除思維定式,在語義上,我們把具有類含義的 function 名字的首字母大寫;
2. 初始化這個實(shí)例
調(diào)用 function F,傳參 arguments,this 指向這個實(shí)例;
3. 返回這個實(shí)例;

prototype 就是 '基類'

每個對象都有一個 prototype,每個 prototype 也是一個對象。每個對象是通過自己的 prototype 來繼承屬性和方法的;

constructor @ ES6
constructor 是一個函數(shù)對象,用于創(chuàng)建和初始化對象;
constructor 的 prototype 屬性是一個 prototype 對象,可以用來實(shí)現(xiàn)繼承和共享屬性;

prototype @ ES6

prototype 是一個對象,提供了供其他對象使用的共享屬性;
當(dāng) constructor 創(chuàng)建對象時,該對象隱性指向 constructor 的屬性 prototype,目的是為了解決屬性指向問題;可以使用 constructor.prototype 引用該屬性;
prototype 里面的屬性是共享的;所有對象通過繼承共享了該 prototype;一個對象也可以通過 Object.create 這個內(nèi)置函數(shù)來創(chuàng)建。

我的理解是用prototype指定的屬性方法其實(shí)就是java對象的static修飾下的屬性方法,不過作為腳本語言,這樣的設(shè)計(jì)也是非常合理的。
特點(diǎn)就是共享的,只有一份;

只有對象,沒有 '類';
通常一個對象 O 如果要作為被繼承對象,只會設(shè)計(jì)該對象 O 的構(gòu)造函數(shù)和設(shè)計(jì)該對象 O 的屬性 prototype,而通常不會再設(shè)計(jì)該對象 O 的其他屬性;
prototype-chain 鏈就是指針;
prototype 是一種隱式引用組合(因引用而共享);

o.prototype.ps1 = "property-shared-1"; 這叫修改所有對象ps1的值
o2.ps1 = "x"; 這叫覆蓋;

constructor prototype 備注
CF(arguments...){...} CF.prototype={...}
CF.p1 p1 是一個屬性 p1 屬 CF 私有
contructor 中出現(xiàn)的屬性 可繼承的屬性,new 對象中可訪問;

contructor function
contructor property
prototype function
prototype property

關(guān)于 Vjeux

Vjeux 是 Facebook React Native 項(xiàng)目的一個前端開發(fā)軟件工程師。

延伸
  • JavaScript-Garden
    A growing collection of documentation about the most quirky parts of the JavaScript programming language.

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容