this的四个绑定规则

220 阅读2分钟

this的四个绑定规则分为:

  1. 默认绑定
  2. 隐式绑定
  3. 显式绑定
  4. new绑定

默认绑定

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

    foo()//this指向window

当一个函数独立调用,他的this就指向window

而当一个函数内部返回一个函数再调用时,他的this指向又是什么呢?

function foo(){

    function bar(){
      console.log(this)
    }
    return bar
    }
    var fn = foo()
    fn()//this指向window

此时this依然指向window。因为执行foo函数后将返回的bar函数赋值给fn变量,执行fn(),此时函数依然是独立调用。this自然还是指向window

隐式绑定

var obj = {
        name: "lt",
        foo: function() {
            console.log(this.name);
        },
    };
    obj.foo()//结果为lt
    var fn = obj.foo
    fn()//结果为undefind

此时执行obj.foo(),为隐式绑定,this绑定为调用这个函数的对象,在这个对象中找到name属性,然后打印。而将obj.foo赋值给fn变量,再调用,就是默认绑定,this默认绑定到window中找到name属性,而name属性的值默认为undefind

显式绑定

 function foo(name, age) {
        console.log(this);
    }
    const obj = {
        name: "foo",
        age: 18,
    };
    //三种显式绑定的方式
    foo.apply(obj);
    foo.call(obj);
    var fn = foo.bind(obj);
    fn();

此时被apply,call,bind函数绑定的foo函数的this都指向obj对象,这就是显式绑定。

new 绑定

 function Person(name, age) {
        (this.name = name), (this.age = age);
    }
    var f = new Person("发发发", 178);
    console.log(f); //Person {name: '发发发', age: 178}

当将一个函数用new关键字时,这个函数将会默认生成一个对象然后赋值给this,然后返回出去

四种绑定优先级比较

显式绑定和隐式绑定

const obj = {
        name: "hhh",
        foo: function() {
            console.log(this);
        },
    };
    obj.foo.apply("aaa");//"aaa"
    obj.foo.call("bbb");//"bbb"
    var f = obj.foo.bind("jhjh");
    f();//"jhjh"

由此例子可知显式绑定是高于隐式绑定的。

而下面这个例子

 function bar() {
        console.log(this);
    }
    const obj = {
        name: "hhh",
        foo: bar.bind("qqq"),
    };
    obj.foo();//"qqq"

同样这种情况打印的依然是qqq,所以显式绑定高于隐式绑定。

new绑定和显式绑定的优先级比较

由于new关键字不能和callapply同时使用,所以只能和bind比较

 function bar() {
        console.log(this);
    }
    const obj = {
        name: "hhh",
        foo: bar.bind("qqq"),
    };
    var c = new obj.foo();//this指向bar函数

所以new绑定高于显式绑定

由此可得出结论:new绑定>显式绑定>大于隐式绑定>默认绑定