this的相关绑定规则
所谓的this指向,就是一个对象。不同调用情况下同一个this的指向都可能不同,同时我们也可以手动修改this指向。
一、默认绑定
如下图所示
var a = 1
var obj = {
a: 2,
}
function fn() {
// 'use strict'
console.log(this.a)
}
fn()
如果在函数调用fn()前什么也没有,那么此时的fn内的this —> window。也就是控制台打印的a为全局变量中的 a = 1。
这里要注意如果在严格模式(use strict)下this将不会指向window,而是会报错。
二、隐式绑定
如下图所示
var a = 1
var obj = {
a: 2,
fn: function () {
console.log(this.a)
},
}
obj.fn()
var objj = {
a: 3,
b: obj,
}
objj.b.fn()
如果函数调用前有对象【obj.fn( ) / objj.b.fn()】,此时fn中的this会指向距离最近的obj。就像上述代码中控制台会打印两个2.
来一个小测试测试以下朋友们
function fn1() {
console.log(this.a)
}
var obj = {
a: 1,
fn1: fn1,
}
var a = 2
function fn2(fn) {
fn()
}
fn2(obj.fn1)
这里的答案为2,因为在fn前什么也没有,所有这边是我们说的默认绑定,也就是this ——>window。看到这里有没有对前两种的绑定有更深的理解?
三、显示绑定
var a = 1
function fn() {
console.log(this.a)
}
var obj = {
a: 2,
}
fn.call(obj)
当使用了call/bind/apply去处理函数fn时,此时,fn的this指向(call、bind、apply)第一个参数。就像上述代码中this指向的是obj,所以答案为2.
当然也有特例
fn.call(null)
当call、bind、apply的第一个实参传递的是null、undefined,会让显示绑定规则失效,这题就会变成默认绑定,答案为1.
四、 new绑定
function Person() {
console.log(this)
this.a = a
}
var p = new Person()
如果函数是构造函数,此时this指向实例化对象。
这里我们可以稍微拓展以下。
这里new的作用是:1.修改函数this的指向
2.可以调用函数, 有意思的是在控制台中打印new Person ,也是可以成功的打印出实例化对象。
感兴趣的小伙伴可以在控制台中试一下。
拓展
问:当出现多个绑定方式的时候该如何确定this的指向呢?
答:他们其实是有一个优先级的。
new > 显式 > 隐式 > 默认 。