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({}, 2, 3) //此时,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,两种方案:
- 正则
const trim = (str) => {
return str.replace(/^\s+|\s+$/g, '')
}
- 剪切
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 正则
- 阅读《三十分钟入门正则表达式》
- 每天使用