我一直想知道为什么JavaScript有全局的Math对象,而不是让数字拥有自己的方法。这样做有好的原因吗?
还有除效率之外的任何缺点吗?:
Number.prototype.round = function(){
return Math.round(this);
};
只是为了明确,我理解像π这样的常量需要有一个地方以及应用于多个数字的函数,例如min/max。问题主要涉及仅影响单个数字的方法,例如round、abs、sin、pow等。
我一直想知道为什么JavaScript有全局的Math对象,而不是让数字拥有自己的方法。这样做有好的原因吗?
还有除效率之外的任何缺点吗?:
Number.prototype.round = function(){
return Math.round(this);
};
只是为了明确,我理解像π这样的常量需要有一个地方以及应用于多个数字的函数,例如min/max。问题主要涉及仅影响单个数字的方法,例如round、abs、sin、pow等。
Math
对象存在的原因很简单:“因为Java这样做”。虽然不是最好的理由,但我们已经这样了。我想在Douglas Crockford开始他的运动压制了语言的一半之前,事情更加合理。最初你“被允许”或者说是打算这样做:
with (Math) {
var n = min( round(a) * round(b), sqrt(c) );
var result = exp( n + d );
}
在扩展 Number.prototype
的缺点是其他人可能会做同样的事情。更糟糕的是,例如,将 Number.prototype.round
定义为一个对称舍入函数。Math
函数作为全局函数包含进来呢?var m = 'abs acos asin atan atan2 ceil cos exp floor log max min ' +
'pow random round sin sqrt tan PI').split(' ');
for (var i=0,l=m.length; i<l; i++) {
window[ m[i] ] = Math[ m[i] ];
}
这将把所有数学函数放入全局作用域,实际上允许您停止输入 "Math."。问问自己:扩展Number
和使用这些函数扩展window
之间是否有任何真正的区别?
* 在你炮轰我之前:Crockford的评论不应该被过分认真对待。我同意他在隐式全局环境中使用with
是非常危险的。
除了会让其他人感到困惑之外,扩展Number.prototype
没有任何缺点。那么,使用value.round()
有什么好处呢?相比之下,使用Math.round(value)
有什么不好的呢?
以下是使用Math
对象的几个好处:
Math.round("5")
是可行的,而value.round()
在value为字符串(例如文本框的值)时无法正常工作。Math.min()
或Math.max()
。你想用它来执行像a.max(b)
这样的操作吗?Math.PI
这样的常量或函数Math.random()
。尝试执行123.round();
你的JavaScript控制台会抛出几百个错误给你看:P,不要...
你可以这样做:
Number.prototype.x
然后: (123).x();
但不要使用123.x();
123..round()
жҲ–(123).round()
пјҢдёӨиҖ…йғҪеҸҜд»ҘгҖӮ123..round() === 123.0.round()
гҖӮ - samError compiling template:
。 - Yevgeniy Afanasyev我相信这样调用也可以正常工作,因为Number的原型函数和其他对象的原型函数的工作方式是一样的:
5.5["round"]();
//should return 6
我认为数学不仅仅是一组数字方法,它的应用范围更广。例如,使用NumberVariable.PI可能会让人感到困惑。同样的道理,随机数生成也是如此。
另外,我认为扩展数字是可以的,因为这是JS本质的一部分。如果我在这里有错的话,或许有人可以纠正我。
所以,先不论这是否是个好主意,你可以很好地执行这项任务。
你可以执行123.x(),但js解释器可能会出错(因为它无法将点解释为消息分发)
奇怪的是,你可以用123 .x()(数字和点之间有一个空格)代替,这样就可以工作了。
123..也能行,但是这是因为你实际上已经创建了一个小数并对其进行了分发
(typeof 123.) === 'number') // true
尝试在控制台中输入:
Number.prototype.times = function(other) { return this * other }; 3 .times(5);
。
你可以做到这个
Number.prototype.round = function() {
return Math.round(this.valueOf());
};
我的看法是,如果您进行适当的检查以避免覆盖原生功能,使用符合本地命名标准的命名方式,使您的代码更易读和可管理,那么请让您的代码更加舒适和便利。
if (Number.prototype.round == null)
Number.prototype.round = function() { return Math.round(this); }
关于使用这个,由于JavaScript的特性,我认为最好的方法是: