题目:
以最小的改动解决一下代码的错误(可以使用es6);
var obj={
name:'jsCoder',
skill:['es6','react','angular'],
say:function(){
for(var i=0,len=this.skill.length;i<len;i++){
setTimeout(function(){
//console.log(this);
console.log('No.'+i+this.name);
console.log(this.skill[i]);
console.log('---------------');
},0);
console.log(i);
}
}
};
obj.say();
错误执行
0
1
2
NO.3
报错
NO.3
报错
NO.3
报错
期望得到以下结果
1
2
3
No.1 jsCoder
es6
---------------------
No.2 jsCoder
react
---------------------
No.3 jsCoder
angular
---------------------
改动后的代码
var obj={
name:'jsCoder',
skill:['es6','react','angular'],
say:function(){
for(let i=0,len=this.skill.length;i<len;i++){
setTimeout(()=>{
console.log('No.'+(i+1)+this.name);
console.log(this.skill[i]);
console.log('---------------');
},0);
console.log(i+1);
}
}
};
obj.say();
说明:考察箭头函数和let块状域
1、《JavaScript高级程序设计》第二版中,写到:“超时调用的代码都是在全局作用域中执行的,因此函数中this的值在非严格模式下指向window对象,在严格模式下是undefined”。也就是说在非严格模式下,setTimeout中所执行函数中的this,永远指向window!!
2、 *let是更完美的var,不是全局变量,具有块级函数作用域,大多数情况不会发生变量提升。const定义常量值,不能够重新赋值,如果值是一个对象,可以改变对象里边的属性值。
1、let声明的变量具有块级作用域
2、let声明的变量不能通过window.变量名进行访问
3、形如for(let x…)的循环是每次迭代都为x创建新的绑定