Почему вы не должны использовать Number в качестве конструктора?
Я ввел этот оператор в JSLint:
var number = new Number(3);
И получил следующее сообщение:
Не используйте Number в качестве конструктора.
Почему? Оператор создает числовой объект, а не примитивное значение, поэтому я не понимаю, почему использование new
является проблемой.
EDIT: Спасибо за все ответы. Они заставили меня задуматься, поэтому я разместил следующий вопрос здесь.
Ответы
Ответ 1
В дополнение к break === и typeof возвращающему "объекту" использование конструктора Number также изменяет способ использования значения в булевых контекстах. Поскольку "new Number (0)" - это объект, а не буквальное значение, он оценивается как "истинный", потому что он не является нулевым. Так, например:
var n1 = 0;
var n2 = new Number(0);
n1 == n2 // true
n1 === n2 // false
if (n1) {
// Doesn't execute
}
if (n2) {
// Does execute, because n2 is an object that is not null
}
Изменить: Еще хуже, чем нарушение === между числовыми литералами и объектами Number, == даже не работает между двумя объектами Number (по крайней мере, не интуитивным способом - они проверяют для идентичность, а не равенство).
var n1 = new Number(3);
var n2 = new Number(3);
alert(n1 == n2); // false
alert(n1 === n2); // false
Ответ 2
var number = new Number(3);
alert(typeof number); // gives "object"
Создание переменной number
имеет тип Object
, вероятно, не самый желаемый результат. Принимая во внимание:
var number = Number(3);
alert(typeof number); // gives "number"
Ответ 3
new Number() не возвращает тот же объект, что и числовой литерал. Это означает, что с использованием нового Number() breaks ===, который является лучшим способом проверить точное равенство в Javascript.
>>> 3 == 1 + 2
true
>>> 3 === 1 + 2
true
>>> new Number(3) == 1 + 2
true
>>> new Number(3) === 1 + 2
false
Вы можете найти обоснование поведения JSLint в книге автора, JavaScript: Хорошие части, в Приложении C.
Ответ 4
К сожалению, JSLint docs не вдаваться в подробности, чем "не ожидает видеть", поэтому мы остаемся угадать. Мое собственное подозрение состоит в том, что это упрощает проверку типов:
assert(typeof 3 === "number");
assert(typeof new Number(3) === "object");
Если вы смешиваете два кода, ваши проверки типов становятся более сложными:
if (typeof foo === "number" || foo instanceof Number) { … }
Однако JSLint также сталкивается с конструкторами Object и Array, которые не делают этого различия, поэтому это может быть просто авторский стиль в стиле кодирования:
assert(typeof [] === "object");
assert(typeof new Array() === "object");
assert(typeof {} === "object");
assert(typeof new Object() === "object");
Изменить:. Ответ Стивена дает отличную точку - оператор равенства без выражений (===). Числовые объекты и числовые примитивы никогда не будут считаться равными этому оператору, даже если их значения одинаковы:
assert(3 !== new Number(3));
Ответ 5
Он медленнее и требует больше памяти. Время выполнения может обрабатывать неизменные литералы как непреложные литералы. Это означает, что когда он встречается 3
где-то в коде, он может оптимизировать это в общий объект. Когда вы используете конструктор Number
, для каждого экземпляра выделяется новая память.
Ответ 6
в JavaScript, тип объекта не равен другому типу объекта, даже если у него есть то же самое значение, если только они не являются объектом ТОЧНОЙ ТОЧКИ.
Другими словами, в примере Matthew, n1 == n2 является ложным, потому что вы сравниваете два REFERENCES с двумя объектами SEPARATE, но n1 == n1 истинно, потому что вы сравниваете ссылки на объект EXACT SAME.
Итак, хотя я теперь понимаю, почему использование Number в качестве конструктора может вызвать проблемы, я обнаружил, что вы можете использовать свойство valueOf при сравнении объектов Number.
Иными словами, n1.valueOf == n2.valueOf истинно! (Это связано с тем, что вы сравниваете возвращаемые значения valueOf FUNCTION, а не REFERENCES с самими объектами.)
Этот ответ /summry был извлечен из вопроса, где он не принадлежит.Суб >