# ECMAScript 對象作用域
**作用域指的是變量的適用范圍。**
## 公用、私有和受保護作用域
### 概念
在傳統的面向對象程序設計中,主要關注于公用和私有作用域。公用作用域中的對象屬性可以從對象外部訪問,即開發者創建對象的實例后,就可使用它的公用屬性。而私有作用域中的屬性只能在對象內部訪問,即對于外部世界來說,這些屬性并不存在。這意味著如果類定義了私有屬性和方法,則它的子類也不能訪問這些屬性和方法。
受保護作用域也是用于定義私有的屬性和方法,只是這些屬性和方法還能被其子類訪問。
### ECMAScript 只有公用作用域
對 ECMAScript 討論上面這些作用域幾乎毫無意義,因為 ECMAScript 中只存在一種作用域 - 公用作用域。ECMAScript 中的所有對象的所有屬性和方法都是公用的。因此,定義自己的類和對象時,必須格外小心。記住,所有屬性和方法默認都是公用的!
### 建議性的解決方法
許多開發者都在網上提出了有效的屬性作用域模式,解決了 ECMAScript 的這種問題。
由于缺少私有作用域,開發者確定了一個規約,說明哪些屬性和方法應該被看做私有的。這種規約規定在屬性前后加下劃線:
```
obj._color_ = "blue";
```
這段代碼中,屬性 color 是私有的。注意,下劃線并不改變屬性是公用屬性的事實,它只是告訴其他開發者,應該把該屬性看作私有的。
有些開發者還喜歡用單下劃線說明私有成員,例如:obj._color。
## 靜態作用域
靜態作用域定義的屬性和方法任何時候都能從同一位置訪問。在 Java 中,類可具有屬性和方法,無需實例化該類的對象,即可訪問這些屬性和方法,例如 java.net.URLEncoder 類,它的函數 encode() 就是靜態方法。
### ECMAScript 沒有靜態作用域
嚴格來說,ECMAScript 并沒有靜態作用域。不過,它可以給構造函數提供屬性和方法。還記得嗎,構造函數只是函數。函數是對象,對象可以有屬性和方法。例如:
```
function sayHello() {
alert("hello");
}
sayHello.alternate = function() {
alert("hi");
}
sayHello(); //輸出 "hello"
sayHello.alternate(); //輸出 "hi"
```
[TIY](/tiy/t.asp?f=jseg_pro_object_scope_static)
這里,方法 alternate() 實際上是函數 sayHello 的方法。可以像調用常規函數一樣調用 sayHello() 輸出 "hello",也可以調用 sayHello.alternate() 輸出 "hi"。即使如此,alternate() 也是 sayHello() 公用作用域中的方法,而不是靜態方法。
## 關鍵字 this
### this 的功能
在 ECMAScript 中,要掌握的最重要的概念之一是關鍵字 this 的用法,它用在對象的方法中。關鍵字 this 總是指向調用該方法的對象,例如:
```
var oCar = new Object;
oCar.color = "red";
oCar.showColor = function() {
alert(`this.color`);
};
oCar.showColor(); //輸出 "red"
```
[TIY](/tiy/t.asp?f=jseg_pro_object_scope_this_1)
在上面的代碼中,關鍵字 this 用在對象的 showColor() 方法中。在此環境中,this 等于 oCar。下面的代碼與上面的代碼的功能相同:
```
var oCar = new Object;
oCar.color = "red";
oCar.showColor = function() {
alert(`oCar.color`);
};
oCar.showColor(); //輸出 "red"
```
[TIY](/tiy/t.asp?f=jseg_pro_object_scope_this_2)
### 使用 this 的原因
為什么使用 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"
```
[TIY](/tiy/t.asp?f=jseg_pro_object_scope_this_3)
在上面的代碼中,首先用 this 定義函數 showColor(),然后創建兩個對象(oCar1 和 oCar2),一個對象的 color 屬性被設置為 "red",另一個對象的 color 屬性被設置為 "blue"。兩個對象都被賦予了屬性 showColor,指向原始的 showColor () 函數(注意這里不存在命名問題,因為一個是全局函數,而另一個是對象的屬性)。調用每個對象的 showColor(),oCar1 輸出是 "red",而 oCar2 的輸出是 "blue"。這是因為調用 oCar1.showColor() 時,函數中的 this 關鍵字等于 oCar1。調用 oCar2.showColor() 時,函數中的 this 關鍵字等于 oCar2。
注意,引用對象的屬性時,必須使用 this 關鍵字。例如,如果采用下面的代碼,showColor() 方法不能運行:
```
function showColor() {
alert(`color`);
};
```
如果不用對象或 this 關鍵字引用變量,ECMAScript 就會把它看作局部變量或全局變量。然后該函數將查找名為 color 的局部或全局變量,但是不會找到。結果如何呢?該函數將在警告中顯示 "null"。
- JavaScript 基礎
- JavaScript 簡介
- JavaScript 使用
- JavaScript 輸出
- JavaScript 語句
- JavaScript 注釋
- JavaScript 變量
- JavaScript 數據類型
- JavaScript 對象
- JavaScript 函數
- JavaScript 運算符
- JavaScript 比較和邏輯運算符
- JavaScript If...Else 語句
- JavaScript Switch 語句
- JavaScript For 循環
- JavaScript While 循環
- JavaScript Break 和 Continue 語句
- JavaScript 錯誤 - Throw、Try 和 Catch
- JavaScript 表單驗證
- JavaScript 保留關鍵字
- JavaScript JSON
- javascript:void(0) 含義
- JavaScript 高級
- JavaScript 對象
- JavaScript Number 對象
- JavaScript 字符串(String)對象
- JavaScript Date(日期)對象
- JavaScript Array(數組)對象
- JavaScript Boolean(邏輯)對象
- JavaScript Math(算數)對象
- JavaScript RegExp 對象
- JavaScript BOM
- JavaScript Window - 瀏覽器對象模型
- JavaScript Window Screen
- JavaScript Window Location
- JavaScript Window History
- JavaScript Window Navigator
- JavaScript 消息框
- JavaScript 計時
- JavaScript Cookies
- HTML DOM
- HTML DOM 簡介
- HTML DOM 節點
- HTML DOM 方法
- HTML DOM 屬性
- HTML DOM 訪問
- HTML DOM - 修改
- HTML DOM - 修改 HTML 內容
- HTML DOM - 元素
- HTML DOM - 事件
- HTML DOM - 導航
- JavaScript HTML DOM EventListener
- AJAX 教程
- AJAX 簡介
- AJAX 實例
- AJAX - 創建 XMLHttpRequest 對象
- AJAX - 向服務器發送請求
- AJAX - 服務器響應
- AJAX - onreadystatechange 事件
- AJAX ASP/PHP 請求實例
- AJAX 數據庫實例
- AJAX XML 實例
- jQuery 基礎
- jQuery 簡介
- jQuery 安裝
- jQuery 語法
- jQuery 選擇器
- jQuery 事件
- jQuery 效果
- jQuery 效果 - 隱藏和顯示
- jQuery 效果 - 淡入淡出
- jQuery 效果 - 滑動
- jQuery 效果 - 動畫
- jQuery 停止動畫
- jQuery Callback 函數
- jQuery - Chaining
- jQuery HTML
- jQuery - 獲得內容和屬性
- jQuery - 設置內容和屬性
- jQuery - 添加元素
- jQuery - 刪除元素
- jQuery - 獲取并設置 CSS 類
- jQuery - css() 方法
- jQuery - 尺寸
- jQuery 遍歷
- jQuery 遍歷
- jQuery 遍歷 - 祖先
- jQuery 遍歷 - 后代
- jQuery 遍歷 - 同胞
- jQuery 遍歷 - 過濾
- jQuery - AJAX
- jQuery - AJAX 簡介
- jQuery - AJAX load() 方法
- jQuery - AJAX get() 和 post() 方法
- jQuery 雜項
- jQuery - noConflict() 方法
- JavaScript 高級教程
- JavaScript 的歷史
- JavaScript 實現
- ECMAScript 基礎
- ECMAScript 語法
- ECMAScript 變量
- ECMAScript 關鍵字
- ECMAScript 保留字
- ECMAScript 原始值和引用值
- ECMAScript 原始類型
- ECMAScript 類型轉換
- ECMAScript 引用類型
- ECMAScript 運算符
- ECMAScript 一元運算符
- ECMAScript 位運算符
- ECMAScript Boolean 運算符
- ECMAScript 乘性運算符
- ECMAScript 加性運算符
- ECMAScript 關系運算符
- ECMAScript 等性運算符
- ECMAScript 條件運算符
- ECMAScript 賦值運算符
- ECMAScript 逗號運算符
- ECMAScript 語句
- ECMAScript if 語句
- ECMAScript 迭代語句
- ECMAScript 標簽語句
- ECMAScript break 和 continue 語句
- ECMAScript with 語句
- ECMAScript switch 語句
- ECMAScript 函數
- ECMAScript 函數概述
- ECMAScript arguments 對象
- ECMAScript Function 對象(類)
- ECMAScript 閉包(closure)
- ECMAScript 對象
- ECMAScript 面向對象技術
- ECMAScript 對象應用
- ECMAScript 對象類型
- ECMAScript 對象作用域
- ECMAScript 定義類或對象
- ECMAScript 修改對象
- ECMAScript 繼承
- ECMAScript 繼承機制實例
- ECMAScript 繼承機制實現
- Google 地圖API
- Google 地圖API Key
- Google Maps 基礎
- Google 地圖疊加層
- Google 地圖事件
- Google 地圖控件集
- Google 地圖類型
- Google 地圖 API 參考手冊
- 地圖 API Map() 構造器
- 免責聲明