2010-11-10 61 views
2

我想添加功能(新方法)到內置對象(在我的情況下,類型CanvasRenderingContext2D)。Object.create和內置對象

第一種方法是將方法添加到原型,它的工作原理,但我不想修改內置對象。

我想使用的Object.create(從ES5)來擴展對象,像Object.create(context, <my_method_descriptors>),但它acessing屬性時/調用擴展對象的方法無法在某些瀏覽器。例如,這個片段

var canvas = document.getElementById("mainCanvas");
var context = canvas.getContext('2d');
var exContext = Object.create(context);
try {
exContext.fillStyle = 'red';
exContext.fillRect(0, 0, 120, 120);
} catch (e) {
alert(e);
}

將無法​​在IE9測試版和Safari 5,但成功的火狐4測試版和Chrome 7

又如:Object.create(new Date()).getDate()無法在所有瀏覽器。

有什麼想法?

回答

3

CanvasRenderingContext2D對象是主機對象,這意味着一個對象,這不是JavaScript語言的一部分,而是由環境提供的對象。有特殊規則主機對象:它們基本上可以做任何他們喜歡的事情,並且沒有義務像本地JavaScript對象那樣行事。大多數瀏覽器使得它們的主對象的行爲與本地對象類似; IE通常不會(參見this recent question對於示例片的IE主機對象quirkiness)

這樣做的結果是,您不應該依賴主機對象來表現本機對象。在這種情況下,他們沒有義務也沒有經常這樣做。我建議創建一個包裝對象。

Object.create(new Date()).getDate()的情況有所不同:問題在於getDate()方法的實現依賴於它所調用的對象的內部時間屬性,它無法訪問,因爲該特定屬性沒有沿原型鏈繼承。有關更詳細的解釋,請參閱this discussion

+0

不錯的答案,我沒有意識到本地對象的限制。我將創建一個包裝。 – 2010-11-11 14:16:44

0

也許使用對象聚合可能對此有所幫助。創建另一個類,該類包含要擴展的類的對象,將新方法添加到該類中,然後...將出現悲傷部分,將所有方法調用映射到內部對象。

如果只有this是一個標準:(

+0

是的,一個全面的方法會使寫包裝更容易。 – 2010-11-12 00:11:58