深入理解 js this关键字

本文详细解析了 JavaScript 中 this 关键字的指向规则,包括函数调用环境及指向对象的所有者,并通过多个示例代码进行验证。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

   看了网上很多关于javascript this关键字的理解,总觉得不够清晰,经过自己多方测试和查阅资料,写点自己的感悟。有不对的地方,还请大神指正。
    大家都知道javascript 中 比较难理解的一个关键字 this,经常不敢确定到底指向哪里了,一般简单的譬如:

    var name = 'zengxindong';

      function showName(){
        return this.name;
    }
    alert(showName()); //zengxindong

    大家都知道是指向window全局对象的属性(变量)name,因为调用showName()实际上就相当于window.showName(),所以this指向window对象。

    但是如果复杂点情况呢,有时候就会有点蒙,关键还是没有彻底理解this关键字什么时候初始化,初始化后指向的对象是谁,只要弄清楚了这两个问题,基本上就很清楚this的指向。

    在此之前先介绍点周边的概念:
        1、函数名是一个指向函数的指针。
        2、函数执行环境(this什么时候初始化):当某个函数第一次被调用时,会创建一个执行环境(execution context),并使用this/arguments和其他命名参数的值来初始化函数的活动对象(activation object)。(这里我们不引入此时也会初始化作用域链概念)
        3、初始化指向谁:在Javascript中,this关键字永远都指向函数(方法)的所有者。(转载地址:http://www.laruence.com/2009/09/08/1076.html)

    但是有了这三个定论(全文都会贯穿这三个理论)了,还需要在复杂的情况下才能深入理解。

    有了这三个定论,可以先理解上面那个简单例子:
        全局函数showName是window对象的一个属性,也就是说showName函数(方法)所有者是window,函数名showName是一个指针,指向函数地址,当直接执行showName()的时候会初始化this,此时this就指向window对象了。


    下面就让我们看看闭包(不理解闭包的可以看看:http://www.ruanyifeng.com/blog/2009/08/learning_javascript_closures.html)情况下,this关键字指向实例:
        var name = 'The window';
        var object = {
            name:'The object',
            getNameFunc:function(){
                return function(){
                    return this.name;
                }
            }
        };
        alert(object.getNameFunc()());//The window
        这是javascript高级程序设计里面解释:在全局函数中,this等于window,而当函数被当做某个对象的方法调用时,this等于那个对象。不过,匿名函数的执行具有全局性,因此this对象通常指向window(在通过call()或apply()改变函数执行环境的情况下,this就会指向其他对象)
        验证测试:
        1、我看到这句话之后总觉得心里不太踏实,然后我就改了一下运行:
            var name = 'The window';
            var object = {
                name:'The object',
                getNameFunc:function(){
                    var tmpFunc = function(){
                        return this.name;
                    }
                    return tmpFunc;
                }
            };
            alert(object.getNameFunc()());//The window
        这里还是这个结果,最后我又去查了一下,javascript里面函数表达式也属于匿名函数。
        2、那我就又改了一下:
            var name = 'The window';
            var object = {
                name:'The object',
                getNameFunc:function(){
                    function tmpFunc(){
                        return this.name;
                    }
                    return tmpFunc;
                }
            };
            alert(object.getNameFunc()());//The window
        发现还是"The window"结果,这下该不是匿名函数了吧,所以我的理解是跟匿名函数没关系,因为最后执行的tmpFunc的方法所有者不是object,只有getNameFunc方法所有者是object。
        而上面的代码其实可以写成:如下形式:
            var tmpFuncPtr = object.getNameFunc();
            tmpFuncPtr();(上面说的函数名就是一个指向函数地址的指针)
            所以此时this就指向的是window对象,从而弹出window对象name属性"The window"。
        3、然后我又做了如下测试:
            var name = 'The window';
            var object = {
                name:'The object',
                getNameFunc:function(){
                    return object1.getNameFunc;
                }
            };
            var object1 = {
                name:'The object1',
                getNameFunc:function(){
                    return this.name;
                }
            };
            alert(object.getNameFunc()());//The window
            结果还是"The window",哈哈哈,再看下面稍微修改一下:

            var name = 'The window';
            var object = {
                name:'The object',
                getNameFunc:function(){
                    return object1.getNameFunc();
                }
            };
            var object1 = {
                name:'The object1',
                getNameFunc:function(){
                    return this.name;
                }
            };
            alert(object.getNameFunc());//The object1

            这里的结果就是"The object1"了。
        我分析一下原因啊,还是上面的三个定论作为依据:
            弹出结果为"The window"的那段程序,object1.getNameFunc只是引用了object1对象的getNameFunc属性,也就是一个函数的地址。此时没有调用函数,所以也就不会初始化this关键字。最后调用实际上还是相当于是:
                var tmpFuncPtr = object1.getNameFunc;
                tmpFuncPtr();//所以还是指向window全局对象
            而弹出结果为"The object1",此时object1.getNameFunc()相当于是调用object1对象的getNameFunc方法,此时会初始化this关键字,而getNameFunc方法的所有者就是object1,this指向object1,所以调用object1.getNameFunc()返回的是object1的name属性,也就是"The object1"
        4、然后再继续测试:
            var name = 'The window';
            var object = {
                name:'The object',
                getNameFunc:function(){
                    return object1.getNameFunc;
                }
            };
            var object1 = {
                name:'The object1',
                getNameFunc:function(){
                    return function(){
                        return this.name;
                    }
                }
            };
            alert(object.getNameFunc()()());//The window
        这个有了上面的介绍大家应该也能理解了。
        总算是彻底搞清楚this关键字了,以前总觉得不踏实,不知道到底指向哪里。希望大家看了我这篇文章能有所收获。有不对的地方,也希望大家能耐心指正


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值