简体   繁体   English

在javascript和Math对象中扩展Number.prototype?

[英]Extending Number.prototype in javascript and the Math object?

I've always wondered why Javascript has the global Math object instead of giving numbers their own methods. 我一直想知道为什么Javascript具有全局Math对象而不是给出数字自己的方法。 Is there a good reason for it? 它有充分的理由吗?

Also are there any drawbacks (other than efficiency) to doing something like this?: 做这样的事情也有任何缺点(效率除外)吗?:

Number.prototype.round = function(){
    return Math.round(this);
};

Just to make clear, I understand that constants like π need somewhere and functions that are applied on more than one number like min/max. 为了说清楚,我理解像π这样的常量需要某个地方和函数应用于多个数字,如最小/最大。 The question was mainly concerning methods which only effect a single number such as round, abs, sin, pow, etc. 问题主要涉及只影响单个数字的方法,如圆形,abs,sin,pow等。

There is no drawback in extending Number.prototype other than confusing other people. 除了混淆其他人之外,扩展Number.prototype没有任何缺点。 What's the point? 重点是什么? What is better in using value.round() instead of Math.round(value) ? 使用value.round()而不是Math.round(value)什么value.round()

There are several good reasons for the Math object: Math对象有几个很好的理由:

  1. It works for non-numbers, too: Math.round("5") works whereas value.round() won't work when value is a string (for example, the value of a textbox) 它也适用于非数字: Math.round("5")有效,而value.round()在值为字符串时不起作用(例如,文本框的值)
  2. Some members of the Math object don't belong to a "primary" number value, like Math.min() or Math.max() . Math对象的某些成员不属于“主”数字值,如Math.min()Math.max() Or do you want to use it like a.max(b) ? 或者你想像a.max(b)一样使用它吗?
  3. Other members are global and do not belong to a specialized number. 其他成员是全球性的,不属于专门的数字。 Examples are constants like Math.PI or the function Math.random() . 示例是Math.PI等常量或Math.random()函数。

The reason for the Math object is simple: "because Java does it". Math对象的原因很简单:“因为Java做到了”。 Not the best of reasons, but here we are. 不是最好的理由,但我们在这里。 I guess things made more sense back then, before Douglas Crockford started his campaign to suppress half the language*. 我认为在道格拉斯·克罗克福德开始他的竞选活动以抑制一半语言*之前,事情变得更有意义了。 Originally you were "allowed", or meant, to do things like this: 最初你被“允许”或意味着做这样的事情:

with (Math) {
  var n = min( round(a) * round(b), sqrt(c) );
  var result = exp( n + d );
}

The drawback to extending Number.prototype is that someone else might do the same thing. 扩展Number.prototype的缺点是其他人可能会做同样的事情。 Or worse, for example, define Number.prototype.round as a symmetrical rounding function. 或者更糟糕的是,例如,将Number.prototype.round定义为对称的舍入函数。

If you are looking for ways to make your life easier, why stop there? 如果您正在寻找让生活更轻松的方法,为什么要停在那里? Why not simply include Math functions as global functions? 为什么不简单地将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] ];
}

This will drop all the math functions into the global scope, effectively allowing you to stop typing "Math." 这会将所有数学函数放入全局范围,从而有效地允许您停止输入“Math”。 Ask yourself: Is there any real difference between extending Number and extending window with these functions? 问问自己:使用这些函数扩展Number和扩展window之间是否有任何真正的区别?

* Before you flame me: The Crockford comment is not meant to be taken too seriously. *在你激怒我之前:克罗克福德的评论并不意味着太过认真。 I do agree with him that with is very dangerous in an implicit global environment. 我同意他的观点with即在一个隐含的全球环境中非常危险。

Try doing 123.round(); 尝试做123.round();

Your javascript console will throw a few hundred of errors to your eyes :P, nah ... 你的javascript控制台会给你的眼睛抛出几百个错误:P,不......

You can do: 你可以做:

Number.prototype.x then: (123).x(); Number.prototype.x then: (123).x(); but never 123.x(); 但从来没有123.x();

So, the conversation on whether its a good idea or not aside, you can do this fine. 那么,关于它是否是一个好主意的谈话,你可以做到这一点。

You can do 123.x() but the interpreter for js is broken (as it doesn't interpret the dot as a message dispatch) 您可以执行123.x()但js的解释器已被破坏(因为它不会将点解释为消息调度)

Weirdly, you can use 123 .x() (with a space between the number and the dot) instead, and it'll work. 奇怪的是,你可以使用123 .x()(在数字和点之间留一个空格),它会起作用。

123..also works but that's because you've effectively made a decimal and then dispatching to it 123 ..也可以,但这是因为你已经有效地制作了一个小数,然后发送给它

(typeof 123.) === 'number') // true (typeof 123.)==='number')// true

Try: 尝试:

Number.prototype.times = function(other) { return this * other }; Number.prototype.times = function(other){return this * other}; 3 .times(5); 3次(5);

in the console. 在控制台中。

I think Math is more than set of Number methods. 我认为Math不仅仅是Number方法的集合。 It's usage wider. 它的用途更广泛。 Say, using NumberVariable.PI can be confusing. 比方说,使用NumberVariable.PI可能会令人困惑。 Same with random numbers generation. 与随机数生成相同。

Also I think extending number is OK, because it's the part of JS nature. 另外我认为扩展数字是可以的,因为它是JS性质的一部分。 Maybe someone will correct me if I am wrong here. 如果我在这里错了,也许会有人纠正我。

I believe calling it this way works as well, since Number's prototype functions work just like every other Object's prototype functions do: 我相信这样调用它也是有效的,因为Number的原型函数就像其他Object的原型函数一样工作:

5.5["round"]();
//should return 6

My view on this is that if you do the proper checks as to not overwrite native functionality, name with understanding of native naming standards and it makes your code more readable and manageable, then make your code comfortable and convenient. 我对此的看法是,如果您进行了正确的检查,以便不覆盖本机功能,请了解本机命名标准,并使代码更易读和易于管理,从而使代码更加舒适方便。

if (Number.prototype.round == null)
    Number.prototype.round = function() { return Math.round(this); }

AS for using this, because of the nature of javascript, I believe the best way to do this is by: 由于javascript的性质,使用它的AS,我认为最好的方法是:

  • Wrapping the number in a variable instead of a simple static value (Most often the case) 将数字包装在变量中而不是简单的静态值(最常见的情况)
    • nNum.round(); nNum.round();
  • Wrapping the simple static value in parentheses : 在括号中包含简单的静态值:
    • (123).round(); (123).round();
  • Calling using square bracket notation 使用方括号表示法调用
    • 123["round"].call(); 123 [ “圆”]()调用。

You can do this 你可以这样做

Number.prototype.round = function() {
    return Math.round(this.valueOf());
};

https://www.w3schools.com/jsref/jsref_prototype_num.asp https://www.w3schools.com/jsref/jsref_prototype_num.asp

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

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