一.简述
js只有两个作用域,全局和函数作用域,且由于js的早期设计缺陷,所以js并没有真正意义上的块级作用域,不过现在使用let可解决这个的部分问题
二.实战
var name = 'window'
var obj1 = {
name: 'person1',
show1() {
console.log(this.name)
},
show2: () => {
console.log(this.name)
},
show3() {
return function() {
console.log(this.name)
}
},
show4() {
return () => {
console.log(this.name)
}
}
}
var obj2 = {
name: 'person2'
}
obj1.show1()
obj1.show1.call(obj2)
//第一个输出person1,因为show1()与name处于同一作用域obj1
//第一个输出person2,因为call()将show1()的作用域绑定到了obj2
obj1.show2()
obj1.show2.call(obj2)
//第一个输出window,因为show2()使用了箭头函数,将本应该在obj1的作用域指向了window(最外层)
//第二个输出window,原理和上一个相同,虽然改变了指向,但最终还是被箭头函数指向了外部
obj1.show3()()
obj1.show3().call(obj2)
obj1.show3.call(obj2)()
//首先理解obj1.show3()(),拆开写法为 第一步:var xx = obj1.show3();第二步:xx();
//第一个输出window,因为正如上面的简写解析,在第一步时,已经将xx的作用域指向了window,而非内部
//第二个输出person2,与第一个不同的是,这里在第二步时将xx的作用域指向了obj2
//第三个输出window,与第二个不同的是,这里在第一步时将xx的作用域指向了obj2,所以并没有影响xx的作用域
obj1.show4()()
obj1.show4().call(obj2)
obj1.show4.call(obj2)()
//首先要先知道箭头函数的一个特性,箭头函数体内的this始终就指向了定义时的对象
//第一个和第二个输出person1,由于前面所述的特性
//第三个输出person2,前面所述的特性仍然存在,但在调用函数内部的函数之前,将xx的作用域指向了obj2,所以函数内部的函数指向往自身上一层,也就是obj2