functionexample () { this === window// true console.log(this.n) }
(function () { 'use strict' example() // 1 })()
匿名函数没有绑定任何对象,因此其 this 通常指向 window(作为独立函数执行)。
var n = 1
var obj = { n: 2, example: function () { returnfunction () { returnthis.n } } }
obj.example()() // 1
作为对象的方法中的 this
调用对象的方法时,方法里的 this 指向调用这个方法的对象
var obj = { example: function () { console.log(this) } }
obj.example() // obj
对象属性引用链中只有上一层或者最后一层在调用位置中起作用。方法中的 this 只指向当前一层的对象。
var obj = { n: 1, obj2: { n: 2, example: function () { console.log(this.n) } } }
obj.obj2.example() // 2 this 指向 obj.obj2 // 谁调用函数,函数中的 this 就指向谁。 // obj.example() this 是 obj // obj.obj2.example() this 是 obj.obj2 // obj.obj2.obj3.example() this 是 obj.obj2.obj3
绑定对象丢失
var n = 1
var obj = { n: 2, example: function () { console.log(this.n) } }
var obj2 = obj.example obj2() // 1
obj2 引用的是 example 函数本身,obj2() 的调用等同于独立函数调用
参数传递就是一种隐式赋值,因此在函数传值也会出现上例的状况。
var n = 1
var obj = { n: 2, example: function () { console.log(this.n) } }
functionexample2 (fn) { fn() }
example2(obj.example) // 1
js 的原生方法也不例外
var n = 1
var obj = { n: 2, example: function () { console.log(this.n) } }
setTimeout(obj.example, 0) // 1
构造函数调用中的 this
构造函数中的 this 指向新创建的实例对象。
在使用 new 运算符来调用构造函数时,会执行一下操作:
创建一个新对象。
将这个新对象的原型指向构造函数的 Prototype。
将这个新对象赋值给函数的 this。
执行构造函数并返回这个新对象(在函数没有返回其他对象的情况下)。
functionPerson (name, age) { this.name = name this.age = age }
var tom = newPerson('tom', 18) console.log(tom.name, tom.age) // tom 18
箭头函数的 this 是当前的词法作用域决定的
箭头函数中的 this 为外层函数的 this(箭头函数定义时所在作用域的 this)。
var n = 1 var obj = { n: 2, f: function () { // 箭头函数定义时的作用域(箭头函数外层作用域) var n = 3 example = () => { // 箭头函数的作用域 console.log(this.n) } returnexample() } }
obj.f() //2
箭头函数中的 this 无法被修改
var n = 1 var obj = { n: 2, f: function () { var n = 3 example = () => { console.log(this.n) } return example.call({ n: 4 }) } }