* 一个特例 * 开始判断 * 法则一:对象方法中的this指向对象自己(箭头函数形式的除外) * 法则二:多层嵌套函数中的this指向等同于包含该this的最近一个function的this * 法则三:箭头函数以及非指向对象方法中的function的状况下this指向window * 习题集 * 普通函数中的this * 函数执行后返回另一个函数中的this(普通函数中) * 多层嵌套函数中的this(定时器&箭头函数)1 * 多层嵌套函数中的this(定时器&箭头函数)2
在正式开始以前,咱们先来讲一个特例。javascript
// 构造函数 function Student(name) { this.name = name } // 建立小明和小红两个实例 var XM = new Student('xiaoming') var XH = new Student('xiaohong') // 输出信息 console.log(XM) // Student {name: "xiaoming"} console.log(XH) // Student {name: "xiaohong"}
在构造函数中,this上的值会在建立实例的时候被绑定到新建立的实例上。不适用于下面的判断方法,因此特此说明。前端
下面是一个典型例子,咱们的分析从这里开始。java
var x = { name: 'bw2', getName1: function() { console.log(this) }, getName2: function() { setTimeout(() => { console.log(this) },0) }, getName31: () => { console.log(this) }, getName32: function() { return function() { console.log(this) } } } x.getName1() // {name: "bw2", getName1: ƒ} x.getName2() // {name: "bw2", getName1: ƒ} x.getName31() // Window {stop: ƒ, open: ƒ, alert: ƒ, confirm: ƒ, prompt: ƒ, …} x.getName32()() // Window {stop: ƒ, open: ƒ, alert: ƒ, confirm: ƒ, prompt: ƒ, …}
var x = { name: 'bw2', getName1: function() { console.log(this) } } x.getName1() // {name: "bw2", getName1: ƒ}
箭头函数没有独立的this做用域,因此继续往外层走,走到了getName: function(){}。那么就是他了,this指向等同于这个function内部的this指向。根据法则一,this指向对象自己。浏览器
var x = { name: 'bw2', getName2: function() { console.log(this) // 等同于此处的this setTimeout(() => { console.log(this) // 原始的this位置 },0) } } x.getName2() // {name: 'bw2', getName1: ƒ}
咱们能够试着在浏览器中运行,看看结果。微信
根据法则二,this是指向最近的function,所以,这里的this等同于返回的函数中的this,不是对象方法中的this,因此,指向全局。函数
是否是感受有点奇怪?不过实践证实确实如此。测试
var x = { name: 'bw2', getName31: () => { console.log(this) }, getName32: function() { return function() { console.log(this) } } } x.getName31() // Window {stop: ƒ, open: ƒ, alert: ƒ, confirm: ƒ, prompt: ƒ, …} x.getName32()() // Window {stop: ƒ, open: ƒ, alert: ƒ, confirm: ƒ, prompt: ƒ, …}
欢迎你们按照法则一到三依次判断,猜想结果,并在浏览器下测试。测试结果也能够回复,你们一块儿讨论。this
因本人能力有限,该系列法则可能在部分状况下失效。欢迎你们一块儿讨论。spa
下面是作题时间。code
function x() { console.log(this) } x()
function xx(){ return function() { console.log(this) } } xx()()
var x = { name: 'bw2', getName: () => { setTimeout(() => { console.log(this) },0) } } x.getName()
var x = { name: 'bw2', getName: () => { setTimeout(function() { console.log(this) },0) } } x.getName()
再次说明,该法则为实验性法则,未进行大范围的测试,不保证在全部状况下都有一致的结果。若是你发现了法则判断失败的状况,欢迎留言,一块儿探讨。
欢迎关注前端进阶指南微信公众号:
另外我也创了一个对应的QQ群:660112451,欢迎一块儿交流。