this到底指向哪里?

236 阅读2分钟

对于javascript中的this指向,做一点个人理解的简单记录。

我认为,this的指向分为两大类,‘静态’和 ‘动态’,‘静态’的指函数定义的时候就知道它的this指向;‘动态’指函数执行的时候才能知道this指向;

‘动态’

独立调用时this的指向

如果函数是独立调用的,也就是说,在非严格模式下,this指向Window

function  aba() {
   console.log(this)      
}
aba();          // 打印出Window

再看一个例子

let obj = {
   name: 'yan',
   say(){
       console.log(this)
   }
}
let objSay = obj.say;
objSay();        //打印出Window

obj.say();    //{name: "yan", say: ƒ}

上面这个例子中,在对象中定义了say方法,将其用一个别的函数接收独立执行的时候,this是指向Window而不是obj。

隐式绑定

隐式绑定,也就是说谁调用这个函数,this指向谁,上面例子中的,obj调用了其say方法,打印出的this为obj本身,再来一个例子。

function foo() {
    console.log(this);
}

let obj = {
   a: 1,
   foo: foo
}
obj.foo();   //{a: 1, foo: ƒ}
//可以看到,obj调用foo方法,this指向obj

显式调用

用call、apply、bind方法给函数显式指定this指向,这个时候的this指向均指向显式绑定的值,在这里不做赘述,简单来一个例子。

var person = {
    fullName: function() {
        return this.firstName 
    }
}
var person1 = {
    firstName:"yan"
}
var person2 = {
    firstName:"shao"
}
person.fullName.call(person1);  // 将返回yan

new 绑定

new 是用来构造函数中实例化一个对象的,这个时候的this指向为构造出来的实例对象;

function Person(name, age) {
    this.name = name;
    this.age = age;
    say() {
        console.log(this.name, this.age);
    }
}

let p1 = new Person('yan', 19);
p1.say();    // 输出 'yan' , 19

‘静态’

‘静态’的意思是,this指向并不是由函数执行的时候决定的,在函数定义的时候就就决定了this的指向;上节提到到四种绑定规则,直接调用、隐式绑定、显示绑定都无效,而箭头函数是无法当做构造函数的,这个可以自己验证下。

箭头函数中,是不存在this的,其this指向,取决于父环境中的this。

let obj = {
    name: 2,
    say: ()=>{
        console.log(this);
    }
}

obj.say();   //this指向window

上面的例子再, obj调用了say方法,如果根据上节的隐式绑定规则:谁调用指向谁, this应该指向obj,但是由于say方法是箭头函数,这种规则失效,this由obj的父环境决定,也就是window。

总结

对this指向做一个简单总结

大类 小类 说明
动态 默认绑定规则 默认指向window
隐式绑定 谁调用指向谁
显式绑定 call、apply、bind显式指定this指向
new绑定 指向构造函数实例本身
静态 箭头函数 箭头函数中本身没有this,由其父环境的this指向决定