Вопрос собеседования: четыре способа определить тип данных

JavaScript

предисловие

JavaScript — это弱类型Или动态类型, что означает, что вам не нужно заранее объявлять тип переменной, тип будет определен автоматически в процессе работы программы. Это означает, что вы можете использовать одну и ту же переменную для хранения разных типов данных:

var data = 5 // data is Number now
data = '5' // data is String now
data = true // data is Boolean now
.......

Я считаю, что независимо от того, в процессе обучения или написания дел вы более или менее столкнетесь с чем-то похожим на ---如何判断数据类型этой проблемы. Особенно в интервью часто спрашивают ---请说出判断数组的几种方法 你知道判断数据类型有哪几种方法и т.п.

Хотя кажется, что это просто метод судейства типа данных, он включает в себя数据类型,原型链Дождитесь различных js-фондов, говорить особо нечего, начнем непосредственно.

тип данных

Последний стандарт ECMAScript определяет 8 типов данных:

  • 7 примитивных типов:
    • Boolean
    • Null
    • Undefined
    • Number
    • BigInt
    • String
    • Symbol
  • Object

Исходное значение

--- На самом деле я впервые знаком с понятием примитивного значения.

除Object 以外的所有类型(基本类型)都是不可以变的(值本身无法被改变)Например: Строки в js неизменяемы (операции js над строками возвращают новую строку, но исходная строка не была изменена), мы называем значения этих типов «примитивными значениями».

Boolean

Для логических типов всегда есть толькоtrueа такжеfalseдва значения.

Null

null является литералом и, в отличие от undefined , не является свойством глобального объекта. null — это отсутствующий идентификатор, указывающий, что переменная не указывает ни на какой объект. Это можно лучше понять, рассматривая null как объект, который еще не создан.

В API часто используется значение null, когда тип возвращаемого значения должен быть объектом, но нет связанного значения.

Undefined

Переменная, которой не присвоено значение, будет иметь значение по умолчанию undefined; undefined является свойством глобального объекта.

Number

Согласно стандарту ECMAScript, в JavaScript существует только один числовой тип: значение в 64-битном двоичном формате двойной точности на основе стандарта IEEE 754 (от -(2^53-1) до 2^53-1). Он не дает конкретного типа для целых чисел. В дополнение к возможности представлять числа с плавающей запятой, существуют некоторые значения со знаком: +Infinity, -Infinity и NaN (Not-a-Number).

BigInt

Используя BigInt, вы можете безопасно хранить большие целые числа и манипулировать ими. Часто в конце создается дополнительное целое число n или вызывается конструктор.

const a = BigInt('43243242424242424242342432')
// 43243242424242424242342432n

const b = 43243242424242424242342432n
// 43243242424242424242342432n

String

Длина строки — это количество ее элементов. После создания строки ее нельзя изменить. Однако можно создавать новые строки на основе операций над исходными строками. Например:

  • String.concat() объединяет строки

Вставьте вопрос:'1'.toString()为什么可以调用?

let a = new Object('1');
a.toString();
console.log('-----a',a); // [String: '1']
a = null
console.log('-----a最终',a); // null
  • Шаг 1: Создайте экземпляр класса Object. Обратите внимание, почему не String? В связи с появлением Symbol и BigInt вызов для них new будет приводить к ошибке.В настоящее время спецификация ES6 не рекомендует использовать new для создания классов-оболочек для базовых типов.
  • Шаг 2: вызовите метод экземпляра.
  • Шаг 3: Уничтожьте экземпляр сразу после выполнения метода.

Symbol

Символ - это новый тип базового типа ES6. Мы можем создать анонимное, глобально уникальное значение, вызывая встроенный символ функции ().

const a = Symbol();
const b = Symbol();
a === b // false

const c = Symbol('c'); // Symbol(c)

Стек функций Symbol не может использовать новую команду, потому что Symbol — это примитивный тип данных, а не объект. Вы можете принять строку в качестве параметра, чтобы предоставить описание вновь созданного символа, которое используется для его отображения на консоли, или в виде строки, которую легко отличить.


Самое большое использование Symbol:避免对象的键被覆盖。

Разница между исходными данными и справочными данными

базовый тип данных
  • Доступ по значению, манипулирование фактическим значением, хранящимся в переменной
  • значение хранится в栈内存, занимая фиксированный размер пространства
