假设我想让所有Numbers在制作完成后都拥有属性foo
,例如包含类似其值的两倍的东西。我想要做如何扩展像Object或Number之类的内建构造函数?
// extend Number constructor here.
console.log(5.foo); // outputs 10
你是怎么做到的?
假设我想让所有Numbers在制作完成后都拥有属性foo
,例如包含类似其值的两倍的东西。我想要做如何扩展像Object或Number之类的内建构造函数?
// extend Number constructor here.
console.log(5.foo); // outputs 10
你是怎么做到的?
你不延长构造,而是原型,通过defining a new property就可以了,用“吸”:
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
的值,然后丢弃该对象(通过垃圾回收)。
有人可能会受到诱惑,也能实现一个二传手,在
set: function(v) { this = v/2; }
,但当然,这是无效的;我们不能设置this
!并且无法访问Number
对象下的[[PrimitiveValue]]
来设置它。
我不推荐以上内容,以这种方式扩展内置类型并不被认为是最佳实践。这最好放在异域的领域。
你需要扩展原型:
Number.prototype.foo = function(){
return this*2;
}
芹苴这是一个方法不是成员。 num = 2; num.foo(); //返回4
数字是原始的。你可以做到这一点,如果你创建一个对象,但为什么? – elclanrs 2014-10-03 21:56:22
我不知道这是否可能,但它可能是一个非常糟糕的主意。想象一下,有人在阅读你的代码,并在某处使用了一个'number.foo'变量,这实际上是数字值的两倍。如果你写了一个像'valueTwice(num)'这样的方法,它会不会更具可读性? – 2014-10-03 22:00:46
不要扩展原始对象,这是一个非常糟糕的主意。 – 2014-10-03 22:15:18