再读《悟透javascript》之一、JavaScript基础

引言
      编程世界只存在两种基本元素:一个是数据、另一个是代码。无论多么复杂的程序,都是对数据和代码间千丝万缕的关系进行的操作。
 

 

一、回归简单,JavaScript的数据类型
1.       简单数据类型
1)       undefined:代表一切未知的事物,什么也没有(注意:typeof(undefined)也是undefined)
2)       null:有一个空间,但空间中没有数据
3)       boolean:布尔类型
(1)    undefined,null,’’,0转换为布尔类型,结果都为false,其它一切值转换成布尔类型都为true,例:alert(Boolean(undefined));

(2)     ===:全等,表示类型和值都要相等,例:alert("123"==123);alert("123"===123);
4)       number:数值类型
5)       string:字符串类型
 

 

2.       复杂数据类型,只有object类型
在JavaScript中不要被类所束缚,JavaScript没有类的概念,因为它已将类化为无形与对象溶为一体了,看下面的代码:
        var life = {};

        for(life.age=0; life.age<3; life.age++){

            switch(life.age){

                case 0:life.body="卵细胞";

                       life.say=function(){alert("now i'm a "+this.body);}

                       break;

                case 1:life.body="小蝌蚪";

                              life.tail="尾巴";

                       life.say=function(){alert("now i'm a "+this.body);}

                       break;

                case 2:life.body="青蛙王子";

                              delete life.tail;

                              life.legs="腿";

                       life.say=function(){alert("now i'm a "+this.body);}

                       break;

            }

           

            life.say();

}
上面可以看到,一个life对象从卵细胞变成小蝌蚪再变成青蛙王子,是多么的有趣,这就是JavaScript的魅力,life不是某个类的固定的实例化对象,它 是如此的灵活,并不局限于某个固定的类;假如我们用面向对象的思想来编写的话,会怎样呢?那么我们就需要建立三个类来反映life生命中的三个阶段,然后再来编程,假如life对象有十个生命过程呢?my god那就要十个对象了,那再多一点~~~~~~,面向对象是为了帮助我们理解问题解决问题的,当它成为了我们的阻碍时,我们就要坚决地抛弃它。
 

 

3.       function,函数,程序之神
1)       静态函数:function xxx(){…},如果在同一个程序段内,出现同名的静态函数,那么该函数将以最后位置的函数为准。例:
<script type="text/javascript">
        function test(){alert("hello");}

        test();

        function test(){alert("hi~~~");}

test();

</script>
我们会看到,它两次都弹出hi~~~,即最后位置的函数。
 

 

2)       动态函数:var xxx = function(){…},动态函数不存在静态函数同名的问题,在程序执行到时,最后赋值的函数就是要调用的函数。例:
    <script type="text/javascript">

        var test = function(){alert("hello");}

        test();

        var test = function(){alert("hi~~~");}

        test();

</script>

这里我们可以看到,程序先弹出hello,后弹出hi~~~,第一个test执行前赋值的是弹出hello的函数,而第二个test执行前赋值的是弹出hi~~~的函数。
 

 

3)       JavaScript是一段段地分析执行函数,而不是一行行地分析执行,如果将上面的静态函数的例子拆成两个程序段,就可以看出来,例:
<script type="text/javascript">
        function test(){alert("hello");}

        test();

</script>
<script type="text/javascript">
        function test(){alert("hi~~~");}

test();

</script>
可以看到,程序先输出hello后输出hi~~~,证明了JavaScript是一段段的执行的。
一段代码中的静态函数会优先执行,这一特征被称为“JavaScript的预编译”,事实上,JavaScript的预编译还包括对所有var变量的创建(初始值为undefined),用以提高对代码的执行效率。(请注意此段话,后面会有示例)
 

 

二、变量、属性、作用域
1.       任何程序都会在一个原始的环境中开始运行,这个原始的环境被称为“全局环境”,全局环境包含一些预定义的元素,这些元素对于我们的程序来说是自然存在的,我们直接拿来即可用,就像我们呼吸的空气一样。在JavaScript中,这个全局环境就是window对象。
 

 

2.       变量与属性
1)       变量:var myName=”luo”;这里声明了一个变量
2)       属性:myName=”soldierluo”;这里定义了一个属性
 

 

3.       变量的作用域只在函数体内,而属性则没这样的限制,这样的安排是JavaScript的一个极大的特点,请特别注意,例:
    <script type="text/javascript">

    var firstName = "luo";

    var lastName = "jun";

    fullName = "soldierluo";

    alert("firstName:"+firstName+" lastName:"+lastName+" fullName:"+fullName);

    function test(){

        alert("firstName:"+firstName+" lastName:"+lastName+" fullName:"+fullName);

        var firstName = "soldier";

           lastName = "kkk";

        fullName = "changed";

        alert("firstName:"+firstName+" lastName:"+lastName+" fullName:"+fullName);

    }

    test();

    alert("firstName:"+firstName+" lastName:"+lastName+" fullName:"+fullName);

