045_对象作用域
1. 公用、私有和受保護作用域
1.1. 在傳統的面向對象程序設計中, 主要關注于公用和私有作用域。公用作用域中的對象屬性可以從對象外部訪問, 即開發者創建對象的實例后, 就可使用它的公用屬性。而私有作用域中的屬性只能在對象內部訪問, 即對于外部世界來說, 這些屬性并不存在。這意味著如果類定義了私有屬性和方法, 則它的子類也不能訪問這些屬性和方法。
1.2. 受保護作用域也是用于定義私有的屬性和方法, 只是這些屬性和方法還能被其子類訪問。
2. JavaScript只有公用作用域
2.1. 對JavaScript討論上面這些作用域幾乎毫無意義, 因為JavaScript中只存在一種作用域, 公用作用域。JavaScript中的所有對象的所有屬性和方法都是公用的。因此, 定義自己的類和對象時, 必須格外小心。記住, 所有屬性和方法默認都是公用的!
3. 建議性的解決方法
3.1. 許多開發者都在網上提出了有效的屬性作用域模式, 解決了JavaScript的這種問題。
3.2. 由于缺少私有作用域,開發者確定了一個規約,說明哪些屬性和方法應該被看做私有的。這種規約規定在屬性前后加下劃線:
obj._color_ = "blue";3.3. 這段代碼中, 屬性color是私有的。注意, 下劃線并不改變屬性是公用屬性的事實, 它只是告訴其他開發者, 應該把該屬性看作私有的。
4. 靜態作用域
4.1. 靜態作用域定義的屬性和方法任何時候都能從同一位置訪問。在Java中, 類可具有屬性和方法, 無需實例化該類的對象, 即可訪問這些屬性和方法, 例如: java.net.URLEncoder類, 它的函數encode()就是靜態方法。
4.2. JavaScript沒有靜態作用域
4.2.1. 嚴格來說, JavaScript并沒有靜態作用域。不過, 它可以給構造函數提供屬性和方法。還記得嗎, 構造函數只是函數。函數是對象, 對象可以有屬性和方法。例如:
function sayHello() {alert("hello"); }sayHello.alternate = function() {alert("hi"); }sayHello(); // 輸出"hello" sayHello.alternate(); // 輸出"hi"4.2.2. 這里, 方法alternate()實際上是函數sayHello的方法。可以像調用常規函數一樣調用sayHello()輸出"hello", 也可以調用sayHello.alternate()輸出"hi"。即使如此, alternate()也是sayHello() 公用作用域中的方法, 而不是靜態方法。
5. 關鍵字this
5.1. this的功能
5.1.1. 在JavaScript中, 要掌握的最重要的概念之一是關鍵字this的用法, 它用在對象的方法中。關鍵字this總是指向調用該方法的對象, 例如:
var oCar = new Object; oCar.color = "red"; oCar.showColor = function() {alert(this.color); };oCar.showColor(); // 輸出"red"5.1.2. 在上面的代碼中, 關鍵字this用在對象的showColor()方法中。在此環境中, this等于oCar。下面的代碼與上面的代碼的功能相同:
var oCar = new Object; oCar.color = "red"; oCar.showColor = function() {alert(oCar.color); };oCar.showColor(); // 輸出"red"5.2. 使用this的原因
5.2.1. 為什么使用this呢?因為在實例化對象時, 總是不能確定開發者會使用什么樣的變量名。使用this, 即可在任何多個地方重用同一個函數。請思考下面的例子:
function showColor() {alert(this.color); };var oCar1 = new Object; oCar1.color = "red"; oCar1.showColor = showColor;var oCar2 = new Object; oCar2.color = "blue"; oCar2.showColor = showColor;oCar1.showColor(); // 輸出"red" oCar2.showColor(); // 輸出"blue"5.2.2. 在上面的代碼中, 首先用this定義函數showColor(), 然后創建兩個對象(oCar1和oCar2), 一個對象的color屬性被設置為"red", 另一個對象的color屬性被設置為"blue"。兩個對象都被賦予了屬性showColor, 指向原始的showColor()函數(注意這里不存在命名問題, 因為一個是全局函數, 而另一個是對象的屬性)。調用每個對象的showColor(), oCar1輸出是"red", 而oCar2的輸出是"blue"。這是因為調用oCar1.showColor() 時, 函數中的this關鍵字等于oCar1。調用oCar2.showColor()時, 函數中的this關鍵字等于oCar2。
5.2.3. 注意, 引用對象的屬性時, 必須使用this關鍵字。例如, 如果采用下面的代碼, showColor()方法不能運行:
function showColor() {alert(color); };5.2.4. 如果不用對象或this關鍵字引用變量, JavaScript就會把它看作局部變量或全局變量。然后該函數將查找名為color的局部或全局變量, 但是不會找到。結果如何呢?該函數將在警告中顯示"null"。
總結