Подтвердить что ты не робот

Почему 4 не является экземпляром Number?

Просто любопытно:

  • 4 instanceof Number = > false
  • new Number (4) instanceof Number = > true?

Почему это? То же самое со строками:

  • 'some string' instanceof String возвращает false
  • new String('some string') instanceof String = > true
  • String('some string') instanceof String также возвращает false
  • ('some string').toString instanceof String также возвращает false

Для объектов, массивов или типов функций оператор instanceof работает так, как ожидалось. Я просто не знаю, как это понимать.

[ новые идеи]

Object.prototype.is = function() {
        var test = arguments.length ? [].slice.call(arguments) : null
           ,self = this.constructor;
        return test ? !!(test.filter(function(a){return a === self}).length)
               : (this.constructor.name ||
                  (String(self).match ( /^function\s*([^\s(]+)/im )
                    || [0,'ANONYMOUS_CONSTRUCTOR']) [1] );
}
// usage
var Newclass = function(){};  // anonymous Constructor function
var Some = function Some(){}; // named Constructor function
(5).is();                     //=> Number
'hello world'.is();           //=> String
(new Newclass()).is();        //=> ANONYMOUS_CONSTRUCTOR
(new Some()).is();            //=> Some
/[a-z]/.is();                 //=> RegExp
'5'.is(Number);               //=> false
'5'.is(String);               //=> true
4b9b3361

Ответ 1

value instanceof Constructor совпадает с Constructor.prototype.isPrototypeOf(value), и оба проверяют цепочку [[Prototype]] value для вхождения определенного объекта.

Строки и числа примитивные значения, а не объекты и, следовательно, не имеют [[Prototype]], поэтому он будет работать, только если вы оберните их в обычные объекты (так называемый "бокс" ) в Java).

Кроме того, как вы заметили, String(value) и new String(value) выполняют разные вещи: если вы вызываете функции конструктора встроенных типов без использования оператора new, они пытаются преобразовать ('cast') аргумент конкретному типу. Если вы используете оператор new, они создают объект-оболочку.

new String(value) примерно эквивалентен Object(String(value)), который ведет себя так же, как new Object(String(value)).


Еще несколько типов в JavaScript: ECMA-262 определяет следующие примитивные типы: Undefined, Null, Boolean, Number и String. Кроме того, существует объект Object для объектов, обладающих свойствами.

Например, функции имеют тип Object (они просто имеют специальное свойство, называемое [[Call]]), а null - это примитивное значение типа Null. Это означает, что результат оператора typeof действительно не возвращает тип значения...

Кроме того, объекты JavaScript имеют другое свойство, называемое [[Class]]. Вы можете получить его через Object.prototype.toString.call(value) (это вернет '[object Classname ]'). Массивы и функции имеют тип Object, но их классы - это Array и Function.

Тест для класса объекта, приведенный выше, работает, когда instanceof терпит неудачу (например, когда объекты передаются между границами окна/кадра и не имеют одинаковых прототипов).


Кроме того, вы можете проверить эту улучшенную версию typeof:

function typeOf(value) {
    var type = typeof value;

    switch(type) {
        case 'object':
        return value === null ? 'null' : Object.prototype.toString.call(value).
            match(/^\[object (.*)\]$/)[1]

        case 'function':
        return 'Function';

        default:
        return type;
    }
}

Для примитивов он вернет свой тип в нижнем регистре, для объектов он вернет класс в заголовке.

<сильные > Примеры:

  • Для примитивов типа Номер (например, 5) он вернет 'number' для объектов-оболочек класса Номер (например, new Number(5)), он вернет 'number';

  • Для функций он вернет 'Function'.

Если вы не хотите различать примитивные значения и объекты-обертки (по какой-либо, вероятно, плохой причине), используйте typeOf(...).toLowerCase().

Известные ошибки - это некоторые встроенные функции в IE, которые считаются 'Object' и возвращаемое значение 'unknown' при использовании с некоторыми объектами COM +.

Ответ 2

Вы можете попытаться оценить:

>>> typeof("a")
"string"
>>> typeof(new String("a"))
"object"
>>> typeof(4)
"number"
>>> typeof(new Number(4))
"object"

Ответ 3

Как указано в ответе Кристофа, строковые и числовые литералы не совпадают с объектами String и Number. Если вы используете какой-либо метод String или Number в литерале, скажите

'a string literal'.length

Литерал временно преобразуется в объект, метод вызывается и объект отбрасывается.
Литералы имеют определенные преимущества перед объектами.

//false, two different objects with the same value
alert( new String('string') == new String('string') ); 

//true, identical literals
alert( 'string' == 'string' );

Всегда используйте литералы, чтобы избежать неожиданного поведения!
Вы можете использовать Number() и String() для typecast, если вам нужно:

//true
alert( Number('5') === 5 )

//false
alert( '5' === 5 )

Ответ 4

Это нюанс Javascript, который я нашел, вылавливает. instanceof оператора всегда будет иметь значение false, если LHS не является типом object.

Обратите внимание, что new String('Hello World') не приводит к типу string, но является object. Оператор new всегда приводит к объекту. Я вижу такие вещи: -

function fnX(value)
{
     if (typeof value == 'string')
     {
          \\Do stuff
     }
}
fnX(new String('Hello World'));

Ожидается, что "Do Stuff" произойдет, но это не потому, что тип значения является объектом.

Ответ 5

В случае примитивных чисел метод isNaN также может помочь вам.