所考察的核心知识点——关于this的指向问题
类型:
(1) 函数名()调用的形式,this指向window对象
(2)对象.方法调用的形式,this指向该对象(即谁调用,this指谁)
(3)test.call() / test.apply() / test.bind()形式,this显式指向参数
拓展:
call、apply、bind的区别
(1)三者的第一个参数都是this的指向,当参数为null或undefined的时候默认指向为window;call和bind的第二个参数是参数列表,apply的第二个参数是参数数组
(2)call和apply是立即调用,而bind返回值是一个新的函数,是延迟调用
(3)call和apply会将第二个参数作为方法的实参传入,而apply会在方法原参数的基础上再累加参数
(4)new test() 形式,this为被new出来的新对象
(5)箭头函数,this在函数定义的时候就已经确定,this指向外层作用域的this的指向
注意:setTimeout的本质属于函数名()调用的方式
题目:
for(var i = 0; i < 5; i++) {
setTimeout(function() {
console.log(i);
}, 300);
}
得到的结果是5个5
若想正确出现下标0,1,2,3,4
则需要修改上面的代码
目前想到的有下面几种方法
方法目录
1. 方法一:立即执行函数传参
for(var i = 0; i < 5; i++) {
(function(i) {
setTimeout(function() {
console.log(i);
}, 300);
})(i);
}
2. 方法二:立即执行函数,换变量
for(var i = 0; i < 5; i++) {
(function() {
var temp = i;
setTimeout(function() {
console.log(temp);
}, 300);
})();
}
3. 方法三:将var换成let关键字
for (let i = 0; i < 5; i++) {
setTimeout(function() {
console.log(i);
}, 300);
}
4. 方法四:使用let换变量
for (var i = 0; i < 5; i++) {
let temp = i;
setTimeout(function() {
console.log(temp);
}, 300);
}
5. 方法五: new function
for (var i = 0; i < 5; i++) {
setTimeout(new function() {
console.log(i);
}, 300);
}
6. 方法六:利用call/apply/bind函数
for (var i = 0; i < 5; i++) {
setTimeout(function() {
console.log(i);
}.call(i), 300);
}