предисловие
Я ранее брал интервью у нескольких разработчиков. Они сделали много проектов и у них хорошие способности, но я обнаружил, что основа js не является прочной, поэтому я решил написать эту базовую статью о типах данных javascript. На самом деле это не так. только из-за интервью.Их оскорбляли, когда они брали интервью раньше, и я до сих пор помню самую глубокую фразу, сказанную интервьюером.
Фундамент очень важен, только если фундамент хороший будет редко
bug,в основномbugВсему виной слабый фундамент.
Об авторе: koala, сосредоточив внимание на совместном использовании полного стека технологий Node.js, от JavaScript до Node.js, до серверной базы данных, я желаю вам стать отличным старшим инженером Node.js. [Руководство по развитию программиста] Автор, блог Github с открытым исходным кодомGitHub.com/koala-co Nth…
Вот два вопроса интервью и ответы, связанные с основами типов данных нашей компании, если вы можете сделать это правильно и знаете, почему (вы можете проигнорировать эту статью):
//类型转换相关问题
var bar=true;
console.log(bar+0);
console.log(bar+"xyz");
console.log(bar+true);
console.log(bar+false);
console.log('1'>bar);
console.log(1+'2'+false);
console.log('2' + ['koala',1]);
var obj1 = {
a:1,
b:2
}
console.log('2'+obj1);
var obj2 = {
toString:function(){
return 'a'
}
}
console.log('2'+obj2)
//输出结果 1 truexyz 2 1 false 12false 2koala,1 2[object Object] 2a
//作用域和NaN 这里不具体讲作用域,意在说明NaN
var b=1;
function outer(){
var b=2;
function inner(){
b++;
console.log(b);
var b=3;
}
inner();
}
outer();
//输出结果 NaN
Эта статья проанализирует и объяснит с точки зрения интервьюера, задающего вопросы.
типы данных в js
Интервьюер: скажи мне
javascriptКакие типы данных существуют?
JavaScriptСуществует семь встроенных типов данных, включаябазовый типа такжетип объекта.
базовый тип
Существует шесть основных типов:
- строка (строка)
- логическое значение (логическое значение)
- количество
- символ
- ноль (нулевое значение)
- неопределенный
Уведомление:
-
string,number,booleanа такжеnullundefinedЭти пять типов коллективны.примитивный тип(Примитивный), указывающий на базовый тип, который не может быть далее подразделен; -
symbolэто новый тип данных в ES6,symbolпредставляет уникальное значение, черезSymbolГенерация вызова функции, так как сгенерированное значение символа является примитивным типом, поэтомуSymbolфункция не может быть использованаnewпередача; -
nullа такжеundefinedЕдинственным значением этих двух типов, которые часто считаются особыми значениями, является само себя.
тип объекта
Типы объектов также называются ссылочными типами.arrayа такжеfunctionявляется подтипом объекта. Объект логически представляет собой неупорядоченный набор свойств, контейнер для различных значений. Значения объекта хранят ссылочные адреса, поэтому в отличие от неизменяемых свойств значений-примитивов, значения объекта изменяемы.
js слабо типизированный язык
Интервьюер: скажи мне
javascriptЯвляется ли понимание слабо типизированных языков?
JavaScriptявляется слабо типизированным языком, иJavaScriptПредопределенного типа при объявлении переменной нет, типом переменной является тип ее значения, т.е.Текущий тип переменной определяется ее значением, утрирую сказать в последнюю секундуString, следующая секунда может бытьNumberТипа, в этом процессе могли быть какие-то действия, происходили приведения. Хотя этот тип слабогоНет необходимости предварительно определять типФункция s приносит нам удобство, но также и беспокоит нас.Чтобы в полной мере использовать эту возможность, мы должны освоить принцип преобразования типов.
Правила принуждения в js
Интервьюер:
javascriptКастинг очень склоненbugЗнаете ли вы правила принуждения?
Примечание. Эти правила лучше всего использовать в сочетании со следующими, когда происходит преобразование, чтобы увидеть лучшие результаты.
ToPrimitive(переведено в исходное значение)
ToPrimitiveНикакой обработки преобразования не происходит для примитивных типов, толькодля ссылочных типов (объект), целью которого является преобразование ссылочного типа (объекта) в необъектный тип, то есть примитивный тип.
ToPrimitiveоператорПринимает значение и необязательный ожидаемый тип в качестве аргументов.ToPrimitiveоператор преобразует значение в тип, не являющийся объектом, если объект может быть преобразован в более чем один примитивный тип, вы можете использовать необязательныйожидаемый типподразумевать этот тип.
преобразованный результатпримитивный типОн определяется ожидаемым типом, который мы и передаемtype. См. непосредственно ниже для большей ясности.ToPrimitiveМетод примерно выглядит так, следующим образом.
/**
* @obj 需要转换的对象
* @type 期望转换为的原始数据类型,可选
*/
ToPrimitive(obj,type)
Описание разных значений типа
- тип
string:
- сначала позвони
objизtoStringметод, если примитивный, тоreturn, иначе перейти к шагу 2 - передача
objизvalueOfметод, если примитивный, тоreturn, иначе перейти к шагу 3 - бросать
TypeErrorаномальный
- тип
number:
- сначала позвони
objизvalueOfметод, если примитивный, тоreturn, иначе перейти к шагу 2 - передача
objизtoStringметод, если примитивный, тоreturn, иначе шаг 3 - бросать
TypeErrorаномальный
- параметр типа пуст
- Объект
Date, установлен типString - В противном случае устанавливается тип
Number
Специальное описание типа данных даты:
дляDateТип данных, который мы ожидаем больше, это строка, преобразованная во время, а не значение миллисекунды (метка времени), если этоnumber, будет получено соответствующее значение миллисекунды, очевидно, строка использует больше.
Другие типы объектов могут работать в соответствии с типом значения.
ToPrimitiveСуммировать
ToPrimitiveКакой исходный тип преобразовать, зависит от типа, а параметр типа является необязательным. Если он указан, он будет преобразован в соответствии с указанным типом. Если не указан, значение по умолчанию делится на два случая в зависимости от практической ситуации.Dateдляstring, остальные объектыnumber. Итак, когда будет указан тип типа, это зависит от следующих двух методов преобразования.
toString
Object.prototype.toString()
toString() Метод возвращает строку, представляющую объект.
Каждый объект имеетtoString()метод, который вызывается автоматически, когда объект представлен в виде текстового значения или когда на объект ссылаются способом, ожидающим строку.
Помните здесь,valueOf()а такжеtoString() Он будет вызываться сам по себе в определенных ситуациях.
valueOf
Object.prototype.valueOf()Метод возвращает исходное значение указанного объекта.
JavaScriptпередачаvalueOf()Методы используются для преобразования объектов в значения примитивных типов (числа, строки и логические значения). Но нам редко нужно вызывать эту функцию самим,valueOfметод обычноJavaScriptВызывается автоматически.
различных встроенных объектовvalueOfвыполнить:
- Строка => возвращаемое строковое значение
- Number => возвращает числовое значение
- Date => возвращает число, то есть значение времени, содержимое строки зависит от конкретной реализации
- Boolean => возвращает это значение Boolean
- Объект => вернуть это
Нагляднее будет сравнить код:
var str = new String('123');
console.log(str.valueOf());//123
var num = new Number(123);
console.log(num.valueOf());//123
var date = new Date();
console.log(date.valueOf()); //1526990889729
var bool = new Boolean('123');
console.log(bool.valueOf());//true
var obj = new Object({valueOf:()=>{
return 1
}})
console.log(obj.valueOf());//1
Number
NumberПравила преобразования оператора:
-
nullпреобразовать в 0 -
undefinedПеревести вNaN -
trueпревращается в 1,falseпреобразовать в 0 - Преобразование строк следует правилам числовых констант, если преобразование не удается, возвращается
NaN
Примечание. Объект здесь должен быть сначала преобразован в исходное значение, вызовите
ToPrimitiveпреобразование, тип указывается какnumber, возвращатьсяToPrimitiveдля преобразования.
String
StringПравила преобразования оператора
-
nullПеревести в'null' -
undefinedПеревести вundefined -
trueПеревести в'true',falseПеревести в'false' - Преобразование чисел следует общим правилам, используя экспоненциальную форму для очень маленьких и больших чисел.
Примечание. Объект здесь должен быть сначала преобразован в исходное значение, вызовите
ToPrimitiveконвертировать,typeобозначен какstring, возвращатьсяToPrimitiveпреобразовать (выше будетToPrimitiveправила преобразования).
String(null) // 'null'
String(undefined) // 'undefined'
String(true) // 'true'
String(1) // '1'
String(-1) // '-1'
String(0) // '0'
String(-0) // '0'
String(Math.pow(1000,10)) // '1e+30'
String(Infinity) // 'Infinity'
String(-Infinity) // '-Infinity'
String({}) // '[object Object]'
String([1,[2,3]]) // '1,2,3'
String(['koala',1]) //koala,1
Boolean
ToBooleanПравила преобразования оператора
В дополнение к следующим шести значениям результат преобразованияfalse, все остальные true:
- undefined
- null
- -0
- 0 или +0
- NaN
- '' (пустой строки)
Значения, отличные от false, являются истинными. Результат преобразования, который включает все объекты (включая пустые объекты), равенtrue, четноеfalseсоответствующий логический объектnew Boolean(false)Слишкомtrue
Boolean(undefined) // false
Boolean(null) // false
Boolean(0) // false
Boolean(NaN) // false
Boolean('') // false
Boolean({}) // true
Boolean([]) // true
Boolean(new Boolean(false)) // true
js применяются в разных сценариях
Интервьюер спросил: я знаю конкретные правила конверсии, но какая конверсия происходит и при каких обстоятельствах?
Когда автоматически преобразовывать в строковый тип
-
без объекта
Автоматическое преобразование строк, в основном происходит в строкахоперация сложенияВремя. Когда одно значение является строкой, а другое не является строкой, последнее преобразуется в строку.
'2' + 1 // '21'
'2' + true // "2true"
'2' + false // "2false"
'2' + undefined // "2undefined"
'2' + null // "2null"
- когда есть объект и с объектом
+когда
//toString的对象
var obj2 = {
toString:function(){
return 'a'
}
}
console.log('2'+obj2)
//输出结果2a
//常规对象
var obj1 = {
a:1,
b:2
}
console.log('2'+obj1);
//输出结果 2[object Object]
//几种特殊对象
'2' + {} // "2[object Object]"
'2' + [] // "2"
'2' + function (){} // "2function (){}"
'2' + ['koala',1] // 2koala,1
к следующему'2'+obj2Подробные примеры:
- слева
string,ToPrimitiveИсходное значение не меняется после преобразования - При конвертации справа то же самое
ToPrimitiveВыполните преобразование примитивного значения, так как указанный типnumber,провестиToPrimitiveконверсионный вызовobj2.valueof(), полученное значение не является исходным, переходим к третьему шагу - передача
toString()return 'a' - существует с обеих сторон символа
string,И является+Используются символьные операторыStringПравила преобразуются вstringТип для соединения - выходной результат
2a
к следующему'2'+obj1Подробные примеры:
- слева
string,ToPrimitiveБез изменений после преобразования в исходное значение - При конвертации справа то же самое
ToPrimitiveВыполните преобразование примитивного значения, так как указанный типnumber,провестиToPrimitiveконверсионный вызовobj2.valueof(),получать{ a: 1, b: 2 } - передача
toString()return [object Object] - существует с обеих сторон символа
string, и используется оператор +StringПравила преобразуются вstringТип для соединения - выходной результат
2[object Object]
Правила преобразования нескольких специальных объектов в коде в основном одинаковы, поэтому я не буду их по отдельности объяснять, вы можете подумать над процессом.
Примечание. Независимо от того, является ли это объектом или нет, существует процесс преобразования в примитивное значение, т.е.是ToPrimitiveПреобразование, но исходный тип после преобразования не меняется, и происходит конкретное преобразование типа объекта.
Моменты, которые могут пойти не так во время разработки преобразования строкового типа:
var obj = {
width: '100'
};
obj.width + 20 // "10020"
Ожидаемый результат вывода 120 Фактический результат вывода 10020
Когда автоматически преобразовывать в числовой тип
-
Есть оператор сложения, но нет
Stringтип, он будет преобразован вNumberТипыпример:
true + 0 // 1 true + true // 2 true + false //1 -
За исключением оператора сложения, все остальные операторы автоматически преобразуют операцию в число.
пример: ````javascript '5' - '2' // 3 '5' * '2' // 10 правда - 1 // 0 ложь - 1 // -1 '1' - 1 // 0 '5' * [] // 0 ложь / '5' // 0 'abc' - 1 // NaN ноль + 1 // 1 не определено + 1 // NaN
//一元运算符(注意点)
+'abc' // NaN
-'abc' // NaN
+true // 1
-false // 0
```
Уведомление:
null0 при преобразовании в числовое значение иundefinedПри преобразовании в числовое значениеNaN.
Знак равенства также ставится вNumberСпециальные инструкции внутри
== абстрактное сравнение на равенство отличается от оператора + и больше неStringприоритет, ноNumberприоритет.
Перечислено нижеx == yпример
- если
x,yобеnumber, прямое сравнение
нечего объяснять
1 == 2 //false
- Если есть объект,
ToPrimitive()типnumberПреобразуйте, а затем сравните
var obj1 = {
valueOf:function(){
return '1'
}
}
1 == obj1 //true
//obj1转为原始值,调用obj1.valueOf()
//返回原始值'1'
//'1'toNumber得到 1 然后比较 1 == 1
[] == ![] //true
//[]作为对象ToPrimitive得到 ''
//![]作为boolean转换得到0
//'' == 0
//转换为 0==0 //true
- существует
boolean,согласно сToNumberБудуbooleanПреобразуйте в 1 или 0, а затем сравните позже
//boolean 先转成number,按照上面的规则得到1
//3 == 1 false
//0 == 0 true
3 == true // false
'0' == false //true
4. Еслиxдляstring,yдляnumber,xПревратиться вnumberСравнивать
//'0' toNumber()得到 0
//0 == 0 true
'0' == 0 //true
Когда делать логическое преобразование
- логическое сравнение
-
if(obj),while(obj)и т. д., или тернарный оператор может содержать только логические значения
Каждое значение условной секции эквивалентноfalse, после использования оператора отрицания становитсяtrue
if ( !undefined
&& !null
&& !0
&& !NaN
&& !''
) {
console.log('true');
} // true
//下面两种情况也会转成布尔类型
expression ? true : false
!! expression
Оценка типа данных в js
Интервьюер спросил: Как судить о типе данных? Как определить, является ли значение типом массива или объектом?
соответственно тремя способамиtypeof,instanceofа также Object.prototype.toString()
typeof
пройти черезtypeofоператор, чтобы определить, к какому примитивному типу принадлежит значение.
typeof 'seymoe' // 'string'
typeof true // 'boolean'
typeof 10 // 'number'
typeof Symbol() // 'symbol'
typeof null // 'object' 无法判定是否为 null
typeof undefined // 'undefined'
typeof {} // 'object'
typeof [] // 'object'
typeof(() => {}) // 'function'
Вывод приведенного выше кода можно увидеть,
-
nullВ суждении есть ошибка, а результат получен
При использованииtypeof,nullПолученный результатobject
- Оператор определяет тип объекта и его подтипы, такие как функции (вызываемые объекты), массивы (объекты упорядоченного индекса) и т. д., все, кроме функций, получат
objectрезультат.
Подводя итог, можно видеть, чтоtypeOfЕсть еще некоторые недостатки в оценке типа, в подтипе объекта иnullкейс.
instanceof
пройти черезinstanceofОператор также может определить тип объекта, принцип заключается в проверке конструктора. prototypeПрисутствует ли он в цепочке прототипов обнаруженного объекта.
[] instanceof Array // true
({}) instanceof Object // true
(()=>{}) instanceof Function // true
Копировать код Примечание:instanceofИ не панацея.
Например:
let arr = []
let obj = {}
arr instanceof Array // true
arr instanceof Object // true
obj instanceof Object // true
В этом примереarrМассив эквивалентенnew Array()вне экземпляра, поэтомуarr.__proto__ === Array.prototype,и потому, чтоArray принадлежатьObjectподтип, т.е. Array.prototype.__proto__ === Object.prototype,следовательноObjectКонструктор находится вarrв цепочке прототипов. такinstanceofДо сих пор нет способа элегантно определить, принадлежит ли значение массиву или обычному объекту.
Еще одно замечание, скажут некоторые разработчики.Object.prototype.__proto__ === null, разве это не говоритarr instanceof nullтакже должно бытьtrue, этот оператор фактически сообщит об ошибке, указывающей, что параметр справа должен быть объектом, что также подтверждает, чтоtypeof nullРезультатobjectдействительно простоjavascriptодин из bug.
Object.prototype.toString()так сказатьJavaScriptОкончательное решение для типа данных в , см. следующий код для конкретного использования:
Object.prototype.toString.call({}) // '[object Object]'
Object.prototype.toString.call([]) // '[object Array]'
Object.prototype.toString.call(() => {}) // '[object Function]'
Object.prototype.toString.call('seymoe') // '[object String]'
Object.prototype.toString.call(1) // '[object Number]'
Object.prototype.toString.call(true) // '[object Boolean]'
Object.prototype.toString.call(Symbol()) // '[object Symbol]'
Object.prototype.toString.call(null) // '[object Null]'
Object.prototype.toString.call(undefined) // '[object Undefined]'
Object.prototype.toString.call(new Date()) // '[object Date]'
Object.prototype.toString.call(Math) // '[object Math]'
Object.prototype.toString.call(new Set()) // '[object Set]'
Object.prototype.toString.call(new WeakSet()) // '[object WeakSet]'
Object.prototype.toString.call(new Map()) // '[object Map]'
Object.prototype.toString.call(new WeakMap()) // '[object WeakMap]'
Мы можем обнаружить, что этот метод может возвращать соответствующий точный тип объекта, когда передается значение любого типа. Хотя использование простое и понятное, есть несколько моментов, которые необходимо четко понимать:
- Метод по существу зависит от
Object.prototype.toString()метод для получения внутренних свойств объекта[[Class]] - Передача примитивного типа, но возможность определить результат, потому что значение обернуто
-
nullа такжеundefinedВозможность вывода результатов обеспечивается внутренней реализацией
Сводка, связанная с NaN
NaNКонцепция чего-либо
NaNявляется свойством глобального объекта,NaNявляется свойством глобального объекта,NaNэто особыйNumberТипы.
Когда возвращать NaN (второй вопрос в дебюте тоже решается)
- бесконечность разделить на бесконечность
- извлеките квадратный корень из любого отрицательного числа
- Арифметические операторы используются с операндами, которые не являются номерами или не могут быть преобразованы в цифры
- Разбор строки в числа
Некоторые примеры:
Infinity / Infinity; // 无穷大除以无穷大
Math.sqrt(-1); // 给任意负数做开方运算
'a' - 1; // 算数运算符与不是数字或无法转换为数字的操作数一起使用
'a' * 1;
'a' / 1;
parseInt('a'); // 字符串解析成数字
parseFloat('a');
Number('a'); //NaN
'abc' - 1 // NaN
undefined + 1 // NaN
//一元运算符(注意点)
+'abc' // NaN
-'abc' // NaN
Непонимание
toStringа такжеStringразница
toString
-
toString()Вы можете преобразовать все данные в строки, ноnullа такжеundefinedНе конвертируемый.console.log(null.toString()) //报错 TypeError: Cannot read property 'toString' of null console.log(undefined.toString()) //报错 TypeError: Cannot read property 'toString' of undefined -
toString()Числа можно записывать в круглых скобках, обозначая основаниедвоичный: .toString(2);
Восьмеричный: .toString(8);
Десятичный: .toString(10);
шестнадцатеричный: .toString(16);
String
-
String()могуnullа такжеundefinedПреобразовано в строку, но не может быть преобразовано в строкуconsole.log(String(null)); // null console.log(String(undefined)); // undefined
общаться с
Обратите внимание на общедоступный номер: «Руководство по развитию программиста», получайте больше избранных статей