簡體   English   中英

通過原型擴展Math對象不起作用

[英]Extending Math object through prototype doesn't work

我嘗試擴展JavaScript Math 但有一件事讓我感到驚訝。

當我試圖通過prototype擴展它

Math.prototype.randomBetween = function (a, b) {
    return Math.floor(Math.random() * (b - a + 1) + a);
};

在控制台中我有錯誤'無法設置屬性'randomBetween'的'undefined'...

但是如果我把這個函數賦予Math.__proto__

Math.__proto__.randomBetween = function (a, b) {
    return Math.floor(Math.random() * (b - a + 1) + a);
};

一切正常。

誰能解釋一下為什么它以這種方式工作? 我感謝任何幫助。

Math不是構造函數,因此它沒有prototype屬性:

new Math(); // TypeError: Math is not a constructor

相反,只需將您的方法添加到Math本身作為自己的屬性

Math.randomBetween = function (a, b) {
    return Math.floor(Math.random() * (b - a + 1) + a);
};

使用__proto__方法是有效的,因為Math是一個Object實例, Math.__proto__Object.prototype

但是請注意,您正在將randomBetween方法添加到所有對象,而不僅僅是Math 這可能會有問題,例如在使用for...in循環迭代對象時。

引用這個答案

一些JavaScript實現允許直接訪問[[Prototype]]屬性,例如通過名為__proto__的非標准屬性。 通常,只能在對象創建期間設置對象的原型:如果通過新的Func()創建新對象,則對象的[[Prototype]]屬性將設置為Func.prototype引用的對象。

您無法使用.prototype分配其原型的.prototype是因為已經創建了Math對象。

幸運的是,我們可以通過簡單地使用以下方法為Math對象分配新屬性:

Math.myFunc = function() { return true };

在您的情況下,這將是:

Math.randomBetween = function(...) { ... };

那是因為Math是一個對象, 而不是一個function

在javascript中, function是面向對象語言中類的粗略等價物。 prototype是一個特殊屬性,允許您向此類1添加實例方法。 當你想擴展那個類時,你使用prototype並且“只是工作”。

現在讓我們考慮Math是什么。 你永遠不會創建一個數學對象,你只需使用它的方法。 事實上,創建兩個不同的Math對象沒有意義,因為Math總是一樣的! 換句話說,javascript中的Math對象只是將一堆預先編寫的數學相關函數組合在一起的便捷方式。 它就像一本普通數學字典。

想要為該群組添加內容嗎? 只需在集合中添加屬性即可! 這有兩種簡單的方法。

Math.randomBetween = function() { ... }
Math["randomBetween"] = function() {... }

使用第二種方式使它更加明顯,它是一個字典類型集合,但它們都做同樣的事情。

var MyMath = Object.create(Math); // empty object with prototype Math

MyMath.randomBetween = function (a, b) {
    return this.floor(this.random() * (b - a + 1) + a);
};

typeof(MyMath);                 // object
Object.getPrototypeOf(MyMath);  // Math
MyMath.PI;                      // 3.14...
MyMath.randomBetween(0, 10);    // exactly that
  • Math對象是新MyMath對象的原型
  • MyMath可以訪問Math所有功能
  • 您可以在不操作Math情況下將自定義功能添加到MyMath
  • 在自定義方法中,使用關鍵字this來引用Math功能

這種方法沒有Monkey Patching 這是擴展JavScript Math的最佳方法。 沒有必要重復其他答案的解釋。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM