Object - 對Object類的擴展

Prototype對Object類進行的擴展主要通過一個靜態函數Object.extend(destination, source)實現了JavaScript中的繼承。 從語義的角度, Object.extend(destination, source)方法有些不和邏輯, 因為它事實上僅僅實現了從源對象到目標對象的全息拷貝。不過你也可以這樣認為:由于目標對象擁有了所有源對象所擁有的特性, 所以看上去就像目標對象繼承了源對象(并加以擴展)一樣。另外, Prototype對Object擴展了幾個比較有用的靜態方法, 所有其他的類可以通過調用這些靜態方法獲取支持。

Source View - 源碼解析

Object.extend = function(destination, source) {  // 一個靜態方法表示繼承, 目標對象將擁有源對象的所有屬性和方法
for (var property in source) {
destination[property] = source[property];   // 利用動態語言的特性, 通過賦值動態添加屬性與方法
}
return destination;   // 返回擴展后的對象
}
Object.extend(Object, {
inspect: function(object) {   // 一個靜態方法, 傳入一個對象, 返回對象的字符串表示
try {
if (object == undefined) return 'undefined';  // 處理undefined情況
if (object == null) return 'null';     // 處理null情況
// 如果對象定義了inspect方法, 則調用該方法返回, 否則返回對象的toString()值
return object.inspect ? object.inspect() : object.toString();
} catch (e) {
if (e instanceof RangeError) return '...';  // 處理異常情況
throw e;
}
},
keys: function(object) {     // 一個靜態方法, 傳入一個對象, 返回該對象中所有的屬性, 構成數組返回
var keys = [];
for (var property in object)
keys.push(property);     // 將每個屬性壓入到一個數組中
return keys;
},
values: function(object) {   // 一個靜態方法, 傳入一個對象, 返回該對象中所有屬性所對應的值, 構成數組返回
var values = [];
for (var property in object)
values.push(object[property]);   // 將每個屬性的值壓入到一個數組中
return values;
},
clone: function(object) {    // 一個靜態方法, 傳入一個對象, 克隆一個新對象并返回
return Object.extend({}, object);
}
});

Field & Function Reference - 屬性方法一覽

Object ( 靜態 ) - 擴展
Method / Property Kind Arguments Description
extend(destination, source) 靜態方法 任意對象  
inspect(object) 靜態方法 任意對象  
keys(object) 靜態方法 任意對象  
values(object) 靜態方法 任意對象  
clone(object) 靜態方法 任意對象  

Analysis & Usage - 分析與使用

Object.extend(destination, source)是Prototype實現的一個靜態方法, 在JavaScript中模擬了繼承。 事實上, 這個方法的語義更加傾向于:動態地為某個對象添加屬性或方法。這個函數貫穿了整個Prototype的框架, 雖然核心思想是一致的, 但是在使用中還是能夠看到一些不同之處, 這些不同之處很微小但是卻值得一提。

1. 擴展現有對象的功能 - 為他們添加新的函數

Object.extend(Number.prototype, {
toColorPart: function() {
var digits = this.toString(16);
if (this < 16) return '0' + digits;
return digits;
},
......
});

這是非常典型的對Number類的擴展, 為Number.prototype加入了一些額外的函數, 從而每個Number對象的實例都擁有這些方法。

2. 定義并實現抽象類

var Enumerable = {
each: function(iterator) {
var index = 0;
try {
this._each(function(value) {
try {
iterator(value, index++);
} catch (e) {
if (e != $continue) throw e;
}
});
} catch (e) {
if (e != $break) throw e;
}
},
......
}
Object.extend(Array.prototype, Enumerable);
Object.extend(Array.prototype, {
_each: function(iterator) {
for (var i = 0; i < this.length; i++)
iterator(this[i]);
},
......
}

這是Prototype中的代碼段, 它向我們展示了定義并實現抽象類的完整過程。這里首先定義了一個Enumerable類, 這是一個抽象類。這個抽象類的內部, 有一個_each方法被調用來完成一些邏輯。但是在整個Enumerable的范圍內, 你無法找到_each方法的具體實現。也就是說, Enumerable是一個抽象類, 具有一個_each的抽象函數。 所以, 如果你還沒有實現_each這個抽象函數, 你是無法直接使用Enumerable類的。之后的代碼就比較明朗了, 使用Object.extend方法, 將所有Enumerable的函數復制給Array.prototype, 然后在Array.prototype中實現_each方法, 這樣就使得Array對象具備了Enumerable這個抽象類的所有特性。



------君臨天下,舍我其誰------