面试题

54 阅读1分钟

setTimeout 代码题

for (var i = 0; i < 6; i++) { // 0 1 2 3 4 5
  setTimeout(function () {
    console.log(i)
  }, 0)  
} 
//问,会打印出什么

答:会打印出 6 个 6

原因:setTimeout 是异步函数,会塞入异步队列中,把代码执行推迟,等到 for 全部循环一遍之后,再执行 log i 6次

如果希望打印出 0 1 2 3 4 5

方案:把 var 改为 let

原因:for+let 会形成迭代绑定,每次进入循环会生成一个新的 i,这个新的 i 的值等同于外面的i

方案2:在 for 循环里添加 let x = i

原因同上,手动实现迭代绑定

方案3:立即执行函数

for(var i = 0; i<6; i++){
  !function(i){
    setTimeout(() => {
      console.log(i);
    }, 0);
  }(i)
}

call、apply和 bind 的区别

区分题目,分别说出定义、用途和优缺点(优点、缺点和缺点的解法)即可

  • call—用于调用函数 fn,第一个参数是 this,后面的所有参数是 arguments

fn.call(this, 1, 2)

  • apply
    • 跟 call 一样,唯一区别是只接受两个参数,第二个参数是数组

fn.apply(this, [1, 2])

call 和 apply 的区别在于,如果数组长度不确定,则用apply

ES6 的新语法中,可以用 fn.call(this, ...args)展开数组,因此两者差不多了

  • bind 并不调用函数,用于为函数绑定参数,并返回新的函数
const f2 = fn.bind({}, 23)				//此时,f2 的函数体为 {}
f2()

this 面试题

看函数的 this 是什么,看调用即可

function fn(p1, p2){
  console.log(this);
  console.log(p1, p2);
}
fn()				//如果直接调用,则 this 为 window/undefined(严格模式下)

闭包 面试题

  • 定义:自由变量 a + 函数 f1 称为闭包
let a = 1
function fo(){
  console.log(a);					//这就是闭包
}

用途:当我们需要隐藏数据暴露接口的时候,可以把数据放在闭包里,把接口放进函数里,return 出去 如:

优缺点:

  • 隐藏核心数据,暴露接口
  • 有可能造成内存泄漏,解决方法是少用闭包,用 class 对象

trim 面试题

trim 即删除字符串两端的空格

手写trim,两种方案:

  1. 正则
const trim = (str) => {
  return str.replace(/^\s+|\s+$/g, '')
}
  1. 剪切
const trim2 = (str) => {
  while (str[0] === ' ') {
    str = str.slice(1)
  }
  while (str[str.length - 1] === ' ') {
    str = str.slice(0, -1)
  }
  return str
}

how to learn 正则

  1. 阅读《三十分钟入门正则表达式》
  2. 每天使用