关于this的总结
- 沿着作用域向上找最近的一个function(不是箭头函数),看这个function最终怎样执行的
- this的指向取决所属function的调用方式,而不是定义
- function调用一般分为一下几种情况
- 作为函数调用,即: foo()
function foo () {
//指向全局对象(globalThis),注意严格模下是undefined
console.log(this) // window
}
- 作为方法的调用,即
foo.bar() / foo.bar.fn() / foo['bar']() / fo[0]()
function bar () {
console.log(this)
}
const foo = {bar:bar}
foo.bar() // foo
const obj = {
bar:{
fn:bar
}
}
obj.bar.fn() // bar
const arr = [bar]
arr[0]() // arr
//总结:指向最终调用这个方法的对象
- 作为构造函数调用,即 new Foo()
class Foo {
constructor () {
console.log(this)
}
}
new Foo()
// 指向一个新对象Foo{}
- 特殊调用,即 foo.call() / foo.apply() / foo.bind()
function foo(){
console.log(this)
}
const obj = {}
foo.call(obj) //obj
foo.call(1) //Number
//指向参数指定成员
- 找不到所属的function,就是全局对象
console.log(this)
- 箭头函数中的this指向离他最近作用域中的this,他会一层层往上查找,直到找到含有this
function fn () {
const foo = ()=>{
console.log(this)
}
foo()
}
const obj = {fn:fn}
obj.fn() //obj
fn() //window
- 事件绑定中的this,一般就是绑定事件的DOM元素
const elm = document.createElement('div')
elm.addEventListener('click',function (){
console.log(this) //elm
})
练习看看下面this指向谁
var length = 10
function fn () {
console.log(this.length)
}
var obj = {
length:5,
method (fn) {
fn() //?
arguments[0]() //?
}
}
obj.method(fn,1,2,3)
var x = 2
var obj = {x:3}
obj.fn = (function () {
this.x *= ++x
return function (y){
this.x *= (++x + y)
console.log(x)
}
})()
var fn = obj.fn
obj.fn(5) //?
fn(4) //?
上述答案依次是 10 4 7 84