</script>

上面这个例子非常有意思,程序总共弹出了四次,firstName由luo->undefined->soldier->luo;而lastName为jun->jun->kkk->kkk;fullName则是soldierluo->soldierluo->changed->changed;
看来变量lastName和属性fullName比较像呢!为什么同是变量的firstName反而更不同呢?因为作用域,请看test函数中也声明了一个firstName的变量,这样它就会屏蔽父域中的同名变量,那为什么是undefined呢?看看上面标红的关于JavaScript预编译的那段话就清楚了,此时的firstName被预编译设置成undefined,等到之后赋值为soldier后再输出就是soldier了。最后firstName怎么又变成luo了呢?因为test函数结束后,test函数中的变量就消失了,所以父域的变量又出现了,就这么回事。
至于lastName和fullName,就不需要解释了吧,他们都是正常的作用域内,规规矩矩的变化着。
看了上面的实例,应该比较清楚什么时候用var了吧,如果使用var,那么它就是一个临时变量,函数结束后它就消失了,而全局变量和属性则不会。所以,在函数中尽量使用var可以避免不必要的冲突,比如修改了父域的变量或属性等等。
 

 

4.       caller对象,返回调用该函数的函数,如果为null,则表示被全局函数调用,例:
    <script type="text/javascript">

    function test(){alert(test.caller);}

    function useTest(){test();}

    test();

    useTest();

</script>

 

 

5.       arguments对象,函数属性,传入参数的集合,例:
    <script type="text/javascript">

    function test(){alert(arguments.length);}

    function test_1(a,b,c){ alert(arguments.length); alert(arguments.length>0arguments[1]:-1);}

    test();

    test_1();

    test_1(1,6);

</script>
可以看到,arguments是实际传入的参数的集合,与函数的定义无关,可以通过arguments[index]来访问参数。
 

 

三、object&function,对象与函数
1.       如果我说函数和对象是一样的,或者说函数就是对象,你一定会骂我sb,对象是实体,函数是行为,怎么可能一样,其实你说的都不错,但是,这是在JavaScript里,事实上函数就是对象。例:
    <script type="text/javascript">

    function sing(){alert(sing.name+":"+sing.title);}

    sing.name = "李白";

    sing.title = "《关山月》";

    sing();

    sing.name = "白居易";

    sing.title = "《琵琶行》";

    sing();

</script>
可以看到sing作为一个函数,我们却可以直接为它添加属性,这不是对象的基本特征吗?通过上面的例子,我们可以很清楚地看到,在JavaScript中,函数的本质它就是对象,只不过它是特殊的可以被调用的对象。
 

 

2.       放下对象,找到自我
1)       this,就是自我,但是这个自我是谁呢?谁调用了函数,那么这个函数的this就是这个谁谁谁(对象)了。例:
    <script type="text/javascript">

    function whoIam(){alert("i'm "+this.name);}

    var luo = {name:"luojun", say:whoIam};

    luo.say();

    var soldier = {name:"soldierluo", say:whoIam};

    soldier.say();

    luo.say.call(soldier);

    soldier.say.call(luo);

    ({name:"noName", say:whoIam}).say();

</script>
从这里我们可以看到,谁调用了whoIam,whoIam中的this就是谁,如果是由window对象调用,那么this就是window了。所以这个this是个很油头的东西,有奶便是娘。
 

 

2)       在一般的对象语言中,方法体代码中的this可以省略,因为成员默认都首先是自己的。但JavaScript却不同,由于有奶便是娘的特点,它没有自己,它必须找到一个有奶的娘,它才知道自己是谁,所以如果要访问自己下的属性或方法时,this不能省略。例:
    <script type="text/javascript">

    name="luo";

    function whoIam(){alert("i'm "+this.name+" name:"+name);}

    var soldier = {say:whoIam};

    soldier.say();

</script>
我们看,soldier对象调用了whoIam函数,此时whoIam中的this就是soldier对象了,而soldier对象没有定义name属性,所以是应该访问不到的,但是如果不用this的话,whoIam函数就是跑到它的祖先域中去查找name属性,这自然不是我们要的结果,因为我们的目的是访问soldier对象的name属性,所以不使用this来访问自己的属性或方法是会出现错误的。
 

 

四、对象素描,json是一种非常简便的创建JavaScript对象的方法
1.       对象属性定义在{}两个大括号之间
2.       属性是以键值对的方式呈现
3.       键值之间用:冒号分隔
4.       键值对之间用,逗号分隔
5.       如果是数组的话,使用[]中括号,值在中括号间
例:    <script type="text/javascript">

    var company = {

        name:"microsoft",

        say:function(){alert("i'm "+this.name+", most important product is "+ this.products[0]);},

        products:["windows","office","xbox"]

    };

    company.say();

</script>
怎样?很是简洁吧,json是JavaScript对象最好的系列化形式,它比xml更简洁。我们还可以使用eval函数,直接将json转换成一个JavaScript对象,这使得它成了ajax的宠儿。


 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章