1 對象相關(guān)的一些語言特性
1.1 一切皆為對象
JavaScript里所有的東西都是對象。 對象是屬性的集合。 數(shù)字, 字符串, 布爾值等原始值是“偽對象”, 它們同樣擁有屬性, 但是是在棧上分配并按值傳遞。 而其他的對象是堆上分配并按引用傳遞。
一個(gè)很重要的概念是, 函數(shù)也是對象, 能夠作為變量的值, 返回值, 參數(shù)或者屬性的值。 函數(shù)對象特殊的地方是能通過“xxx()”語法執(zhí)行包含在xxx函數(shù)對象內(nèi)的代碼。 因?yàn)檫@一特殊性, typeof xxx 將會(huì)返回function, 但這只是一種便利設(shè)施。
1.2 對象的屬性可以動(dòng)態(tài)添加和刪除
以下為引用的內(nèi)容: var foo = new Object(); |
1.3 除了宿主對象, 其它對象皆由構(gòu)造函數(shù)創(chuàng)建
要有對象, 就先要有創(chuàng)建對象的方法。
在C++/Java等語言, 這個(gè)方法就是實(shí)例化XXX類的一個(gè)實(shí)例xxx.
而在JavaScript的世界里實(shí)際沒有類的東西, 當(dāng)然仍然可以用“類”和“實(shí)例”等慣用語來描述JavaScript中類似的行為, 但其機(jī)制是完全不同的。 JavaScript的對象是由構(gòu)造函數(shù)創(chuàng)建的, 每個(gè)對象都有constructor屬性表示創(chuàng)建該對象的構(gòu)造函數(shù):
以下為引用的內(nèi)容: function Test() { this.a = "hello"; } |
構(gòu)造函數(shù)也是對象, 那構(gòu)造函數(shù)是由什么創(chuàng)建? 內(nèi)建的Function函數(shù):
以下為引用的內(nèi)容: function Test(a, b) |
Function函數(shù)又是由什么創(chuàng)建? 實(shí)際上Function是本機(jī)代碼實(shí)現(xiàn)的固有對象. 不過為了一致性, Function也有constructor屬性, 該屬性指向它自己. 接上面的代碼:
以下為引用的內(nèi)容: /* 輸出 function Function(){ |
2 原型prototype
2.1 prototype的概念
prototype是構(gòu)造函數(shù)的一個(gè)屬性, 該屬性指向一個(gè)對象。 而這個(gè)對象將作為該構(gòu)造函數(shù)所創(chuàng)建的所有實(shí)例的基引用(base reference), 可以把對象的基引用想像成一個(gè)自動(dòng)創(chuàng)建的隱藏屬性。 當(dāng)訪問對象的一個(gè)屬性時(shí), 首先查找對象本身, 找到則返回; 若不, 則查找基引用指向的對象的屬性(如果還找不到實(shí)際上還會(huì)沿著原型鏈向上查找, 直至到根)。 只要沒有被覆蓋的話, 對象原型的屬性就能在所有的實(shí)例中找到。
原型默認(rèn)為Object的新實(shí)例, 由于仍是對象, 故可以給該對象添加新的屬性:
以下為引用的內(nèi)容: // prototype默認(rèn)為new Object(); 為了方便, 記為p_obj |
2.2 原型鏈
除了能修改prototype指向的對象, 還能修改prototype指向哪一個(gè)對象, 即為prototype賦予一個(gè)不同的對象。 這可以實(shí)現(xiàn)一種簡單的繼承:
以下為引用的內(nèi)容: function Superman() {} |
如果先實(shí)例化出一個(gè)對象, 再為構(gòu)造函數(shù)prototype賦予一個(gè)不同的對象, 將會(huì): 已經(jīng)創(chuàng)建的對象的基引用不變, 將來創(chuàng)建的對象的基引用為新的原型對象:
以下為引用的內(nèi)容: var f1 = {echo: function() { alert("sound"); } }; |
所有的構(gòu)造函數(shù)的prototype都不能為空, 就是說Superman.prototype = null 會(huì)被解釋引擎無視; 另一方面, Object構(gòu)造函數(shù)也有prototype屬性(該屬性是只讀的, 可以為原型增加屬性,但不能賦予不同的對象), 故因此可以有多層的原型鏈, 但原型鏈的根必定會(huì)是Object.prototype 。 這意味著給Object.prototype增加屬性影響到所有對象:
以下為引用的內(nèi)容: Object.prototype.echo = function() { |
3. 構(gòu)造函數(shù)和new的實(shí)質(zhì)
構(gòu)造函數(shù)是一個(gè)地地道道的函數(shù), 一個(gè)函數(shù)之所以能成為構(gòu)造函數(shù), 是因?yàn)閚ew運(yùn)算符:
以下為引用的內(nèi)容: this.msg = "window"; |
二者區(qū)別在于如何切入對象: Test() 在某個(gè)對象(例子中為window)的上下文上執(zhí)行代碼, 即this指向這個(gè)對象; new Test()創(chuàng)建一個(gè)新對象, 并以這個(gè)新的對象為上下文(this指向新對象)執(zhí)行代碼, 然后返回這個(gè)新對象。
假如有個(gè)函數(shù):
以下為引用的內(nèi)容: function Test() { |
結(jié)合以上的所有論述, 可以推測new Test()行為的偽代碼表示為:
以下為引用的內(nèi)容: 創(chuàng)建一個(gè)新對象temp; |
原文地址:http://www.cnblogs.com/FlyingCat/archive/2009/09/21/1570656.html
如對本文有疑問,請?zhí)峤坏浇涣髡搲?,廣大熱心網(wǎng)友會(huì)為你解答!! 點(diǎn)擊進(jìn)入論壇