javascript那些事(1),javascript那些事
最近看到winter(寒冬)老師的一篇博文,說的是js這類基於原型的繼承與普通的基於類繼承方式的差異。文章最後拋出幾個有意思的小練習嘗試的解決了下。
一般來說,建立一個對象有如下三個步驟:
1. 構建一個新對象
2. 把新對象的__proto__指向函數對象的共有對象屬性:prototype
3. 以新對象為this執行建構函式
Function.prototype.prop=1;alert(Object.prop)alert(Function.prop)
輸出:1, 1
怎麼理解呢?
首先應該知道,所有的constructor(構造器)的原型鏈模型:selfFunction.__proto__ ==> Function.prototype.__proto__==> Object.prototype
那麼:
Object.prop ==> Object.__proto__.prop === Function.prototype.prop === 1
Function.prop ==> Function.__proto__.prop === Function.prototype.prop === 1
Object.prototype.prop=1;alert(Object.prop)alert(Function.prop)
同理:
Object.prop ==> Object.prototype.prop === 1
Function.prop ==> Function.__proto__.prop === Function.prototype.prop ==>Function.prototype.__proto__.prop === Object.prototype.prop === 1
Function.__proto__.prop=1;alert(Object.prop)alert(Function.prop)
推導:
Object.prop ==> Object.__proto__.prop === Function.prototype.prop === Function.__proto__.prop === 1
Function.prop == >Function.__proto__.prop === 1
Object和Function一樣都是constructor所以他們的__proto__屬性都指向Function.prototype。
function Class(){}Class.prototype=Class;Class.__proto__.prop=1alert((new Class).prop);
這裡new了一個對象然後訪問其prop屬性,根據之前說的構造對象的三個步驟,我們可以知道新對象的__proto__屬性指向Class這個constructor的prototype,所以有:
var client = new Class;
client.prop ==>client.__proto__.prop === Class.prototype.prop ==> Class.prototype.__proto__.prop;
又因為Class.__proto__.prop = 1. 且,Class.prototype=== Class,==>Class.prototype.__proto__.prop === 1.
function Class(){}Class.prototype=Class.__proto__;Function.prototype.prop=1;alert((new Class()).prop)基於上面幾個推導過程,可以很快的得出結果:
(new Class()).prop ==> (new Class()).__proto__.prop === Class.prototype.prop === Class.__proto__.prop ==>
Function.proptype.prop === 1
function Class(){}Class.prototype.__proto__.prop=1;Class.prototype=new Class;alert((new Class).prop);這個例子有點不好解釋, 首先看看Class.prototype.__proto__.prop=1;這句做了什麼,
一個函數在聲明之後,預設會得到自己的一個prototype屬性,指向一個全新建立的Object,就跟{}一樣。所以:
Class.prototype.__proto__ === Object.prototype //true,所以這一句實際上是對Object.prototype新增一個prop屬性。
Class.prototype.__proto__.prop = 1;
var classProto = Class.prototype;
var classNewProto = Object.create(classProto, {});
classNewProto.__proto__ === classProto //true
Class.prototype = classNewProto;
var inst = Object.create(classProto, {});
so:
inst.__proto__ === classNewProto//true
inst.__proto__.__proto__ ===classProto //true
inst.__proto.__proto__.__proto__ === Object.prototype//true
最後通過原型鏈在Object.prototype上找到了prop屬性。