this绑定的顺序

在上一章,我们已经知道了一共有4种绑定的方式

  1.默认绑定                       

  2.隐式绑定                       

  3.显示绑定                       

  4.new绑定                       

如果你不记得的话请看上一节 传送点

  在这4种绑定中,我们知道默认绑定的级别是最低的!!!!!为什么?

    因为上面的所有都不能用了才考虑默认绑定,请考虑下面的代码

        var obj={
            d:10,
            fn:function(){
                console.log(this.d);//10
                function foo(){
                
                    console.log(this);//window
                    console.log(this.d);//undefined
                }
                foo();//在这里只是一个函数调用!!!!!!!!!!!!,所以指向的是window
            }
        }
        obj.fn();

所以说默认绑定的级别是最低的                                          

隐式绑定vs显示绑定                                                                                                                    

        function foo(){
            console.log(this.a);
        }
        var b={
            a:100,
            foo:foo
            };
        var b2={
                a:200,
                foo:foo
                };
            b.foo();//100
            b2.foo();//200
        b.foo.call(b2);//200
        b2.foo.call(b);//100

  可以看到显示绑定的优先级别高于隐式绑定                                                                 

隐式绑定 vs new绑定                                                                                                                                                                    

function foo(something) {
this.a = something;
}
var obj1 = {
foo: foo
};
var obj2 = {};
obj1.foo( 2 );
console.log( obj1.a ); // 2
obj1.foo.call( obj2, 3 );
console.log( obj2.a ); // 3
var bar = new obj1.foo( 4 );
console.log( obj1.a ); // 2
console.log( bar.a ); // 4

          可以看到New绑定高于隐式绑定

显示绑定 vs New绑定                                                                                                                 

function foo(something) {
this.a = something;
}
var obj1 = {};
var bar = foo.bind( obj1 );
bar( 2 );
console.log( obj1.a ); // 2
var baz = new bar(3);
console.log( obj1.a ); // 2
console.log( baz.a ); // 3

判断 this                                                                                                           
  现在我们可以根据优先级来判断函数在某个调用位置应用的是哪条规则。可以按照下面的
  顺序来进行判断:
1. 函数是否在 new 中调用( new 绑定)?如果是的话 this 绑定的是新创建的对象。
  var bar = new foo()
2. 函数是否通过 call 、 apply (显式绑定)或者硬绑定调用?如果是的话, this 绑定的是
  指定的对象。
  var bar = foo.call(obj2)
3. 函数是否在某个上下文对象中调用(隐式绑定)?如果是的话, this 绑定的是那个上
  下文对象。
  var bar = obj1.foo()
4. 如果都不是的话,使用默认绑定。如果在严格模式下,就绑定到 undefined ,否则绑定到
  全局对象。
  var bar = foo()
  就是这样。对于正常的函数调用来说,理解了这些知识你就可以明白 this 的绑定原理了。
  不过……凡事总有例外。

间接引用                                                                                                                       

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

this 词法                                                                                                 

 

function foo() {
// 返回一个箭头函数
return (a) => {
//this 继承自 foo()
console.log( this.a );
};
}
var obj1 = {
a:2
};
var obj2 = {
a:3
};
var bar = foo.call( obj1 );
bar.call( obj2 ); // 2, 不是 3 

箭头函数的绑定无法被修改                                                                           

 

当然使用下面的和上面的效果一样

function foo() {
var self = this; // lexical capture of this
setTimeout( function(){
console.log( self.a );
}, 100 );
}
var obj = {
a: 2
};
foo.call( obj ); // 2

 

posted @ 2017-03-29 20:47  夏风微凉  阅读(145)  评论(0编辑  收藏  举报