Сижу я, значит, никого не трогаю, починяю примус пишу один модуль, и тут выясняется неприятное: оказывается, в YUI 3.0.0.pr2, модуле Lang методы isNumber и isBoolean того. Не этого. В смысле, бажные:
alert(YUI.Lang.isNumber(new Number(1))); // false alert(YUI.Lang.isBoolean(new Boolean(true))) // false
Неприятно.
Лезу в код, и вижу:
// для простоты восприятия я выкинул все лишнее, относящееся только к YUI isBoolean = function(o) { return typeof o === 'boolean'; }; isNumber = function(o) { return typeof o === 'number' && isFinite(o); };
Придется править ручками.
Как известно, typeof объекта Boolean возвращает 'object'. Лезу в Boolean Reference, что на w3schools, и вижу, что у Boolean есть метод, который мне поможет – valueOf. Правлю isBoolean на что-то вроде:
isBoolean = function(o) { return (typeof o === 'boolean' || (o !== null && typeof o === 'object' && (typeof o.valueOf() === 'boolean'))); };
Тесты прогоняются на ура. Идем дальше. Смотрим в Number Reference, и по накатанной правлю и isNumber:
isNumber = function(o) { return ((typeof o === 'number') || (o !== null && typeof o === 'object' && (typeof o.valueOf() === 'number')) && isFinite(o); };
Казалось бы, все круто? Не совсем.
alert(isNumber(new Date())); // return true;
Хм. Ну, давайте еще добавлю проверку на то, что это не Date.
isNumber = function(o) { return ((typeof o === 'number') || (o !== null && typeof o === 'object' && !(o instanceof Date))) && (typeof o.valueOf() === 'number')) && isFinite(o); };
Теперь все работает нормально, но какой монстрик-то жуткий получается. Ладно, в идиота я наигрался, пора и голову включить:
isBoolean = function(o) { return typeof o === 'boolean' || o instanceof Boolean; }; isNumber = function(o) { return (typeof o === NUMBER || o instanceof Number) && isFinite(o); };
Вуаля. Пойду на форум YUI рапортовать о баге. Всем спасибо за внимание.
>> Пойду на форум YUI рапортовать о баге.
Какая же это бага? Это скорее вы чего-то странного хотите :) Boolean и Number это объекты-обертки над примитивными типами данных boolean и number. Методы YUI.Lang.isBoolean и YUI.Lang.isNumber как раз и проверяют примитивного ли типа переменная.
Кстати, я вообще не понимаю зачем использовать эти объекты в явном виде и писать new Boolean, new Number и new String. Если нужны методы этих объектов, то примитивные типы boolean, number и string автоматически оборачиваются в эти объекты:
var a = 123.45678;
alert(a.toFixed(3));
Если же очень хочется писать new Number, то у полученного объекта есть метод valueOf, который возвращает «обернутое примитивное значение». Результат вызова valueOf и передавайте в YUI.Lang.isNumber, а курочить YUI не надо :)
<quote>Какая же это бага? Это скорее вы чего-то странного хотите :) Boolean
и Number это объекты-обертки над примитивными типами данных boolean и
number. </quote>
Любопытно. Если мне не изменяет память, встроенные типы данных — это
Undefined, Null, Boolean, Number, String, Object. А примитивы boolean и
number – это что-то вроде «примитивных значений» соответствующих встроенных
типов. Хотя за правильность формулировки не ручаюсь, лень лезть в спеку.
<quote>Методы YUI.Lang.isBoolean и YUI.Lang.isNumber как раз и проверяют
примитивного ли типа переменная.</quote>
Я хочу не странного, а того, чтобы эти методы возвращали true, если в них
передаешь примитив или встроенный тип.
<quote>Кстати, я вообще не понимаю зачем использовать эти объекты в явном
виде</quote>
Не знаю :)
http://www.ecma-international.org/publications/...
Не поленился посмотреть спецификацию:
4.3.2 Primitive Value
A primitive value is a member of one of the types Undefined, Null, Boolean, Number, or String. A primitive value is a datum that is represented directly at the lowest level of the language implementation.
4.3.3 Object
An object is a member of the type Object. It is an unordered collection of properties each of which
contains a primitive value, object, or function. A function stored in a property of an object is called a
method.
…
4.3.20 Number Type
The type Number is a set of values representing numbers. In ECMAScript, the set of values represents the double-precision 64-bit format IEEE 754 values including the special “Not-a-Number” (NaN) values, positive infinity, and negative infinity.
4.3.21 Number Object
A Number object is a member of the type Object and is an instance of the built-in Number object. That is, a Number object is created by using the Number constructor in a new expression, supplying a number as an argument. The resulting object has an implicit (unnamed) property that is the number. A Number object can be coerced to a number value by calling the Number constructor as a function.
———————–
new Number возвращает именно объект (Object).
Кстати, немаловажно заметить, что примитивные типы передаются по значению, в то время как объекты передаются по ссылке.
С одной стороны, вы правы:
var a = new Number();
alert(typeof a === 'object' && a instanceof Number && a instanceof Object);
// true
Получается, Number Object это подобъект (ну, или что-то в этом роде) типа
Object.
А объект Number экземпляр встроенного объекта Number.
И ситуация с Boolean и String симметричная.
А с другой стороны, типов (в значении «набор значений данных») все равно
шесть – Undefined, Null, Boolean, Number, String и Object. Мы это знание
получим, прочитав 8 (стр. 31)
Да в общем-то и спорить не о чем :) Главное, что и я и вы понимаем, что new Number() возвращает Object.
Просто я считаю, что YUI.Lang.isNumber проверяет именно тип переменной и должен возвращать true только если переменная типа Number.
Я все же думаю, что правильнее будет такое поведение:
Потому что
aв данном случае – объект, но, одновременно, позволяет выполнять над собой операции, свойственные числам.