Js作用域以及this指向实战详解

2020.03.30
评论

一.简述

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