Мало знаний, большой вызов! Эта статья участвует в "Необходимые знания для программистов«Творческая деятельность
Эта статья участвовала в "Проект «Звезда раскопок»”, чтобы выиграть творческий подарочный пакет и бросить вызов творческим поощрительным деньгам.
предисловие
Портал:Душевная пытка нативного JavaScript, сколько можно ответить (2)
В текущей фронтенд-разработке три основных фреймворка занимают три трети мира Простота и мощь фреймворка не позволяют нам остановиться, используя нативныйJavaScriptВсе меньше и меньше.
но я думаюJavaScriptВ качестве основы каждого фронтенд-инженера необходимо не только учиться, но и хорошо учиться и хорошо учиться, и не будет преувеличением учиться этому много раз.
С другой стороны, во фронтовых интервью все больше внимания уделяется нативнымJavaScriptДоля расследований также увеличивается.
Я взял вопросы онлайн-интервью этого года и лично на Nioke, о500Левые и правые вопросы, роднойJavaScriptСложность (замыканий,eventLoop,this, вручную рви нативный JS) частота проверок очень высока.
Я все еще работаю над полным анализом, и я надеюсь, что вы поддержите меня, когда придет время.
Поэтому я решил отсортироватьJavaScriptВ точках знаний, которые легко проигнорировать или запутать, напишите серию статей, в пути пытки души, систематически и полностью возьмите всех, чтобы изучить оригиналJavaScriptМир, я надеюсь принести вам урожай.
Вопрос типа JS — концепция и обнаружение
1. Какие типы данных есть в JS?
- Базовые типы данных: всего 7 типов
Boolean Number String undefined null Bigint Symbol
Symbol:ES6Вводится новое примитивное значение, представляющее уникальное значение, в основном для решения проблемы конфликта имен атрибутов.
Bigint:ES2020новое дополнение, болееNumberТипы имеют более широкий диапазон целых чисел.
- Тип справочных данных: 1
Object对象(包括普通Object、Function、Array、Date、RegExp、Math)
2. Вы действительно понимаете typeof?
-
typeofроль?Различая типы данных, можно вернуть 7 типов данных:
number、string、boolean、undefined、object、function,так же какES6добавленsymbol -
typeofМожно ли правильно различать типы данных?не можем. Для примитивных типов, кроме
nullмогут быть правильно оценены; для эталонных типов, кромеfunction, вернусь"object" -
typeofМеры предосторожности-
typeofВозвращаемое значениеstringФормат, обратите внимание на такие вопросы:typeof(typeof(undefined)) -> "string" -
typeofНеопределенные переменные не сообщают об ошибке и возвращают"undefiend" -
typeof(null) -> "object": давнийbug -
typeofНевозможно отличить массив от обычного объекта:typeof([]) -> "object" typeof(NaN) -> "number"
-
-
упражнение
console.log(typeof(b));
console.log(typeof(undefined));
console.log(typeof(NaN));
console.log(typeof(null));
var a = '123abc';
console.log(typeof(+a));
console.log(typeof(!!a));
console.log(typeof(a + ""));
console.log(typeof(typeof(null)));
console.log(typeof(typeof({})));
Отвечать
undefined // b未定义,返回undefined
undefined
number // NaN 为number类型
object
number // +a 类型转换为NaN
boolean
string
string // typeof(null) -> "object"; typeof("object") -> "string"
string
3. Что такое instanceof? Можете ли вы смоделировать реализацию instanceof?
-
instanceofОпределяет, существует ли прототип конструктора в цепочке прототипов объекта. Могут быть определены только ссылочные типы. -
instanceofчасто используется, чтобы судитьAЭтоBслучай
// A是B的实例,返回true,否则返回false
// 判断A的原型链上是否有B的原型
A instaceof B
- Реализация моделирования
instanceof
Идея: найти цепочку прототипов
function instance_of(Case, Constructor) {
// 基本数据类型返回false
// 兼容一下函数对象
if ((typeof(Case) != 'object' && typeof(Case) != 'function') || Case == 'null') return false;
let CaseProto = Object.getPrototypeOf(Case);
while (true) {
// 查到原型链顶端,仍未查到,返回false
if (CaseProto == null) return false;
// 找到相同的原型
if (CaseProto === Constructor.prototype) return true;
CaseProto = Object.getPrototypeOf(CaseProto);
}
}
тестовое задание:
console.log(instance_of(Array, Object)) // true
function User(name){
this.name = name;
}
const user = new User('zc');
const vipUser = Object.create(user);
console.log(instance_of(vipUser, User)) // true
4. Как отличить массив от объекта? Надежно ли использовать instanceof для оценки массива?
-
ES6предоставлен новый методArray.isArray() - если не существует
Array.isArray()Шерстяная ткань? можно использоватьObject.prototype.toString.call()Судя по всему, этот метод имеет наилучшую совместимость.
if (!Array.isArray) {
Array.isArray = function(o) {
return typeof(o) === 'object'
&& Object.prototype.toString.call(o) === '[object Array]';
}
}
-
instanceofсудить
Метод суждения
// 如果为true,则arr为数组
arr instanceof Array
instanceofОпределить тип массива так просто, почему это не рекомендуется?
instanceofПроблема с операторами заключается в том, что если их несколькоiframe, то их будет несколькоArrayКонструктор, в данный момент будет проблематично определить, является ли это массивом.
Для получения более подробной информации, пожалуйста, обратитесь к сообщению в блоге:Почему JavaScript не использует instanceof для обнаружения массивов?
5. Как определить, является ли число NaN?
NaNимеет особую особенность,NaNне равно никакому значению, в том числе самому себе
NaN === NaN // false
NaN == NaN // false
Ввиду этой уникальной особенности относительно простая функция суждения может быть разорвана вручную.
function isNaN(x) {
return x != x;
}
- глобальная функция
isNaNМетод: не рекомендуется.MDNВведение к нему такое:isNaNФункции содержат несколько очень интересных правил.
Но дабы избежать некоторых непопулярных вопросов от некоторых интервьюеров, давайте немного разберемсяisNaNИнтересный механизм: сначала он будет судить, является ли параметрNumberтипа, если нетNumbertype попытается преобразовать этот параметр вNumberвведите, а затем оцените, является ли этоNaN.
Например:
// 为什么对象会带来三种不同的结果
// 是不是很有趣
// 具体原因可以参考类型转换篇
console.log(isNaN([])) // false
console.log(isNaN([1])) // false
console.log(isNaN([1, 2])) // true
console.log(isNaN(null)) // false
console.log(isNaN(undefined)) // true
isNaNРезультат во многом зависит отNumber()результат преобразования типа, оNumberРезультаты преобразования , будут представлены в специальной части позже.
-
Number.isNaN(Рекомендуемое использование)
а такжеisNaN()в сравнении с,Number.isNaN()Не самопреобразует аргумент в число, только значение параметра NaNномер, он вернетсяtrue.
6. Как реализовать полнофункциональную функцию определения типа?
Object.prototype.toString.call([value]), можно точно определить тип данных, поэтому можно инкапсулировать свои по этому принципуtypeметод.
toString.call(()=>{}) // [object Function]
toString.call({}) // [object Object]
toString.call([]) // [object Array]
toString.call('') // [object String]
toString.call(22) // [object Number]
toString.call(undefined) // [object undefined]
toString.call(null) // [object null]
toString.call(new Date) // [object Date]
toString.call(Math) // [object Math]
toString.call(window) // [object Window]
Вопросы о типах JS — преобразование типов
7. В чем разница между методами toString и valueOf?
- Основы: Эти два метода относятся к
Objectобъект, решитьJavaScriptПроблема работы и отображения значений. Чтобы лучше выполнять свои функции, многиеJavaScriptВстроенные объекты переопределяют оба метода. -
toString(): возвращает строковую форму текущего объекта;valueOf(): возвращает исходное значение объекта - Сравнение возвращаемых значений двух методов по каждому типу
| Типы | valueOf | toString |
|---|---|---|
| Array[1,2,3] | Сам массив [1, 2, 3] | 1,2,3 |
| Object | сам объект | [object Object] |
| Логический тип | Логическое значение | "правда или ложь" |
| Function | сама функция | function fnName(){code} |
| Number | Численная величина | Числовое представление символов |
| Date | Временная метка в мм формате | Строка времени в формате GMT |
-
приоритет вызова
Вызывается автоматически при неявном преобразовании
toStringа такжеvalueOfметод, приоритет двух следующий:- При приведении к строковому типу он вызывается первым
toStringметод - При приведении к числовому типу он вызывается первым
valueOfметод - При использовании оператора оператор,
valueOfприоритет надtoStirng - Преобразование типа объекта см. Следующий вопрос.
- При приведении к строковому типу он вызывается первым
8. Знаете ли вы, что такое процесс преобразования объекта в примитивное значение (ToPrimitive)?
Преобразование объекта в примитивный тип вызовет встроенный[ToPrimitive]функция
(Справочный блог:Глубокое понимание преобразований типов JavaScript из спецификации ECMA.)
-
ToPrimitiveМетод принимает два параметра, один из которых является входным значением.input, один тип, который, как ожидается, будет преобразованPreferredType- Если не прошел в
PreferredTypeпараметр, пустьhintравный'default', что будет позжеhintпревратиться в'number' - если
PreferredTypeдаhint String,Позволятьhintравный'string' - если
PreferredTypeдаhint Number,Позволятьhintравный'number' - вернуть
OrdinaryToPrimitive(input, hint)
- Если не прошел в
-
OrdinaryToPrimitive(input, hint)- если
hintда'string', тоmethodNamesУстановить какtoString、valueOf - если
hintда'number', тоmethodNamesУстановить какvalueOf、toString
- если
methodNameХранилище в настоящее времяpreferredTypeЕсли приоритет вызова не преобразуется в исходное значение после завершения всех вызовов, произойдет ошибка.
9. Можете ли вы ответить на следующий вопрос?
const a = {x:1};
const b = {x:2};
const obj = {};
obj[a] = 100;
obj[b] = 200;
console.log(obj[a]);
console.log(obj[b]);
При знании седьмого и восьмого вопросов эта задача не представляет сложности.JavaScriptКлючи объектов должны быть строками, поэтому объект должен бытьaа такжеbПеревести вstringТипы. Конкретный процесс преобразования:
// 1.执行ToPrimitive
// hint 为 string
ToPrimitive(a, 'hint String')
// 2.执行OrdinaryToPrimitive
OrdinaryToPrimitive(a, 'string')
// 3.返回methodNames
methodNames = ['toString', 'valueOf']
// 4.调用methodNames里方法
// 调用toString
a.toString() // 返回[object Object]
объектaа такжеbПреобразованный результат[object Object],objК объекту добавляется только одно свойство[object Object].
Отвечать
200
200
10. Можете ли вы разобраться с преобразованием типов?
Сначала вам нужно знать:JavaScript, Толькотри типапреобразование
- Перевести в
NumberТипы:Number() / parseFloat() / parseInt() - превратиться в
StringТипы:String() / toString() - превратиться в
BooleanТипы:Boolean()
Итак, столкнулись с проблемами преобразования типов, просто нужно разобраться вкакая сценаПеревести вэтот типВот и все.
преобразовать в логическое значение
- Явно:
Booleanметоды могут явно преобразовывать значения в логический тип - Неявный: обычно срабатывает, когда есть логическое суждение или логический оператор (
|| && !)
Boolean(1) // 显式类型转换
if (1) {} // 逻辑判断类型触发隐式转换
!!1 // 逻辑运算符触发隐式转换
1 || 'hello' // 逻辑运算符触发隐式转换
booleanтолько типtrueа такжеfalseДва вида стоимости.
разделить на значение0, -0, null, NaN, неопределенная или пустая строка ("")дляfalse, все остальноеtrue
преобразовать в строку
- Явно:
Stringметоды для явного преобразования значений в строки - Скрытый:
+Оператор имеет один побочный операндstringвведите время
превратиться вstringХарактер типа:Часть, которую нужно преобразовать в строку, вызывает собственный метод toString (null/undefined возвращает null и undefined в строковом формате).
Когда преобразованное значение является объектом, это эквивалентно выполнению
ToPrimitive(input, 'hint String')
String([1,2,3]) // 1,2,3
String({x:1}) // [object Object]
1 + '1' // 11
1 + {} // 1[object Object]
преобразовать в число
- Явно:
Numberметоды могут явно преобразовывать значения в числовые типы
Numberконкретные правила,ES5Спецификация даетСоответствующая таблица результатов
| Типы | результат |
|---|---|
| undefined | NaN |
| null | +0 |
| Boolean | NaN |
| undefined | Параметр имеет значение true и возвращает 1; false возвращает +0. |
| Number | вернуть значение, равное |
| String | Несколько сложно, пример |
| Object | Сначала выполните метод ToPrimitive, а затем выполните преобразование типа Number. |
-
String: вернуть пустую строку0, появится любой недопустимый числовой символ, возвратNaN
console.log(Number("1 3")) // NaN
console.log(Number("abc")) // NaN
console.log(Number("1a")) // NaN
console.log(Number("0x11")) // 17
console.log(Number("123")) // 123
console.log(Number("-123")) // -123
console.log(Number("1.2")) // 1.2
- Скрытый:
numberНеявное преобразование типов более сложное, и часть, требующая неявного преобразования, выполняетсяNumber:- сравнить операции (
<, >, <=, >=) - побитовые операции (
| & ^ ~) - арифметические операции (
+ - * / %) Уведомление:Когда операнд + существует в строке, он преобразуется в строку - Один юань
+-действовать
- сравнить операции (
11. Неявные правила преобразования для ==
-
==: требуется только равенство значений, равенство типов не требуется;null, undefinedсуществует==равны друг другу и равны между собой -
==Правила преобразования для:
| Сравниваемое число B | |||||
|---|---|---|---|---|---|
| Number | String | Boolean | Object | ||
| Сравнительный номер | |||||
| Number | A == B | A == ToNumber(B) | A == ToNumber(B) | A == ToPrimitive(B) | |
| String | ToNumber(A) == B | A == B | ToNumber(A) == ToNumber(B) | ToPrimitive(B) == A | |
| Boolean | ToNumber(A) == B | ToNumber(A) == ToNumber(B) | ToNumber(A) == ToNumber(B) | ToNumber(A) == ToPrimitive(B) | |
| Object | ToPrimitive(A) == B | ToPrimitive(A) == B | ToPrimitive(A) == ToPrimitive(B) | A === B | |
В приведенной выше таблицеToNumber(A)Попробуйте поставить параметры перед сравнениемAПреобразовать в числа.ToPrimitive(A)установить параметрAПреобразовать в примитивное значение (Primitive).
12.1 + {}а также{} + 1Что такое выход?
Благодаря вышеуказанному обучению, когда объект добавляется с другими элементами, объект будет вызыватьtoPrimitiveПреобразовать в исходное значение:
- воплощать в жизнь
toPrimitive, не прошелPreferredType,methodNamesдля[valueOf, toString] - воплощать в жизнь
({}).valueOf, который возвращает сам объект{}, а не исходное значение - Продолжать
({}).toString(),вернуть"[object Object]", возвращаемый результат является исходным значением, преобразование завершается
В настоящее время1 + {}, правая сторона естьstringтипа, будет1провестиToString()превратиться в"1", окончательная конкатенация строк, результат"1[object Object]"
Уведомление:{} + 1И результаты вывода1 + {}Это то же самое?
{}существуетJavaScript, не только как определения объектов, но и как определения блоков кода.jsдвигатель будет{} + 1анализируется в1 кодовый блок и 1 +1, окончательный вывод1
Отвечать
1[object Object]
1
13. Что получится, если сложить [] и {}?
[] + {}
Массивы — это специальные объекты, которые нужно вызыватьtoPrimitive, преобразуется в исходное значение
- воплощать в жизнь
toPrimitive, не прошелPreferredType,methodNamesдля[valueOf, toString] - воплощать в жизнь
[].valueOf, который возвращает сам массив - воплощать в жизнь
[].toString, который возвращает пустую строку''
Пустые объекты не вдаются в детали.
Отвечать
"[object Object]"
[] + []
аналогичный1Оба пустых массива выполняютсяtoPrimitive, который возвращает две пустые строки.
Отвечать
""
{} + []
похожий на{} + 1,{} + []эквивалентно{}; + [], один юань+заствили""неявно преобразуется в0, окончательный результат0
Отвечать
0
{} + {}
На этот вопрос я сначала объявлю ответ, а затем расскажу о своем вопросе.
Отвечать
[object Object][object Object]
сомневаться
ЗачемJavaScriptДвигатель не повернул переднюю{}Интерпретируется как блок кода?
Дружеское напоминание: потому что
{}Его можно интерпретировать в виде блока кода, есть несколько моментов, на которые стоит обратить внимание, например:
- При вызове метода для пустого объекта:
{}.toString()сообщит об ошибке- Когда функция стрелки возвращает объект:
let getTempItem = id => { id: id, name: "Temp" }сообщит об ошибке
14. Можно ли гибко использовать parseInt и parseFloat?
-
parseInt: Начните с числового класса и возвращайтесь к исходному числу, пока он не увидит нечисловой класс. (десятичная точка также является незначащим числом)
parseInt('123x') -> 123
parseInt('-023x') -> -23
parseInt('1.1') -> 1
parseInt('-abc') -> NaN
parseInt('x123') -> NaN
-
parseInt(string, radix)Есть еще второй параметрradixУказывает основание числа для анализа, значение равно2~36(по умолчанию10) -
parseFloatа такжеparseIntАналогично, за исключением того, что он возвращает число с плавающей запятой. Начиная с числового класса, обратите внимание, что нечисловой класс, за исключением первой точки, является отсечкой, возвращающей предыдущее число.
Чистый красный вопрос: ['1', '2', '3']. Карта (Парсент)
Этот чистый красный вопрос исследуетparseIntЕсть два параметра.mapПереданная функция может быть выполнена с тремя параметрами:
// ele 遍历的元素
// index 遍历的元素索引
// arr 数组
arr.map(function(ele, index, arr){})
['1','2','3'].map(parseInt) эквивалентно выполнению следующих трех процессов:
parseInt('1', 0, ['1','2','3'])
parseInt('2', 1, ['1','2','3'])
parseInt('3', 2, ['1','2','3'])
-
parseInt('1', 0, ['1','2','3']): когда основание равно 0, по умолчанию принимает 10 и, наконец, возвращает 1. -
parseInt('2', 1, ['1','2','3']): основание равно 2~36, возвращает NaN -
parseInt('3', 2, ['1','2','3']): значение системы счисления равно 2, двоичный код включает только 0, 1 и возвращает NaN.
15. Как сделать условие if(a == 1 && a == 2) истинным?
valueOfПриложения
var a = {
value: 0,
valueOf: function() {
this.value++;
return this.value;
}
};
console.log(a == 1 && a == 2); //true