В JavaScript есть операторы typeof и instanceof, на первый взгляд они похоже, но они выполняют разные функции.

В этой статье будет рассмотрена разница между ними и показаны примеры использования.

Typeof оператор

Оператор typeof используется, в основном, для того, чтобы узнать тип примитивного значения.

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

К примеру, у нас есть :

console.log(typeof 1);  

В терминале отобразится 'number'.

Более полезно, когда у нас есть переменные:

 let foo = 1;
 console.log(typeof foo);  

В таком случае мы можем использовать typeof, чтобы узнать тип переменной foo.

Важно запомнить, что typeof не следует использовать для null, если мы напишем:

 console.log(typeof null);

В терминале отобразится 'object'. Вместо этого следует использовать оператор === ://

 foo === null

Другой пример содержит boolean значения.

typeof false === 'boolean';
typeof Boolean(0) === 'boolean';

Мы также можем проверить числа следующим образом:

typeof Number('1') === 'number';
typeof Number('foo') === 'number';
typeof NaN === 'number';

Обратите внимание, что NaN и вычисления, которые возвращают NaN, такие как Number(‘foo’ ), также относятся к типу 'number' . Мы должны проверить их с помощью метода Number.isNaN().

Для BigInt:

 typeof 2n === 'bigint';

Для строк:

typeof '' === 'string';
typeof 'foo' === 'string';

Для символов:

typeof Symbol() === 'symbol'
typeof Symbol('bar') === 'symbol'

Также, можно использовать typeof для определения типа undefined:

typeof undefined === 'undefined';
let x;
typeof x === 'undefined';

Можно использовать для объектов, однако все объекты возвращают тип 'object', так что это не очень полезно:

typeof new String('foo') === 'object';
typeof new Number(1) === 'object';

Некоторые старые браузеры возвращают «функцию», когда мы применяем оператор typeof к литералам регулярных выражений. Однако сегодня это не должно быть проблемой.

Исключения

Typeof document.all всегда возвращает undefined, даже если он определен во всех браузерах.

Оператор instanceof

Оператор instanceof проверяет, появляется ли свойство прототипа конструктора где-либо в цепочке прототипов объекта.

Это означает, что мы можем использовать его, чтобы проверить, является ли объект конструктором из данного класса или функции-конструктора.

Он возвращает true, если объект является экземпляром класса или функции-конструктора, и false в противном случае.

Например, если у нас есть:

class Foo {};
let foo = new Foo();
console.log(foo instanceof Foo);
function Bar (){};
let bar = new Bar();
console.log(bar instanceof Bar);

В терминале будет два "true".

Все, что создано с помощью new, можно проверить с помощью оператора instanceof.

Instanceof полезен для проверки всего, что создано с помощью оператора new, включая строки, логические значения и числа.

Например, если у нас есть:

let foo = new String('foo');
console.log(typeof foo);
console.log(foo instanceof String);

Затем мы получаем 'object' из первого console.log и true для второго.

Это связано с тем, что мы создали экземпляр объекта String вместо строки примитивного значения, хотя в противном случае мы можем использовать примитивную строку и строковые объекты таким же образом.

Литеральные объекты

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

Итак, если у нас есть:

console.log({} instanceof Object);

Выведется 'true'

Все объекты являются экземплярами Object в дополнение к тому, что они являются экземплярами конструктора, из которого они созданы. Например, если у нас есть:

let date = new Date();
console.log(date instanceof Object);
console.log(date instanceof Date);

В обоих случаях выведутся значение true, поскольку date является экземпляром конструктора Date, а все непримитивные объекты являются экземплярами Object.

Выводы

Оператор typeof и instanceof совершенно разные. typeof возвращает тип объекта, над которым он работает.

Instanceof of возвращает true, если объект создан из данного конструктора, и false в противном случае.

Все непримитивные объекты являются экземплярами Object, поэтому он всегда будет возвращать true.

Комментарии (6)


  1. mayorovp
    07.07.2022 15:37
    +2

    Все объекты являются экземплярами Object в дополнение к тому, что они являются экземплярами конструктора, из которого они созданы.

    Ха-ха:


    let foo = Object.create(null);
    console.log(foo instanceof Object); // false


    1. dmitryvashkevich
      07.07.2022 16:31
      -2

      Я не эксперт, но вроде бы нельзя через instanceof проверять примитивы. А Object.create(null) - создает именно примитив.


      1. dopusteam
        07.07.2022 17:00
        +3

        let foo = Object.create(null);
        typeof foo
        'object'


    1. NewMax
      08.07.2022 09:55
      -1

      Документация честно предупреждает про кейс с null.

      Использование с нормальным аргументом даст ожидаемый результат.

      let foo = Object.create({});
      console.log(foo instanceof Object); // true


      1. mayorovp
        08.07.2022 09:59
        +2

        Документация-то предупреждает, но это не отменяет того факта что в посте недоговорка.


  1. Sovietmade
    09.07.2022 09:47
    +1

    Стрёмный косноязычный перевод, к тому же сама статья такая себе. Можно было упомянуть про возможность настроить поведение instanceof через Symbol.hasInstance, а ещё рассказать, что есть нюанс с фреймами