# ECMAScript 修改對象
**通過使用 ECMAScript,不僅可以創建對象,還可以修改已有對象的行為。**
**prototype 屬性不僅可以定義構造函數的屬性和方法,還可以為本地對象添加屬性和方法。**
## 創建新方法
### 通過已有的方法創建新方法
可以用 prototype 屬性為任何已有的類定義新方法,就像處理自己的類一樣。例如,還記得 Number 類的 toString() 方法嗎?如果給它傳遞參數 16,它將輸出十六進制的字符串。如果這個方法的參數是 2,那么它將輸出二進制的字符串。我們可以創建一個方法,可以把數字對象直接轉換為十六進制字符串。創建這個方法非常簡單:
```
Number.prototype.toHexString = function() {
return this.toString(16);
};
```
在此環境中,關鍵字 this 指向 Number 的實例,因此可完全訪問 Number 的所有方法。有了這段代碼,可實現下面的操作:
```
var iNum = 15;
alert(iNum.toHexString()); //輸出 "F"
```
[TIY](/tiy/t.asp?f=jseg_pro_js_object_modifying_1)
由于數字 15 等于十六進制中的 F,因此警告將顯示 "F"。
### 重命名已有方法
我們還可以為已有的方法命名更易懂的名稱。例如,可以給 Array 類添加兩個方法 enqueue() 和 dequeue(),只讓它們反復調用已有的 push() 和 shift() 方法即可:
```
Array.prototype.enqueue = function(vItem) {
this.push(vItem);
};
Array.prototype.dequeue = function() {
return this.shift();
};
```
[TIY](/tiy/t.asp?f=jseg_pro_js_object_modifying_2)
### 添加與已有方法無關的方法
當然,還可以添加與已有方法無關的方法。例如,假設要判斷某個項在數組中的位置,沒有本地方法可以做這種事情。我們可以輕松地創建下面的方法:
```
Array.prototype.indexOf = function (vItem) {
for (var i=0; i<this.length; i++) {
if (vItem == this[i]) {
return i;
}
}
return -1;
}
```
該方法 indexOf() 與 String 類的同名方法保持一致,在數組中檢索每個項,直到發現與傳進來的項相同的項目為止。如果找到相同的項,則返回該項的位置,否則,返回 -1。有了這種定義,我們可以編寫下面的代碼:
```
var aColors = new Array("red","green","blue");
alert(aColors.indexOf("green")); //輸出 "1"
```
[TIY](/tiy/t.asp?f=jseg_pro_js_object_modifying_3)
### 為本地對象添加新方法
最后,如果想給 ECMAScript 中每個本地對象添加新方法,必須在 Object 對象的 prototype 屬性上定義它。前面的章節我們講過,所有本地對象都繼承了 Object 對象,所以對 Object 對象做任何改變,都會反應在所有本地對象上。例如,如果想添加一個用警告輸出對象的當前值的方法,可以采用下面的代碼:
```
Object.prototype.showValue = function () {
alert(this.valueOf());
};
var str = "hello";
var iNum = 25;
str.showValue(); //輸出 "hello"
iNum.showValue(); //輸出 "25"
```
[TIY](/tiy/t.asp?f=jseg_pro_js_object_modifying_4)
這里,String 和 Number 對象都從 Object 對象繼承了 showValue() 方法,分別在它們的對象上調用該方法,將顯示 "hello" 和 "25"。
## 重定義已有方法
就像能給已有的類定義新方法一樣,也可重定義已有的方法。如前面的章節所述,函數名只是指向函數的指針,因此可以輕松地指向其他函數。如果修改了本地方法,如 toString(),會出現什么情況呢?
```
Function.prototype.toString = function() {
return "Function code hidden";
}
```
前面的代碼完全合法,運行結果完全符合預期:
```
function sayHi() {
alert("hi");
}
alert(sayHi.toString()); //輸出 "Function code hidden"
```
[TIY](/tiy/t.asp?f=jseg_pro_js_object_modifying_5)
也許你還記得,Function 對象這一章中介紹過 Function 的 toString() 方法通常輸出的是函數的源代碼。覆蓋該方法,可以返回另一個字符串(在這個例子中,可以返回 "Function code hidden")。不過,toString() 指向的原始函數怎么了呢?它將被無用存儲單元回收程序回收,因為它被完全廢棄了。沒有能夠恢復原始函數的方法,所以在覆蓋原始方法前,比較安全的做法是存儲它的指針,以便以后的使用。有時你甚至可能在新方法中調用原始方法:
```
`Function.prototype.originalToString = Function.prototype.toString;`
Function.prototype.toString = function() {
if (this.originalToString().length > 100) {
return "Function too long to display.";
} else {
return this.originalToString();
}
};
```
[TIY](/tiy/t.asp?f=jseg_pro_js_object_modifying_6)
在這段代碼中,第一行代碼把對當前 toString() 方法的引用保存在屬性 originalToString 中。然后用定制的方法覆蓋了 toString() 方法。新方法將檢查該函數源代碼的長度是否大于 100。如果是,就返回錯誤信息,說明該函數代碼太長,否則調用 originalToString() 方法,返回函數的源代碼。
## 極晚綁定(Very Late Binding)
從技術上講,根本不存在極晚綁定。本書采用該術語描述 ECMAScript 中的一種現象,即能夠在對象實例化后再定義它的方法。例如:
```
var o = new Object();
Object.prototype.sayHi = function () {
alert("hi");
};
o.sayHi();
```
[TIY](/tiy/t.asp?f=jseg_pro_js_object_modifying_7)
在大多數程序設計語言中,必須在實例化對象之前定義對象的方法。這里,方法 sayHi() 是在創建 Object 類的一個實例之后來添加進來的。在傳統語言中不僅沒聽說過這種操作,也沒聽說過該方法還會自動賦予 Object 對象的實例并能立即使用(接下來的一行)。
注意:不建議使用極晚綁定方法,因為很難對其跟蹤和記錄。不過,還是應該了解這種可能。
- 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() 構造器
- 免責聲明