初学者关于this
的理解一直很模糊,关于this
的面试题更加令人头大。
this
是函数执行的主体(谁执行的),this 是和执行上下文绑定的。
请记住:this是谁和函数在哪儿创建的或者在哪执行的都没有关系
1. 给元素的某个事件绑定方法,当事件触发方法执行的时候,方法中的this
是当前操作的元素(隐式绑定)
document.body.onclick = function() {
// this: body
}
通常来说this的值是触发事件的元素的引用,这种特性在多个相似的元素使用同一个通用事件监听器时非常让人满意。
当使用 addEventListener() 为一个元素注册事件的时候,句柄里的 this 值是该元素的引用。其与传递给句柄的 event 参数的 currentTarget 属性的值一样。
2. 方法执行,看方法前面是否有点(.),如果有点,点前面是谁this
就是谁(隐式绑定),没有点this
就是window
(在严格模式下("use strict
")没有点this
是undefined
,也成为默认绑定)
注意:自执行函数((function(){...})()
)的this
一般是window
function fn() {
console.log(this)
}
let obj = {
fn: fn
}
fn()
obj.fn()
上述代码等同于:
let obj = {
fn: function fn() {
console.log(this)
}
}
fn()
obj.fn()
3. 在构造函数模式执行中,函数体中的this
是当前类的实例
执行new操作的时候,将创建一个新的对象,并且将构造函数的this指向所创建的新对象。JS编译器会做这四件事情:
-
创建一个新的空的对象
-
把这个对象链接到原型对象上
-
这个对象被绑定为this
-
如果这个函数不返回任何东西,那么就会默认return this
function Fn(name) {
// this: Fn类的实例
this.name = name
}
var f1 = new Fn('qxj')
var f2 = new Fn('lx')
console.log(f1.name)
console.log(f2.name)
输出:qxj
lx
4.绑定优先级
总结:
- 箭头函数(
() => {}
) - 关键字new调用(
new Person()
) - 显式绑定(
bind/apply/call
) - 隐式绑定(
obj.foo()
) - 默认绑定(
foo()
)