乐趣区

关于前端:10道JS高频面试题重要

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 成立?

// 办法 1
var a = {
  value: 1,
  valueOf: function () {return this.value++;}
};

// 办法 2
var a = {
  value: 1,
  toString: function () {return this.value++;}
};

// 办法 3
var 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 res
res = 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 // 2

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

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

  • 对象和非对象

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

退出移动版