《你不知道的JavaScript》(上卷)读书笔记:this全面解析(0)

调用位置

理解调用位置:调用位置就是函数在代码中被调用的位置(而不是声明的位置);

只有仔细分析调用位置才能回答这个问题:这个this到底引用的是什么?

寻找调用位置最重要是要分析调用栈

绑定规则

我们需要根据调用位置,来确定所采用的规则!

默认绑定:

最常用的函数调用类型,默认调用,这条规则是无法应用其它规则时的默认规则

看一段最简单的代码:

var a=1;
    function foo(){
        console.log(this.a);
    }
    foo();//1

我们看一下运行情况:

声明在全局作用域中的变量,比如代码开始的声明 var a=1;就是全局对象的一个同名属性

当调用foo时,this.a被解析成了全局变量在本例子中,函数调用了this的默认绑定,因此指向全局对象。

在代码中,foo是直接不使用带任何修饰符的函数引用进行调用的,因此只能采用默认绑定。

如果使用严格模式,则不能将全局对象用于默认绑定,因此this会绑定到undefined:

var a=1;
    function foo(){
        "use strict"
        console.log(this.a);
    }
foo();//TypeError:this is undefined

虽然this的绑定规则完全取决于调用位置,但是只有foo运行在非严格模式下时,默认绑定才能绑定到全局对象

虽然foo在严格模式下,但是他不是this的调用位置,所以,下面的例子还是输出1;

var a=1;
    function bar(){
      console.log(this.a);//1
    }
    function foo(){
        "use strict"
        bar();//1
    }

隐式绑定:

看一下下面的代码:

 function foo(){
        console.log(this.a);
    }
var obj={
    a:2,
    foo:foo
};
obj.foo();//2
foo();//undefined

 需要注意的是foo的声明方式,以之后是如何被当做引用属性添加到obj中的。

但是无论是直接在obj中定义还是先定义再添加为引用的属性,这个函数严格来说都不属于obj对象。 

函数定义在全局作用域中,个人感觉属于全局作用域。

然而,调用位置会使用obj上下文来引用函数,因此可以说函数被调用时,obj对象“拥有”或“包含”它。

当函数引用有上下文对象时隐式绑定规则会把函数调用中的this绑定到这个上下文对象

个人感觉:

1.默认绑定也是隐式绑定的一种特殊情况,第一种情况的调用,可以被认为是

window.foo();

window对象也是一个对象呀!

2.取对象的属性的操作也是一种对上下文的体现,例如obj.foo();

隐式丢失:

在一些情况下,隐式绑定的函数会丢失绑定的对象而应用默认绑定,我们看一段代码:

 function foo(){
        console.log(this.a);
    }
var obj={
    a:2,
    foo:foo
};
var bar =obj.foo;
var a=12;
bar();//12

虽然bar是obj.foo的一个引用,但是this的绑定取决于调用位置:bar函数调用时,上下文是window对象,因此使用了默认绑定。

在传入回调函数时,参数传递其实就是一种隐式赋值,因此我们传入函数时也会被隐式赋值

function foo(){
        console.log(this.a);//12
    }
function doFoo(fn){
    fn();//调用位置
}
var obj={
    a:2,
    foo:foo
};
var a=12;
doFoo(obj.foo);

如果把最后的调用改成 setTimeout(obj.foo,100);结果也是一样的,因为这个函数的效果跟下面的伪代码类似:

在doFoo里调用fn和在全局对象里调用fn是等效的!!!

function setTimeout(fn,delay){

//等待dely毫秒

fn();

}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值