Расширение Number.prototype в javascript и объекте Math? - PullRequest
28 голосов
/ 07 марта 2009

Мне всегда было интересно, почему в Javascript есть глобальный объект Math вместо того, чтобы давать числам свои собственные методы. Есть ли для этого веская причина?

Также есть ли какие-либо недостатки (кроме эффективности), чтобы сделать что-то подобное?

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

Просто чтобы прояснить, я понимаю, что где-то нужны такие константы, как π, и функции, которые применяются к более чем одному числу, например, min / max. В основном речь шла о методах, которые влияют только на одно число, таких как round, abs, sin, pow и т. Д.

Ответы [ 8 ]

20 голосов
/ 08 марта 2009

Нет никаких недостатков в расширении Number.prototype, кроме как сбить с толку других людей. В чем смысл? Что лучше использовать value.round() вместо Math.round(value)?

Есть несколько веских причин для объекта Math:

  1. Это работает и для не-чисел: Math.round("5") работает, тогда как value.round() не будет работать, когда значение является строкой (например, значение текстового поля)
  2. Некоторые члены объекта Math не принадлежат «первичному» числовому значению, например Math.min() или Math.max(). Или вы хотите использовать его как a.max(b)?
  3. Другие члены являются глобальными и не принадлежат к специализированному номеру. Примерами являются константы, такие как Math.PI или функция Math.random().
19 голосов
/ 09 марта 2009

Причина использования объекта Math проста: «потому что это делает Java». Не самая лучшая причина, но мы здесь. Я думаю, что тогда было больше смысла, прежде чем Дуглас Крокфорд начал свою кампанию по подавлению половины языка *. Первоначально вы были «разрешены» или имели в виду делать такие вещи:

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] ];
}

Это переведет все математические функции в глобальную область, эффективно позволяя вам прекратить вводить «Математика». Задайте себе вопрос: есть ли реальная разница между расширением Number и расширением window с помощью этих функций?

* Прежде, чем вы меня разозлите: комментарий Крокфорда не должен восприниматься слишком серьезно. Я согласен с ним, что with очень опасен в неявной глобальной среде.

13 голосов
/ 26 октября 2010

Попробуйте сделать 123.round();

Ваша консоль javascript выдаст вам несколько сотен ошибок: P, нет ...

Вы можете сделать:

Number.prototype.x тогда: (123).x(); но никогда 123.x();

1 голос
/ 25 октября 2012

Итак, разговор о том, хорошая ли это идея или нет, вы можете сделать это хорошо.

Вы можете выполнить 123.x (), но интерпретатор для js не работает (поскольку он не интерпретирует точку как отправку сообщения)

Странно, вы можете вместо этого использовать 123 .x () (с пробелом между числом и точкой), и это сработает.

123 .. также работает, но это потому, что вы фактически сделали десятичную дробь и затем отправили ей

(typeof 123.) === 'число') // true

Попробуйте:

Number.prototype.times = function (other) {вернуть это * other}; 3 раза (5);

в консоли.

1 голос
/ 24 января 2012

Я считаю, что вызов этого способа также работает, поскольку функции-прототипы Number работают так же, как и все функции-прототипы других объектов:

5.5["round"]();
//should return 6
1 голос
/ 07 марта 2009

Я думаю, что математика - это больше, чем набор числовых методов. Это использование шире. Скажем, использование NumberVariable.PI может сбить с толку. То же самое с генерацией случайных чисел.

Также я думаю, что расширение числа в порядке, потому что это часть природы JS. Может быть, кто-то поправит меня, если я здесь не прав.

0 голосов
/ 21 августа 2017

Вы можете сделать это

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

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

0 голосов
/ 13 марта 2014

По моему мнению, если вы выполните надлежащие проверки, чтобы не перезаписывать собственные функциональные возможности, назовите их с пониманием собственных стандартов именования, и это сделает ваш код более читабельным и управляемым, а затем сделайте ваш код удобным и удобным.

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

Как использовать это, из-за природы javascript, я считаю, что лучший способ сделать это:

  • Заключение числа в переменную вместо простого статического значения (чаще всего бывает)
    • nNum.round ();
  • Завершение простого статического значения в скобках:
    • (123) .round ();
  • Вызов с использованием квадратных скобок
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...