资讯专栏INFORMATION COLUMN

快速理解JavaScript中this的用法与陷阱

Kylin_Mountain / 3565人阅读

摘要:赫敏第三行的是在最外层执行,也就是在全局对象下。而在对象下声明了属性,就相当于罗恩,输出的当然就是罗恩。之所以写这篇文章,是为了我下一篇文章做铺垫快速理解中和的用法敬请期待

this是 JS 这门语言的魅力之一——灵活方便又难以捉摸,即使是有经验的程序员,如果不仔细也有可能搞错,关于this的用法也成为许多公司的经典面试题。

如果你写过 Java ,你可能接触过this——一般指向当前对象,实际上,这时候this的含义已经确定了,因为Java属于编译期绑定,而JS属于运行期绑定,所以导致this的含义在运行过程中可能有多种变化。

进一步说,this和它声明环境无关,而完全取决于他的执行环境。务必牢记这句话。

//读以下代码之前,必须先阅读《哈利·波特》原著。(笑)

var name = "罗恩";
var aaa = {
    name: "哈利",
    say: function () {
        console.log(this.name);
    }
}

var bbb = {
    name: "赫敏",
    say: aaa.say
}

var ccc = aaa.say;

aaa.say();    //哈利
bbb.say();    //赫敏
ccc();        //罗恩

我们看第一行,aaa.say()调用的是aaa对象本身的say()方法,此时this指代的是aaa对象本身,所以此时输出当然就是aaa对象的name属性值。

第二行,bbb.say();输出赫敏一定和JS新手们的常识不相符,其实只要牢记“this取决于执行环境”就能想明白。bbb对象是怎么声明自身的say方法的呢?它只是把aaa对象的say方法引用过来,注意,引用的是一个方法而非一个对象,而aaa.say存储的是一个匿名函数,所以这种写法和以下代码并没有什么区别。

var bbb = {
    name: "赫敏",
    say: function () {
        console.log(this.name);
    }
}

第三行的ccc()是在最外层执行,也就是在全局对象window下。所以ccc()执行的时候this指代的就是window对象。而在window对象下声明了name属性,就相当于window.name = "罗恩",输出的当然就是罗恩

当然,也有特殊情况,那就是 setTimeout 和 setInterval 。
我把开头的aaa对象的声明改成:

var aaa = {
    name: "哈利",
    getName: function () {
        setTimeout(function(){
            console.log(this.name);
        },100)
    }
}

仅仅是在console.log(this.name)外面套了一个setTimeout,猜猜原来三行的输出会是什么?

答案:3个罗恩
也就是说,三次this,指代的都是window对象。

关于为什么会这样,我这里暂时不详细展开,因为涉及到JS异步回调的知识,如果你仅仅想快速熟悉this的用法,那么只要记住这个特殊情况即可。这个知识点曾经是阿里还是小米的面试题。

显然,三个罗恩不是我想要的,毕竟韦斯莱夫人的孩子已经够多了。那么我们只需稍微改写一下这个方法:

getName: function () {
        //在setTimeout外存储this指代的对象
        var that = this;
        setTimeout(function(){
            //this.name变成了that.name
            console.log(that.name);
        },100)
    }

输出就又正常了。

显然,that并不是一个关键字,只是一个大家解决这种情况时约定俗成的名字。如果你愿意,也可以叫thatGuy。当然,考虑到可能会有其他人维护你的代码,还是用that比较好。

之所以写这篇文章,是为了我下一篇文章做铺垫:
《快速理解JavaScript中apply()和call()的用法》
敬请期待~~

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/78847.html

相关文章

  • 快速理解JavaScriptapply()和call()用法和用途

    摘要:在学习之前,我们必须对的作用和使用方法有所了解,可以参考我前一篇文章快速理解中的用法与陷阱。和的作用十分相似,只是参数类型上的差别,以适应不同的使用场景。 在学习apply()之前,我们必须对this的作用和使用方法有所了解,可以参考我前一篇文章《快速理解JavaScript中this的用法与陷阱》。当然如果你已经熟悉this的相关知识,那么请直接往下看。 call()和apply()...

    chenjiang3 评论0 收藏0
  • 前端文档收集

    摘要:系列种优化页面加载速度的方法随笔分类中个最重要的技术点常用整理网页性能管理详解离线缓存简介系列编写高性能有趣的原生数组函数数据访问性能优化方案实现的大排序算法一怪对象常用方法函数收集数组的操作面向对象和原型继承中关键词的优雅解释浅谈系列 H5系列 10种优化页面加载速度的方法 随笔分类 - HTML5 HTML5中40个最重要的技术点 常用meta整理 网页性能管理详解 HTML5 ...

    jsbintask 评论0 收藏0
  • 前端文档收集

    摘要:系列种优化页面加载速度的方法随笔分类中个最重要的技术点常用整理网页性能管理详解离线缓存简介系列编写高性能有趣的原生数组函数数据访问性能优化方案实现的大排序算法一怪对象常用方法函数收集数组的操作面向对象和原型继承中关键词的优雅解释浅谈系列 H5系列 10种优化页面加载速度的方法 随笔分类 - HTML5 HTML5中40个最重要的技术点 常用meta整理 网页性能管理详解 HTML5 ...

    muddyway 评论0 收藏0
  • JavaScript深入浅出

    摘要:理解的函数基础要搞好深入浅出原型使用原型模型,虽然这经常被当作缺点提及,但是只要善于运用,其实基于原型的继承模型比传统的类继承还要强大。中文指南基本操作指南二继续熟悉的几对方法,包括,,。商业转载请联系作者获得授权,非商业转载请注明出处。 怎样使用 this 因为本人属于伪前端,因此文中只看懂了 8 成左右,希望能够给大家带来帮助....(据说是阿里的前端妹子写的) this 的值到底...

    blair 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<