本文源自 @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.