| 對象 Javascript 根本上是和對象相關(guān)的。數組是對象。函數是對象。對象是對象。那什么是對象呢?對象是名-值對的集合。名是字符串,值可以是字符串,數字,布爾值或者對象(包括數組和函數)。通常對象是像哈希表一樣執行地,這樣便于值地快速檢索。 如果值是函數,我們可以認為這是一個(gè)方法。當一個(gè)對象地方法被調用的時(shí)候,this 變量就設置為這個(gè)對象。方法就可以通過(guò) this 變量來(lái)訪(fǎng)問(wèn)實(shí)例變量。 對象可以由用來(lái)初始化對象的構造函數生成。構造函數提供了其他語(yǔ)言中類(lèi)所提供的特性,包括靜態(tài)變量和方法。 公共 對象的成員全部是公共成員。任何函數都可以訪(fǎng)問(wèn)、修改或者刪除這些成員,或者增加新成員。有兩種向新對象中添加成員的方法: 在構造函數中添加 這個(gè)技術(shù)通常用于初始化公共實(shí)例變量。使用構造函數的 this 變量向對象中添加成員。 function Container(param){ this.member = param; } 這樣,如果我們創(chuàng )建一個(gè)新對象: var myContainer = new Container('abc'); 這樣 myContainer.member 就包含 ‘abc’ 了。 在原型中添加 這個(gè)技術(shù)通常用于添加公共方法。當一個(gè)成員被檢索并且沒(méi)能在對象本身里面找到時(shí),就要從對象的構造函數的原型成員里面尋找。原型機制是用于繼承的。也用于節省內存。向一個(gè)構造函數生成的所有對象中添加一個(gè)方法,只需要向構造函數原型中添加一個(gè)函數: Container.prototype.stamp = function(string){ return this.member + string; } 因此,我們可以調用這個(gè)方法: myContainer.stamp('def') 結果為 ‘abcdef’。 私有 私有成員是由構造函數生成的。一般構造函數的變量和參數都是私有成員。 function Container(param){ this.member = param; var secret = 3; var that = this; } 這個(gè)構造函數生成了3個(gè)私有實(shí)例變量:param,secret 和 that。它們和對象相關(guān)聯(lián),但是它們不僅在函數外邊不可訪(fǎng)問(wèn),而且對對象自身的公共方法來(lái)說(shuō)也是不可訪(fǎng)問(wèn)的。它們只可以被私有方法訪(fǎng)問(wèn)。私有方法是構造函數的內部函數。 function Container(param) { function dec() { if (secret > 0) { secret -= 1; return true; } else { return false; } } this.member = param; var secret = 3; var that = this; } 私有方法 dec 檢查 secret 實(shí)例變量。如果它大于零,將其減一并返回 true。否則返回 false。它可以用作限定對象使用3次。 按照習慣,我們設置了一個(gè)私有的 that 參數。它使得這個(gè)對象對于私有方法使可見(jiàn)的。在 ECMAScript 語(yǔ)言規范中,這是一個(gè)可行的錯誤,它使得 this 對于內部函數被不正確地設置。(This is a workaround for an error in the ECMAScript Language Specification which causes this to be set incorrectly for inner functions.) 私有方法不能被公共方法調用。要想使得私有方法有用,需要介紹一下特權方法。 特權 特權方法可以訪(fǎng)問(wèn)私有變量和方法,并且其自身對于公共方法和對象外部都是可訪(fǎng)問(wèn)地??梢詣h除或者替換一個(gè)特權方法,但是不能改變它,或者強迫它泄密。 特權方法是在構造函數內使用 this 指定地。 function Container(param) { function dec() { if (secret > 0) { secret -= 1; return true; } else { return false; } } this.member = param; var secret = 3; var that = this; this.service = function () { if (dec()) { return that.member; } else { return null; } }; } service 就是特權方法。前三次調用 myContainer.service() 時(shí)會(huì )返回 ‘abc’。之后返回空(null)。service 調用了可訪(fǎng)問(wèn)私有變量 secret 的私有方法 dec。service 對其他對象和方法都是可見(jiàn)的,但是不能直接訪(fǎng)問(wèn)私有成員。 閉包 由于 Javascript 有閉包,因此這種公共,私有和特權成員模型時(shí)可以的。這意味著(zhù)內部函數總是可以訪(fǎng)問(wèn)它外部函數的變量和參數,甚至在外部函數返回后也可以。這是這個(gè)語(yǔ)言一個(gè)非常有用的特性。目前沒(méi)有任何關(guān)于 Javascript 編程的書(shū)描述了如何利用它。大部分甚至都不提及它。(糖伴西紅柿說(shuō),這是2001年的文章,當時(shí)估計還沒(méi)有這方面的研究文章?,F在來(lái)說(shuō),犀牛書(shū)等都有涉及,javascript 的難點(diǎn)之一啊。) 私有和特權成員只在對象被創(chuàng )建時(shí)生成。公共成員可以隨時(shí)添加。 模式 公共 function Constructor(...) { this.membername = value; } Constructor.prototype.membername = value; 私有 function Constructor(...) { var that = this; var membername = value; function membername(...) {...} } 注意:函數語(yǔ)句 function membername(...) {...} 是 var membername = function membername(...) {...}; 的縮寫(xiě)。 特權 function Constructor(...) { this.membername = function (...) {...}; } |
聯(lián)系客服