根据《你不知道的JavaScript(上卷)》
关于this的章节,进行了简单的总结
重点:判断一个运行中函数的 this 绑定,就需要找到这个函数的直接调用位置,即this只能在调用时确定
function foo() {
console.log(this.a)
}
const a = 10
// 直接调用,没用任何的修饰
foo() // 10
这种情况下,当调用这个函数时,this指向当前的上下文,也就是window,如果使用了严格模式,那么this指向的是undefined,就会报错
function foo() {
console.log(this.a)
}
const obj = {
a: 2,
foo,
}
const a = 10
// 通过对象作为属性时调用
obj.foo() // 2
function foo() {
console.log(this.a)
}
const obj = {
a: 2,
foo: foo,
}
const bar = obj.foo // 简单的理解,其实就是一个取值,再赋值的操作,和this没有任何关系
const a = 'oops, global'
bar() // "oops, global" 这种形式其实是默认调用,所有指向window
这种情况下,当调用这个函数时,this指向调用的那个对象,也就是obj
function foo() {
console.log(this.a)
}
const obj = {
a: 2,
foo,
}
const a = 10
// 通过call或apply,手动给函数指定this,就是传进来的第一个参数
foo.call(obj) // 2
// ps:如果call(apply同理),如果第一个参数为null,则会忽略
function foo() {
console.log(this.a)
}
const a = 2
foo.call(null) // 2
//ps: 硬绑定后,不能再修改它的 this
function foo() {
console.log(this.a)
}
const obj = {
a: 2,
}
const bar = function () {
foo.call(obj)
}
bar() // 2
const a = 100
setTimeout(bar, 100) // 2
// 硬绑定的 bar 不可能再修改它的 this
bar.call(window) // 2
这种情况下,当调用这个函数时,this指向call的第一个参数,也就是obj
JavaScript中的函数,并没有所谓的构造函数的概念,只是这个函数能用new进行构造调用,创建新对象
function foo(a) {
this.a = a
}
// 通过new调用
const bar = new foo(2)
console.log(bar.a) // 2
这种情况下,当调用这个函数时,this指向新创建的那个对象
优先级如下
const bar = new foo()
const bar = foo.call(obj2)
const bar = obj1.foo()
const bar = foo()