Вы действительно понимаете типы данных JavaScript, которые часто задают интервьюеры?

JavaScript опрос
Вы действительно понимаете типы данных JavaScript, которые часто задают интервьюеры?

предисловие

Я ранее брал интервью у нескольких разработчиков. Они сделали много проектов и у них хорошие способности, но я обнаружил, что основа 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Существует семь встроенных типов данных, включаябазовый типа такжетип объекта.

базовый тип

Существует шесть основных типов:

  • строка (строка)
  • логическое значение (логическое значение)
  • количество
  • символ
  • ноль (нулевое значение)
  • неопределенный

Уведомление:

  1. string,number,booleanа такжеnull undefinedЭти пять типов коллективны.примитивный тип(Примитивный), указывающий на базовый тип, который не может быть далее подразделен;

  2. symbolэто новый тип данных в ES6,symbolпредставляет уникальное значение, черезSymbolГенерация вызова функции, так как сгенерированное значение символа является примитивным типом, поэтомуSymbolфункция не может быть использована newпередача;

  3. 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:
  1. сначала позвониobjизtoStringметод, если примитивный, тоreturn, иначе перейти к шагу 2
  2. передачаobjизvalueOfметод, если примитивный, тоreturn, иначе перейти к шагу 3
  3. бросатьTypeErrorаномальный
  • типnumber:
  1. сначала позвониobjизvalueOfметод, если примитивный, тоreturn, иначе перейти к шагу 2
  2. передачаobjизtoStringметод, если примитивный, тоreturn, иначе шаг 3
  3. бросатьTypeErrorаномальный
  • параметр типа пуст
  1. ОбъектDate, установлен типString
  2. В противном случае устанавливается тип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:

  1. undefined
  2. null
  3. -0
  4. 0 или +0
  5. NaN
  6. '' (пустой строки)

Значения, отличные от 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Подробные примеры:

  1. слеваstring,ToPrimitiveИсходное значение не меняется после преобразования
  2. При конвертации справа то же самоеToPrimitiveВыполните преобразование примитивного значения, так как указанный типnumber,провестиToPrimitiveконверсионный вызовobj2.valueof(), полученное значение не является исходным, переходим к третьему шагу
  3. передачаtoString() return 'a'
  4. существует с обеих сторон символаstring,И является+Используются символьные операторыStringПравила преобразуются вstringТип для соединения
  5. выходной результат2a

к следующему'2'+obj1Подробные примеры:

  1. слеваstring,ToPrimitiveБез изменений после преобразования в исходное значение
  2. При конвертации справа то же самоеToPrimitiveВыполните преобразование примитивного значения, так как указанный типnumber,провестиToPrimitiveконверсионный вызовobj2.valueof(),получать{ a: 1, b: 2 }
  3. передачаtoString() return [object Object]
  4. существует с обеих сторон символаstring, и используется оператор +StringПравила преобразуются вstringТип для соединения
  5. выходной результат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пример

  1. еслиx,yобеnumber, прямое сравнение

нечего объяснять

1 == 2 //false
  1. Если есть объект,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
  1. существует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'

Вывод приведенного выше кода можно увидеть,

  1. nullВ суждении есть ошибка, а результат получен

При использованииtypeof,nullПолученный результатobject

  1. Оператор определяет тип объекта и его подтипы, такие как функции (вызываемые объекты), массивы (объекты упорядоченного индекса) и т. д., все, кроме функций, получат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
  1. 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
    
  2. toString()Числа можно записывать в круглых скобках, обозначая основание

    двоичный: .toString(2);

    Восьмеричный: .toString(8);

    Десятичный: .toString(10);

    шестнадцатеричный: .toString(16);

  • String
  1. String()могуnullа такжеundefinedПреобразовано в строку, но не может быть преобразовано в строку

    console.log(String(null));
    // null
    console.log(String(undefined));
    // undefined
    

общаться с

Обратите внимание на общедоступный номер: «Руководство по развитию программиста», получайте больше избранных статей

Стек технологий личного публичного аккаунта

QR-код официального аккаунта