简体   繁体   English

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

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

Suppose I'd like to make all Numbers have property foo after they are made, containing something like the double of their value, for example. 假设我想让所有Numbers在制作之后都具有属性foo ,例如包含它们的值的两倍。 I'd like to do 我想做

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

How do you do it? 你怎么做呢?

You don't extend the constructor, but rather the prototype, by defining a new property on it, with a "getter": 你没有扩展构造函数,而是扩展原型,通过使用“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

Why does the first example 1.foo fail? 为什么第一个例子1.foo失败了? The JS parser, once it sees the dot, expects a decimal portion. JS解析器一旦看到点,就需要一个小数部分。 There's no way around that. 没有办法解决这个问题。 So you'll have to content yourself with saying 1.0.foo . 所以你必须满足于自己说1.0.foo

But 1.0 is a primitive not an object, right? 但1.0是原始而不是对象,对吧? Then, how can 1.0.foo possibly work? 那么, 1.0.foo怎么可能有效呢? Because JavaScript will coerce (cast, or transform) primitives to objects when necessary. 因为JavaScript会在必要时强制(转换或转换)基元到对象。 In this case the numeric value is coerced to a number object just long enough to compute the value of foo , after which the object is thrown away (by garbage collection). 在这种情况下,数值被强制转换为数字对象,其长度足以计算foo的值,之后将丢弃该对象(通过垃圾回收)。

One might be tempted to also implement a setter, as in 人们可能也想要实现一个setter,就像在

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

but of course this is invalid; 但当然这是无效的; we can't set this !! 我们不能this !! And there's no way to access the [[PrimitiveValue]] underlying the Number object to set it. 并且无法访问Number对象下面的[[PrimitiveValue]]来设置它。

I do not recommend the above, It's not considered best practice to extend built-in types in this way. 我不推荐上述内容,以这种方式扩展内置类型并不是最佳实践。 This is best placed in the realm of exotica. 这最好放在exotica的领域。

you need to extend the prototype: 你需要扩展原型:

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

Tho it's a method not a member. 这是一种不是会员的方法。 num = 2; num = 2; num.foo(); num.foo(); //returns 4 //返回4

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM