• JavaScript


    要理解JavaScript,你得首先放下对象和类的概念,回到数据和代码的本原。前面说过,编程世界只有数据和代码两种基本元素,而这两种元素又有着纠缠不清的关系。JavaScript就是把数据和代码都简化到最原始的程度。

        JavaScript中的数据很简洁的。简单数据只有 undefined, null, boolean, number和string这五种,而复杂数据只有一种,即object。这就好比中国古典的朴素唯物思想,把世界最基本的元素归为金木水火土,其他复杂的物质都是由这五种基本元素组成。

        JavaScript中的代码只体现为一种形式,就是function。

        注意:以上单词都是小写的,不要和Number, String, Object, Function等JavaScript内置函数混淆了。要知道,JavaScript语言是区分大小写的呀!

        任何一个JavaScript的标识、常量、变量和参数都只是unfined, null, bool, number, string, object 和 function类型中的一种,也就typeof返回值表明的类型。除此之外没有其他类型了。

        先说说简单数据类型吧。

        undefined:   代表一切未知的事物,啥都没有,无法想象,代码也就更无法去处理了。
                          注意:typeof(undefined) 返回也是 undefined。
                                  可以将undefined赋值给任何变量或属性,但并不意味了清除了该变量,反而会因此多了一个属性。

        null:            有那么一个概念,但没有东西。无中似有,有中还无。虽难以想象,但已经可以用代码来处理了。
                          注意:typeof(null)返回object,但null并非object,具有null值的变量也并非object。

        boolean:      是就是,非就非,没有疑义。对就对,错就错,绝对明确。既能被代码处理,也可以控制代码的流程。

        number:      线性的事物,大小和次序分明,多而不乱。便于代码进行批量处理,也控制代码的迭代和循环等。
                          注意:typeof(NaN)和typeof(Infinity)都返回number 。
                                  NaN参与任何数值计算的结构都是NaN,而且 NaN != NaN 。
                                  Infinity / Infinity = NaN 。

        string:         面向人类的理性事物,而不是机器信号。人机信息沟通,代码据此理解人的意图等等,都靠它了。

         简单类型都不是对象,JavaScript没有将对象化的能力赋予这些简单类型。直接被赋予简单类型常量值的标识符、变量和参数都不是一个对象。

        所谓“对象化”,就是可以将数据和代码组织成复杂结构的能力。JavaScript中只有object类型和function类型提供了对象化的能力。

    没有类

        object就是对象的类型。在JavaScript中不管多么复杂的数据和代码,都可以组织成object形式的对象。

        但JavaScript却没有 “类”的概念!

        对于许多面向对象的程序员来说,这恐怕是JavaScript中最难以理解的地方。是啊,几乎任何讲面向对象的书中,第一个要讲的就是“类”的概念,这可是面向对象的支柱。这突然没有了“类”,我们就象一下子没了精神支柱,感到六神无主。看来,要放下对象和类,达到“对象本无根,类型亦无形”的境界确实是件不容易的事情啊。

        这样,我们先来看一段JavaScript程序:

        var life = {};
        for(life.age = 1; life.age <= 3; life.age++)
        {
            switch(life.age)
            {
                case 1: life.body = "卵细胞";
                        life.say = function(){alert(this.age+this.body)};
                        break;
                case 2: life.tail = "尾巴";
                        life.gill = "腮";
                        life.body = "蝌蚪";
                        life.say = function(){alert(this.age+this.body+"-"+this.tail+","+this.gill)};
                        break;
                case 3: delete life.tail;
                        delete life.gill;
                        life.legs = "四条腿";
                        life.lung = "肺";
                        life.body = "青蛙";
                        life.say = function(){alert(this.age+this.body+"-"+this.legs+","+this.lung)};
                        break;
            };
            life.say();
        };


        这段JavaScript程序一开始产生了一个生命对象life,life诞生时只是一个光溜溜的对象,没有任何属性和方法。在第一次生命过程中,它有了一个身体属性body,并有了一个say方法,看起来是一个“卵细胞”。在第二次生命过程中,它又长出了“尾巴”和“腮”,有了tail和gill属性,显然它是一个“蝌蚪”。在第三次生命过程中,它的tail和gill属性消失了,但又长出了“四条腿”和“肺”,有了legs和lung属性,从而最终变成了“青蛙”。如果,你的想像力丰富的话,或许还能让它变成英俊的“王子”,娶个美丽的“公主”什么的。不过,在看完这段程序之后,请你思考一个问题:

        我们一定需要类吗?

        还记得儿时那个“小蝌蚪找妈妈”的童话吗?也许就在昨天晚,你的孩子刚好是在这个美丽的童话中进入梦乡的吧。可爱的小蝌蚪也就是在其自身类型不断演化过程中,逐渐变成了和妈妈一样的“类”,从而找到了自己的妈妈。这个童话故事中蕴含的编程哲理就是:对象的“类”是从无到有,又不断演化,最终又消失于无形之中的...

        “类”,的确可以帮助我们理解复杂的现实世界,这纷乱的现实世界也的确需要进行分类。但如果我们的思想被“类”束缚住了,“类”也就变成了“累”。想象一下,如果一个生命对象开始的时就被规定了固定的“类”,那么它还能演化吗?蝌蚪还能变成青蛙吗?还可以给孩子们讲小蝌蚪找妈妈的故事吗?

        所以,JavaScript中没有“类”,类已化于无形,与对象融为一体。正是由于放下了“类”这个概念,JavaScript的对象才有了其他编程语言所没有的活力。

        如果,此时你的内心深处开始有所感悟,那么你已经逐渐开始理解JavaScript的禅机了。

    函数的魔力

        接下来,我们再讨论一下JavaScript函数的魔力吧。

        JavaScript的代码就只有function一种形式,function就是函数的类型。也许其他编程语言还有procedure或 method等代码概念,但在JavaScript里只有function一种形式。当我们写下一个函数的时候,只不过是建立了一个function类型的实体而已。请看下面的程序:

        function myfunc()
        {
            alert("hello");
        };
        
        alert(typeof(myfunc));


        这个代码运行之后可以看到typeof(myfunc)返回的是function。以上的函数写法我们称之为“定义式”的,如果我们将其改写成下面的“变量式”的,就更容易理解了:

        var myfunc = function ()
            {
                alert("hello");
            };
        
        alert(typeof(myfunc));


        这里明确定义了一个变量myfunc,它的初始值被赋予了一个function的实体。因此,typeof(myfunc)返回的也是function。其实,这两种函数的写法是等价的,除了一点细微差别,其内部实现完全相同。也就是说,我们写的这些JavaScript函数只是一个命了名的变量而已,其变量类型即为function,变量的值就是我们编写的函数代码体。

        聪明的你或许立即会进一步的追问:既然函数只是变量,那么变量就可以被随意赋值并用到任意地方啰?

        我们来看看下面的代码:

        var myfunc = function ()
            {
                alert("hello");
            };
        myfunc(); //第一次调用myfunc,输出hello
        
        myfunc = function ()
            {
                alert("yeah");
            };    
        myfunc(); //第二次调用myfunc,将输出yeah


        这个程序运行的结果告诉我们:答案是肯定的!在第一次调用函数之后,函数变量又被赋予了新的函数代码体,使得第二次调用该函数时,出现了不同的输出。

        好了,我们又来把上面的代码改成第一种定义式的函数形式:

        function myfunc ()
        {
            alert("hello");
        };
        myfunc(); //这里调用myfunc,输出yeah而不是hello
        
        function myfunc ()
        {
            alert("yeah");
        };    
        myfunc(); //这里调用myfunc,当然输出yeah


        按理说,两个签名完全相同的函数,在其他编程语言中应该是非法的。但在JavaScript中,这没错。不过,程序运行之后却发现一个奇怪的现象:两次调用都只是最后那个函数里输出的值!显然第一个函数没有起到任何作用。这又是为什么呢?

        原来,JavaScript执行引擎并非一行一行地分析和执行程序,而是一段一段地分析执行的。而且,在同一段程序的分析执行中,定义式的函数语句会被提取出来优先执行。函数定义执行完之后,才会按顺序执行其他语句代码。也就是说,在第一次调用myfunc之前,第一个函数语句定义的代码逻辑,已被第二个函数定义语句覆盖了。所以,两次都调用都是执行最后一个函数逻辑了。

        如果把这个JavaScript代码分成两段,例如将它们写在一个html中,并用<script/>标签将其分成这样的两块:

    <script>
        function myfunc ()
        {
            alert("hello");
        };
        myfunc(); //这里调用myfunc,输出hello
    </script>

    <script>
        function myfunc ()
        {
            alert("yeah");
        };    
        myfunc(); //这里调用myfunc,输出yeah
    </script>


        这时,输出才是各自按顺序来的,也证明了JavaScript的确是一段段地执行的。

        一段代码中的定义式函数语句会优先执行,这似乎有点象静态语言的编译概念。所以,这一特征也被有些人称为:JavaScript的“预编译”。

        大多数情况下,我们也没有必要去纠缠这些细节问题。只要你记住一点:JavaScript里的代码也是一种数据,同样可以被任意赋值和修改的,而它的值就是代码的逻辑。只是,与一般数据不同的是,函数是可以被调用执行的。

        不过,如果JavaScript函数仅仅只有这点道行的话,这与C++的函数指针,DELPHI的方法指针,C#的委托相比,又有啥稀奇嘛!然而,JavaScript函数的神奇之处还体现在另外两个方面:一是函数function类型本身也具有对象化的能力,二是函数function与对象 object超然的结合能力。

  • 相关阅读:
    课堂作业04 2017.10.27
    课程作业 03 动手动脑 2017.10.20
    课程作业 03 2017.10.20
    HDU 3974 Assign the task
    POJ 2155 Matrix
    POJ 2481 Cows
    HDU 3038 How Many Answers Are Wrong
    CS Academy Array Removal
    POJ_1330 Nearest Common Ancestors LCA
    CF Round 427 D. Palindromic characteristics
  • 原文地址:https://www.cnblogs.com/lowerma/p/10960087.html
Copyright © 2020-2023  润新知