zoukankan      html  css  js  c++  java
  • JavaScript的因为所以

      各位看官,楼主开始说过写几篇博客,这是这个系列的最后一集。吾以为:了解JavaScript的身世之谜,掌握其近乎心想事成的变量系统,了解其解析运行的偷梁换柱之法,熟悉布大师迂回曲折的OOP实现。那你离height level也不远了。当然,要想height level还要再掌握两个常常被各位园友挂在嘴边的东西:this与闭包。this是什么鬼?闭包又是什么鬼?照本宣科的概念,这里不说,我们只聊“因为所以”。废话少说,开聊!

    this是什么鬼?

      this这玩儿称呼为鬼一点不为过,好多小白一看满屏都是this的脚本瞬间眩晕。看样子有点像Java、C#之类的this,但凭直觉好像又超越了Java、C#的this,看得是隐隐约约、似懂非懂。各种度娘、G哥大部分得到的都是照本宣科的解析。用心的会记下并研究的,无心的大大咧咧过目而已。于是乎,好多老鸟都没彻底搞清楚this是什么鬼。要想了解this是什么鬼,那得先了解这鬼是怎么来的。

      话说JavaScript的设计初衷是过程式的,后面布大师为了紧跟时代潮流,迂回曲折地实现OOP,为此引入了this来表示实例对象。OOP是实现,但是JavaScript的世界从此多了一个this。this在应用于JavaScript的OOP时候,表示的是实例本身。但是如果我写的JavaScript并不需要new对象,而是随意到处写了this,那这个时候this代表什么?真所谓填一坑挖一坑啊!有坑得填啊,于是,布大师又想折子给这个this赋予意义了:当this应用于OOP的时候,它表示实例本身;而当this应用于非OOP的时候则表示this所在元素的归属对象。这话说来说去还是有点抽象,看代码最实在:

    1)当this在function中,但是funciton只是过程式函数

        <script>
            /**解析:
             *test在这里只是个过程式的函数,没有玩OOP
             *调用test函数打印this,那这里的this指的就是test函数的归属
             *而test函数是归属到当前Window对象上的
             * ****/
           function test(){
               console.log(this); //结果是 Window对象
           }
           test();
        </script>
    

    2)当this在某个非实例化的对象中

       <script>
            /**解析:
             *这里的this被定义一个名为f的函数中
             *f函数归属的是obj对象
             *结果:this代表obj对象
             * ****/
            var obj={
                a:123,
                f:function(){
                    console.log(this);//结果 是obj对象
                    console.log(this.a);//结果是123
                }
            };
            console.log(obj.f());//结果
        </script>
    

    3)当this应用于OOP的玩法中

        <script>
            /**解析:
             *clazz是一个类的构造函数,用于创建clazz的实例对象
             *this在这里就表示每一个new出来的对象
             * ****/
            function clazz(a,b){
                this.a=a;
                this.b=b;
                this.print=function(){
                    console.log(this.a+this.b);
                };
            }
            var c1=new clazz(1,1);
            c1.print(); //打印:2
            var c2=new clazz(2,2);
            c1.print(); //打印:4
        </script>
    

    4)当this被偷梁换柱

        <script>
            /**解析:
             *利用call或者apply让f函数运行期间的this指向另一个对象
             * ****/
            var obj={
                a:123,
                f:function(){
                    console.log(this);//结果 是obj对象
                    console.log(this.a);//结果是 undefined
                }
            };
            //利用call或者apply让f函数运行期间,将this换成当前window
            obj.f.call(this);
        </script>
    

    闭包是什么鬼?

      咱们还是废话少说,按套路,先了解这个所谓的闭包是怎么来的。全世界(写代码的人)都知道,像c、java、c++这些言语都有一套一套严格的语法,特别像数据类型、函数的定义都有自己规则,不是你想怎么写就写的。但是JavaScript这玩儿,被布大师设计得你想怎么写就怎么写,竟然可以函数里面再定义函数,可见自由度之大。你再看看java、c++能这样干嘛?自由是自由了,但是这玩法引出了一个问题:但凡大学里认真念过点书的鞋同都知道,函数是基于栈运行的,如果函数嵌套函数,子函数又引用了父函数里定义的成员,当父函数已经over的时候,按常规套路,父函数出栈了,它定义的成员也应该被Over了,如果此时子函数还活着,那它引用的父函数变量又不见了,那子函数就没法用了。于是乎,布大师又不得不给这个bug做补丁,闭包这玩儿就出生了。那咱们通俗给闭包来个定义吧:

      闭包:活着的人从死去的人那里偷来了东西,让那些东西不随死去的人而消失。活着的人拥有了这些东西,这些东西的寿命也因此边长了。这是JavaScript为了应对天马行空的自由度产生的bug而打的补丁!

      这比如虽然有点不雅,但也只是为了看官便于理解,请勿介意。好,咱们还是看看代码分析:

        <script>
            function oldMan(){
                var money=999999;// 老人的财富
                //老人有一个年轻的儿子
                return function young(){
                    console.log("儿子要花老子的钱"+money+"美刀");
                }
            }
            var y=oldMan();//老人将儿子放出来之后就挂了,oldMan函数运行完成,出栈了!!
            y();//儿子开始活动了,儿子竟然有老人的钱
        </script>
    

      看官,不知道你看了这寥寥几十字的通俗解法,是否还对那个所谓的闭包还怀抱敬畏呢!

      

      如果你认真看这寥寥几篇的通俗博文,我相信你对JavaScript的认识肯定是另一个阶梯。当然要想在前端立足,仅仅掌握JavaScript还不足以混饭,你还得懂HTML、CSS。楼主打算接下来就这两个知识再聊上几篇。如有兴趣,请留意!其他JavaScript的问题,也欢迎一起学习探讨!

  • 相关阅读:
    C#如何防止程序多次运行的技巧
    C#导出Excel按照指定格式设置单元格属性值
    js前台遍历后台返回的Datatable数据
    Datatable数据分组
    DataTable 详解(转)
    遍历Datatable
    DataTable转Json
    键值集合List转换成datatable
    DataTable转换成实体
    泛型集合与DataSet相互转换
  • 原文地址:https://www.cnblogs.com/kevinJhuang/p/6151799.html
Copyright © 2011-2022 走看看