繁体   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