ссылочный тип данных
  • Доступ к значениям ссылочных типов осуществляется по ссылке
  • Объекты, хранящиеся в куче памяти, не могут напрямую обращаться к пространству памяти объекта операции.

Возвращаясь к теме, поговорим о методе оценки типа данных👇


typeof

typeof '5' // string
typeof 5 // number
typeof null // object
typeof undefined // undefined
typeof true // boolean
typeof Symbol('5') // symbol
typeof 5n // bigint
typeof new Object(); // object
typeof new Function(); // function

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

  • null считается пустым объектом, поэтому объект возвращается
  • Поскольку любой объект будет преобразован в двоичный, нуль, преобразованный в двоичный, означает, что все 0 с, если первые три равны 0, js будет рассматривать его как объект, что является ошибкой, оставшейся с первых дней js.

Итак, тип:

  • 适用于判断(除null)基础类型,
  • 判断引用类型,除了function 全返回object类型

instanceof

  • только судить变量的原型链上是否有构造函数的prototype属性(两个对象是否属于原型链的关系), не обязательно конкретный тип объекта
  • Instanceof не подходит для оценки значения исходного типа, его можно использовать только для определения того, является ли объект аффилированным
[] instanceof Array; // true
[] instanceof Object; // true

function Person() {};
const person = new Person();

person instanceof Person; // true
person instanceof Object; // true

Сначала проанализируем, почему[] instanceof Array правда.

  • первый,[].protoПрототип указывает на Array.prototype, указывая, что два объекта принадлежат к одной и той же цепочке прототипов, и возвращает true.
  • Аналогично можно узнать из кодаperson instanceof Personтакже возвращает true, так почемуperson instanceof ObjectТоже правда?
  • Основан на принципе цепочки прототипов: начинайте искать от прототипа конструктора объекта-экземпляра, а у прототипа конструктора есть его прототип, и продолжайте искать до тех пор, пока не будет найдена вершина цепочки прототипов Object.prototype. Возвращает ноль, если нет
  • Видно, что человек и объект принадлежат к цепочке прототипов, поэтому верните true

注意:空对象{}的判断问题

let obj1 = {}
console.log(obj1 instanceof Object) // true

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

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

constructor

принцип:每一个实例对象都可通过constructor来访问它的构造函数, На самом деле он тоже основан на принципе цепочки прототипов.

'5'.__proto__.constructor === String // true
[5].__proto__.constructor === Array // true

undefined.__proto__.constructor // Cannot read property '__proto__' of undefined

null.__proto__.constructor // Cannot read property '__proto__' of undefined

Поскольку undefined и null являются недопустимыми объектами, свойства конструктора нет, и эти два значения нельзя оценивать таким образом.

toString

  • Метод Object.prototype.toString возвращает строку типа объекта, поэтому его можно использовать для определения типа значения.

  • Поскольку объект экземпляра может настроить метод toString и переопределить Object.prototype.toString, лучше всего добавить вызов при его использовании.

  • С помощью этого метода можно обнаружить все типы данных, и он очень точен.

Object.prototype.toString.call('5') // [object String]
Object.prototype.toString.call(5) // [object Number]
Object.prototype.toString.call([5]) // [object Array]
Object.prototype.toString.call(true) // [object Boolean]
Object.prototype.toString.call(undefined) // [object Undefined]
Object.prototype.toString.call(null) // [object Null]
Object.prototype.toString.call(new Function()); // [object Function]
Object.prototype.toString.call(new Date()); // [object Date]
Object.prototype.toString.call(new RegExp()); // [object RegExp]
Object.prototype.toString.call(new Error()); // [object Error]

Суммировать

  • тип подходящих базовых типов и типов функций обнаружения, не может быть определен с нулевым объектом
  • instanceof подходит для пользовательских объектов, а также может использоваться для обнаружения собственных объектов. Он не работает при обнаружении между различными фреймами и окнами. Также необходимо обратить внимание на проблему объектов Object.create(null).
  • Конструктор может в основном оценивать все типы, кроме null и undefined, но конструктор легко модифицировать и его нельзя использовать в iframe.
  • tostring может оценивать все типы, его можно инкапсулировать как всемогущий DataType() для оценки всех типов данных.