zoukankan      html  css  js  c++  java
  • JavaScript那些事儿-容易迷失方向的this

        在上一篇博文《JavaScript那些事儿-高大不好上的闭包》撸主对闭包做了概述,当然闭包这个东西理解是有一个过程的,也许在一个瞬间,某个转身突然就悟到了,有种“只可意会不可言传”的感觉;撸主天生愚钝,也是在这个理解的路上,不敢说自己写得有多好,但是将自己的理解说出来了,有说得不好的请博友踊跃指正!撸主洗耳恭听。

        在我们开发实际项目上this的作用极大,它也更灵活的增加编程的乐趣,撸主在此对使用this的场景一一概述,其实在最开始接触JavaScript时,一直感觉它挺神秘,只到通过大大小小的项目总结出this其实并不是传说中的那么神秘,本文将一步一步解开它神秘的面纱(很高级的说)。

    示例1:

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

    请问这段代码执行,this是谁?答案:window。

    示例2:

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

    请问这段代码执行,this是谁?答案:obj。

    示例3:

    var oDiv = document.getElementById('div');
    oDiv.onclick = function(){
        console.log(this);
    };

    请问当点击id为div的元素,this是谁?答案:oDiv。

    示例4:

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

    请问这个自执行函数执行时,this是谁?答案:window。

        为什么能够一眼看出来this是谁,其实是有绝招的,其绝招是:函数执行的主体是谁,那么this就是谁这句话似乎好高深,那么我将它更通俗表达,它遵循函数调用:看它的调用语句前有没有点儿(”.”),如果有点儿(“.”)那么this就是点儿(“.”)前面的东西,如果没有点儿(“.”)那么this就是window,这是第一条理论;对于事件绑定,在事件触发时this就是绑定的那个DOM元素,这是第二条理论只要固执得遵循这两条理论,那么this问题走遍天下都不怕(当年读书流行这句话:学好数理化走遍天下都不怕),其实这两大理论一出,今天的博文就可以收尾了,但是很少有人遵循它,因为现实的诱惑实在太多,它无不诱惑着你让你不遵循这两条理论,就好像每天接到各种电话问你需不需要办理XX保险,XX理财,XX免费领取…都是诱惑你,其本质就是骗你钱。

    261437287137395
    (研究this好久了也没整明白,却被一个高手轻而易举解决了)

    我们来分析一下上面4个示例,因为两个理论的重要思想已提出(我TM搞得跟党的两个理论三个代表似的),就不一一画图了:
    对于示例1第4行代码是它的调用语句,我们发现它的调用语句前没有点儿(“.”),根据第一条理论,this就是window;
    对于示例2:第6行代码是它的调用语句,我们发现它的调用语句前有点儿(”.”),根据第一条理论,this就是点儿(”.”)前面的东西,故this是obj;
    对于示例3:从第2~4行代码,我们将一个匿名函数绑定给oDiv这个DOM元素事件属性onclick上了,那么当事件触发,这个匿名函数执行时,这个this就是绑定的那个DOM元素即oDiv,显然遵循第二条理论;
    对于示例4:这个是一个自执行函数,在执行时没有点儿(“.”),根据第一条理论,this就是window。(其实对于这种自执行函数this就是window,这个稍稍特殊)

    常见的坑儿

    第一个坑儿:

    function fn2(){
        console.log(this);
    }    
    function fn(){
        fn2();
        console.log(this);
    }
    fn();

    请问fn2被调用在执行时this是谁?fn被调用在执行时this是谁?那么我告诉你:fn2被调用执行时this是window,fn被调用执行时this也是window。显然都是根据理论一,得出的结论,究其原因:调用语句前有没有点儿(“.”),显然都没有点儿,即都是window。如果仍有不明白之处,请仔细斟酌红色标记的话。

    第二个坑儿:

    var oDiv = document.getElementById('div');
    oDiv.onclick = (function(){
        console.log(this);
        return function(){
            console.log(this);
        };
    })();

    请问自执行函数((function (){ … })())中this是谁?当id为div的元素被点击时(其实就是执行的那个小函数)this又是谁?我们来分析下:这种自执行函数被调用执行时,其this就是window,这个在示例4中已提到,故自执行函数被调用执行时this就是window。我再啰嗦下,其实当我们的代码从上到下执行后(并不是点击id为div的元素后),这个自执行函数已经执行了,它执行返回的值就是里面的小函数(function(){ console.log(this); }),如果您有疑问,这里有图有真相:

    image

    我们知道这个id为div的元素的事件属性(onclick)的值是这个小函数,根据第二条理论我们就知道this就是oDiv。其实细心的你们会发现,当你点击id为div的D元素时,是不是相当于oDiv.onclick(),根据第一条理论,调用语句前有没有点儿(“.”),有点儿(“.”)那么this就是点儿(“.”)前面的东西,故也是oDiv。细心的你是不是也发现了!

    总结

        本篇博文准备多写几个坑儿,但是考虑到后面坑儿的知识点儿综合性比较强,当然对于大神请无视,比如function中的call和apply、JavaScript数据类型间比较等顾虑,当然这些知识点儿撸主在后面的文章中会一一概述,敬请大家关注!如有疑问或者说得不对的地方请指正。再次感谢大家的支持!

    改变自己,从代码做起!
  • 相关阅读:
    React元素渲染
    初识JSX
    微信小程序复制文本到剪切板
    微信小程序报错request:fail url not in domain list
    小程序,通过自定义编译条件,模拟推荐人功能
    积分抵扣逻辑
    微信小程序 switch 样式
    tomcat 配置开启 APR 模式
    tomcat8 传输json 报错 Invalid character found in the request target. The valid characters are defined in RFC 3986
    c++数组初始化误区
  • 原文地址:https://www.cnblogs.com/everyding/p/JavaScript-this.html
Copyright © 2011-2022 走看看