javascript中的this判断

在javascript中每执行一个函数时,会为函数创建一个执行上下文,并把他压入调用栈中,这个执行上下文包含了函数执行所需要的信息,如该函数是由谁调用的等等,而this也是这些信息中的一员。

this的值是在执行时去确认的,所以我们判断this的值分为两个部分,第一个部分是确认出函数被调用的位置,级、第二个部分是结合第一步分析出的结果,根据四个规则来确认this的值

一. 我们判断this的值首先第一步应该是判断出函数的调用栈信息,我举个例子

function frist() {    // 调用栈是 全局
    second();
}

function second() {    // 调用栈是 全局 => first
    third();
}

function third() {     // 调用栈是 全局 => first => second
    
}

first();

(调用栈信息可以用调试器打断点来查看)

二. 结合第一步的调用栈信息,结合四个规则来判断this的值

1. 隐式绑定,可能有些地方是这样描述这个规则的,“调用一个对象的方法时,该方法的this指向该对象”,但是这样不是很准确,应该是,当一个函数拥有上下文对象时,该函数的this指向离函数最近的上下文对象(其实就是刚刚的调用栈信息),代码示例

var obj1 = {
    foo: function() {
        console.log(this);     
    }
}

obj1.foo()     //obj1 foo函数被obj调用,他的上下文对象就是obj1

//下面解释什么是离函数最近的上下文对象
var obj2 = {
    foo: function() {
        console.log(this);
    }
}

var obj3 = {
    obj2: obj2
}

obj3.obj2.foo()    //obj2 这时foo函数的上下文对象是 obj3 -> obj2 但是this指向最近 所以是obj2

2. 显式绑定,即用bind,call,apply来调用函数,可以为函数来绑定一个值

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

var obj = {
    
}

foo.call(obj);        //obj  
foo.apply(obj);        //obj
var bar = foo.bind(obj);
bar()                    //obj

3.使用new时 new FunctionName() 时,先会创建一个新的对象,然后如果没有return对象的话,就return这个新对象

function Person() {
    
}

new Person(); 

/**
    相当于 function Person() {
        var obj = {};
        return obj;
    }

    Person();
**/

这时的this是执行这个新创建的对象的,就是obj

4. 默认绑定 默认情况就是说如果一个函数的调用方式匹配不了以上的三种方式,就会采用的方式

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

foo()            //global / undefined 非严格模式下指向global,严格模式下指向undefined

三. 优先级问题

在有些情况下,可能会同时匹配到多个规则,那么在这种情况下应该使用哪种呢?我先说明一下结论,new > 显示绑定 > 隐式绑定 > 默认绑定,具体的分析过程再写一篇blog

四. 特殊例子

上面的四个例子可能很简单,完全无法匹配我们日常中遇到的一下情况,下面我来举一些特殊例子来分析

var obj = {
    foo: function() {
        console.log(this);
    }
}

var bar = obj.foo;
bar()           //global或undefined  这是因为 把obj.foo赋值给bar后,bar的值就是函数foo的一个引用
                //bar的调用是没有上下文对象 匹配默认绑定
function bar() {
    console.log(this);
}

bar.call(null)        //这时null会被忽视,函数保持原来的this值

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值