this指向

  • 什么是this

    this是在函数调用时建立的一个绑定,this不是在编写的时候绑定的,而是在运行时绑定的,他依赖于函数调用的上下文关系,this绑定与他的调用点有关,而与函数的声明位置无关。

  • 调用点:函数在代码中被调用的位置。
  • 3种this绑定的规则

    1 默认绑定:这种绑定规则是在没有其他规则时使用,常见有:独立函数调用(如下)

function foo(){ 
    console.log( this.a ); 
} 
var a = 2; 
foo();// 2 此时foo是在全局中被调用的,所以this指向了全局对象,this.a相当于window.a,故输出2

    2 隐含绑定    

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

var obj = {
    a: 2,
    foo: foo
};

obj.foo(); // 2 this此时指向obj,所以this.a相当于obj.a 

     隐含绑定丢失

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

function doFoo(fn) {
    // `fn` 只不过`foo`的另一个引用

    fn(); // <-- 调用点!
}

var obj = {
    a: 2,
    foo: foo
};

var a = "global"; // `a`也是一个全局对象的属性

doFoo( obj.foo ); // "global",doFoo()调用时this指向全局,所以指向this.a是会调用全局属性a而不是obj中的a

    3 明确绑定 使用call apply bind(硬绑定,解决this丢失的问题)

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

var obj = {
    a: 2
};
var a = "global";

foo.call( obj ); // 2
  • 绑定的优先级  明确绑定 > 隐含绑定 > 默认绑定
  • 绑定类型判定

    函数是否用call apply bind调用,是就是明确绑定 -> 函数环境对象调用的话就是隐含绑定 -> 默认绑定

  • 特例

    明确绑定中的参数this的指向为null和undefined的时候采用默认绑定

    间接引用:

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

var a = 2;
var o = { a: 3, foo: foo };
var p = { a: 4 };

o.foo(); // 3
(p.foo = o.foo)(); // 2 赋值表达式p.foo = o.foo的 结果值 是一个刚好指向底层函数对象的引用。如此,起作用的调用点就是foo(),而非你期待的p.foo()o.foo()。根据上面的结果,默认绑定 规则适用。

    箭头函数 :一旦绑定就不会被覆盖   

function foo() {
  // 返回一个arrow function
    return (a) => {
    // 这里的`this`是词法上从`foo()`采用
        console.log( this.a );
    };
}

var obj1 = {
    a: 2
};

var obj2 = {
    a: 3
};

var bar = foo.call( obj1 ); //bar是return的箭头函数的引用,已经指向obj1,此后不在覆盖
bar.call( obj2 ); // 2, 不是3!

 

posted @ 2018-03-13 13:11  BarneyWhite  阅读(99)  评论(0编辑  收藏  举报