В дополнение к повреждению === и typeof, возвращающийся "объект", с помощью конструктора 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
}
Редактирование: Еще хуже, чем повреждение === между литералами числа и объектами Числа, == даже не работает между двумя объектами Числа (по крайней мере, не интуитивным способом - они тестируют на идентификационные данные, не равенство).
var n1 = new Number(3);
var n2 = new Number(3);
alert(n1 == n2); // false
alert(n1 === n2); // false
var number = new Number(3);
alert(typeof number); // gives "object"
Создание переменной number
имеет тип Object
, вероятно, не большая часть желаемого результата. Принимая во внимание, что:
var number = Number(3);
alert(typeof number); // gives "number"
new Number () не возвращает тот же объект, что и числовой литерал. Это означает, что использование new Number () прерывает ===, что является лучшим способом проверки на точное равенство в Javascript.
>>> 3 == 1 + 2
true
>>> 3 === 1 + 2
true
>>> new Number(3) == 1 + 2
true
>>> new Number(3) === 1 + 2
false
Обоснование поведения JSLint можно найти в книге автора JavaScript: The Good Parts , в приложении C.
К сожалению, документы JSLint не вдаются в дальнейшие подробности, чем, "не ожидает видеть", таким образом, нас оставляют предположить. Мое собственное подозрение - то, что это должно сделать проверку типа легче:
assert(typeof 3 === "number");
assert(typeof new Number(3) === "object");
при смешивании двух в коде проверки типа становятся более сложными:
if (typeof foo === "number" || foo instanceof Number) { … }
Однако JSLint также не соглашается с Объектом и Конструкторами Array, которые не делают это различие, таким образом, это может просто быть предпочтение стиля кодирования автора:
assert(typeof [] === "object");
assert(typeof new Array() === "object");
assert(typeof {} === "object");
assert(typeof new Object() === "object");
Редактирование: ответ Steven поднимает точный вопрос — оператор равенства непреобразования типа (===). Объекты числа и примитивы числа никогда не будет считать равными этот оператор, даже если их значения будут тем же:
assert(3 !== new Number(3));
Это медленнее, и требует большей памяти. Время выполнения может рассматривать неизменные литералы как неизменные литералы. Это означает, что, когда это встречается 3
где-нибудь в коде, это может оптимизировать это в общий объект. Когда Вы используете Number
конструктор, новая память выделяется для каждого экземпляра.