如何扩展像Object或Number这样的内建函数的构造函数

How do you extend the constructor for a builtin like Object or Number?

本文关键字:Number 内建函数 构造函数 Object 何扩展 扩展      更新时间:2023-09-26

假设我想让所有数字在生成后都具有属性foo,例如,包含它们值的两倍。我想做

// extend Number constructor here.
console.log(5.foo); // outputs 10

你是怎么做到的?

您不扩展构造函数,而是通过在其上定义一个新属性来扩展原型,并使用"getter":

Object.defineProperty(Number.prototype, 'foo', {
    get: function() { return this * 2; }
});
> 1.foo
  SyntaxError           // parser expected decimal part of number after dot
> (1).foo
  2
> 1..foo
  2
> 1.0.foo
  2
> Number(1).foo
  2
> new Number(1).foo
  2
> 1['foo']
  2
> 1e0.foo               // exponential notation
  2
> parseInt('1px').foo
  2
> 0x1.foo               // hex
  2
> 01.foo                // octal, disallowed in strict mode
  2
> Math.PI.foo
  6.283185307179586
> Infinity.foo
  Infinity
> NaN.foo
  NaN

为什么第一个示例1.foo失败?JS解析器一旦看到点,就需要一个小数部分。这是没有办法的。所以你必须满足于说1.0.foo

但是1.0是一个基本体而不是一个对象,对吧?那么,1.0.foo怎么可能工作呢?因为JavaScript会在必要时将基元强制转换为对象。在这种情况下,数值被强制到一个数字对象,其长度刚好足以计算foo的值,之后该对象将被丢弃(通过垃圾收集)。

人们可能会想实现一个setter,就像在中一样

set: function(v) { this = v/2; }

但这当然是无效的;我们无法设置this!!并且没有办法访问Number对象下面的[[PrimitiveValue]]来设置它

我不推荐以上内容,以这种方式扩展内置类型并不是最佳实践。这是最好放在异国情调的领域。

您需要扩展原型:

Number.prototype.foo = function(){
return this*2;
}

这是一种方法,而不是成员。num=2;num.foo()//返回4