1. 为什么 typeof null === 'object' ?

typeof null // 'object'

因为 JavaScript 中,一个变量的值会被保留在一个 32 位的内存单元中。该单元蕴含一个 1 或 3 位的类型标记理论数据的值。类型标记存储在单元的最初

  • 000:object - 对象
  • 1:int - 整数
  • 010:double - 浮点数
  • 100:string - 字符串
  • 110:boolean - 布尔值
  • undefined -2^30
  • null 空指针(全是 0)

后果很显著,因为 null 的存储单元(全是 0)最初三位和 object 齐全一样是 000

2. 等式 0.1 + 0.2 === 0.3 不成立?

0.1 + 0.2 === 0.3 // false

因为二进制浮点数中的 0.1 和 0.2 并不是非常准确,在两数相加时,会先转换成二进制,0.1 和 0.2 转换成二进制的时候尾数会产生有限循环,而后进行对阶运算,JS 引擎对二进制进行截断,所以造成精度失落。所以它们相加的后果不是刚好等于 0.3,而是一个十分十分十分靠近的数字:0.300000000000000004,所以条件判断为 false。

3. a==1 && a==2 && a==3 成立?

// 办法1var a = {  value: 1,  valueOf: function () {    return this.value++;  }};// 办法2var a = {  value: 1,  toString: function () {    return this.value++;  }};// 办法3var value = 1;Object.defineProperty(window, "a", {  get: function () {    return this.value++;  }});if (a === 1 && a === 2 && a === 3) {  console.log("这也太神奇了吧!")}

办法一、二:利用 JS 对象有 toString() 和 valueOf() 两个办法,toString()将该对象的原始值以字符串的模式返回,valueOf()返回最适宜该对象的原始值

1.用运算符对对象进行转换的时候 valueOf()的优先级高于 toString()

2.对对象进行强字符串转换时会优先调用 toString()

3.toString()办法不能对 null 和 undefined 进行字符串转换,能够用 String()办法代替

办法三:应用 Object.defineProperty()劫持变量 a,在 get 中返回变量 a++的值。

4. 字符串反转('zbw'->'wbz')?

var name = 'zbw'var resres = name.split('').reverse().join('')console.log(res) // 'wbz'

先把字符串转为数组,而后调用数组的 reverse 办法反转数组元素,最初把数组转回字符串即可

5. 函数每秒顺次输入 1,2,3,4,5...9?

for(var i = 0; i < 10; i++) {  setTimeout(function timer() {    console.log(i)  }, i * 1000)}

冀望:每秒顺次打印 1、2、3、4、5...9

后果:每秒打印的都是 10

  1. 利用 IIFE
for(var i = 0; i < 10; i++) {  (function(i) {    setTimeout(function timer() {        console.log(i)    }, i * 1000)  })(i)}
  1. let 关键字
for(var i = 0; i < 10; i++) {  let j = i // 闭包的块作用域  setTimeout(function timer() {    console.log(j)  }, j * 1000)}
  1. let 关键字(举荐写法)
for(let i = 0; i < 10; i++) {  setTimeout(function timer() {    console.log(i)  }, i * 1000)}

6. 说一说 this 的指向问题?

要判断一个运行中的函数的 this 绑定,须要找到该函数的调用地位(联合调用栈),接着依据优先级得出的四条规定来判断 this 的绑定对象。

  1. 函数由 new 调用?绑定到新创建的对象
  2. 由 call/apply/bind 调用?绑定到指定对象
  3. 由上下文对象调用?绑定上下文对象
  4. 默认:严格模式下绑定到 undefined,否则绑定到全局对象

ES6 的箭头函数不实用以上四条规定,而是依据以后的词法作用域来决定 this 绑定,也就是说,箭头函数会继承外层函数调用的 this 绑定(无论绑定到什么),而且箭头函数的 this 绑定无奈被批改

7. JavaScript 的数据类型?

number、string、boolean、undefined、null、object、symbol、bigInt

其中除了 object 以外,其余的类型统称为根本数据类型

object 类型称为援用数据类型(简单数据类型),它蕴含两个子类型(array、function)

8. Symbol 类型有什么作用?

  1. 能够用来示意一个举世无双的变量,避免命名抵触。
  2. 能够用来模仿公有变量。(利用 symbol 不会被惯例的办法(除了 Object.getOwnPropertySymbols 外)遍历)
  3. 次要用来提供遍历接口,安排了 symbol.iterator 的对象才能够应用 for···of 循环,可对立解决数据结构。

9. NaN 是什么?typeof NaN 输入?

NaN(not a number)不是一个数字,但 typeof NaN 输入 'number'。换句话说,NaN 能够了解为不是数字的数字(尽管有点绕口)。

10. JavaScript 的隐式转换?

个别状况下,非根本数据类型的数据会 优先调用 valueOf() 来获取根本数据类型的值,如果无奈获取则持续调用 toString() 获取根本数据类型的值。

  • 字符串和数字相加

如果有一个为字符串,那么都转化为字符串而后执行字符串拼接

'11' + 23 + '24' // 112324
  • 字符串和数字相减

转化为数字再进行运算

'11' - 2 // 9
  • 布尔值和数字

转化为数字再进行运算

1 + true // 21 + false // 1
  • 其余类型和布尔类型

将布尔类型转化为数字再进行运算

  • 对象和非对象

执行对象 ToPrimitive(valueOf/toString)而后再进行比拟