您好,欢迎访问三七文档
当前位置:首页 > 商业/管理/HR > 项目/工程管理 > 第2章 基本概念{JavaScript内核系列}
JavaScript内核系列第2章基本概念原创作者:abruzzi阅读:1254次评论:5条更新时间:2010-04-09收藏第二章基本概念本章将聚焦于JavaScript中的基本概念,这些概念与传统语言有比较大的不同,因此单独列出一章来做专门描述,理解本章的概念对书中后续章节的概念,代码的行为等会有很大的帮助,读者不妨花比较大的时间在本章,即使你对JavaScript已经比较熟悉,也建议通读本章。本章主要讲述JavaScript中的数据类型(基本类型与引用类型),变量(包括变量的作用域),操作符(主要是一些较为常见,但是不容易从字面上理解的操作符)。由于JavaScript中的“一切皆对象”,在掌握了这些基本的概念之后,读者就可以较为轻松的理解诸如作用域,调用对象,闭包,currying等等较难理解的概念了。2.1数据类型有程序设计经验的读者肯定知道,在C或者Java这样的语言中,数据是有类型的,比如用以表示用户名的属性是字符串,而一个雇员的年龄则是一个数字,表示UI上的一个开关按钮的数据模型则为布尔值等等,对数字可能还可以细分为浮点数,整型数,整型数又可能分为长整型和短整型,总而言之,它们都表示语言中的数据的值的类型。JavaScript中的数据类型分为两种:基本数据类型和对象类型,其中对象类型包含对象,数组,以及函数(事实上,函数,数组等也都是对象,这个在后边的章节详述)。2.1.1基本数据类型在JavaScript中,包含三种基本的数据类型,字符串(String),数值(Number),布尔值(boolean),下面是一些简单的例子:Js代码1.varstr=Hello,world;//字符串2.vari=10;//整型数3.varf=2.3;//浮点数4.5.varb=true;//布尔值我们可以分别查看变量的值及变量的类型:Js代码1.print(str);2.print(i);3.print(f);4.print(b);5.6.print(typeofstr);7.print(typeofi);8.print(typeoff);9.print(typeofb);注意,在此处使用的print()函数为rhino解释器的顶层对象的方法,可以用来打印字符串,通常情况下,在客户端,程序员多使用alert()进行类似的动作,alert()是浏览器中JavaScript解释器的顶层对象(window)的一个方法。Js代码1.Hello,world2.103.2.34.true5.6.string7.number8.number9.Boolean在JavaScript中,所有的数字,不论是整型浮点,都属于“数字”基本类型。typeof是一个一元的操作符,在本章的另外一个小节会专门讲到。2.1.2对象类型这里提到的对象不是对象本身,而是指一种类型,我们在第三章会对对象进行详细的讨论,此处的对象包括,对象(属性的集合,即键值的散列表),数组(有序的列表),函数(包含可执行的代码)。对象类型是一种复合的数据类型,其基本元素由基本数据类型组成,当然不限于基本类型,比如对象类型中的值可以是其他的对象类型实例,我们通过例子来说明:Js代码1.varstr=Hello,world;2.varobj=newObject();3.obj.str=str;4.obj.num=2.3;5.6.vararray=newArray(foo,bar,zoo);7.8.varfunc=function(){9.print(Iamafunctionhere);10.}可以看到,对象具有属性,如obj.str,obj.num,这些属性的值可以是基本类型,事实上还可以更复杂,我们来看看他们的类型:Js代码1.print(typeofobj);2.print(typeofarray);3.print(typeoffunc);4.5.//将打印出6.object7.object8.function读者可能会对print(typeofarray)打印出object感到奇怪,事实上,对象和数组的界限并不那么明显(事实上它们是属于同一类型的),但是他们的行为却非常不同,本书的后续章节将两个重要的数据类型做了分别介绍。2.1.3两者之间的转换类似与Java中基本数据类型的自动装箱拆箱,JavaScript也有类似的动作,基本数据类型在做一些运算时,会临时包装一个对象,做完运算后,又自动释放该对象。我们可以通过几个例子来说明:Js代码1.varstr=JavaScriptKernal;2.print(str.length);//打印17str为一个字符串,通过typeof运算符可知其type为”string”,而:Js代码1.varstr2=newString(JavaScriptKernal);2.3.print(typeofstr2);可知,str2的type为”object”,即这两者并不相同,那么为什么可以使用str.length来的到str的长度呢?事实上,当使用str.length时,JavaScript会自动包装一个临时的String对象,内容为str的内容,然后获取该对象的length属性,最后,这个临时的对象将被释放。而将对象转换为基本类型则是通过这样的方式:通过调用对象的valueOf()方法来取得对象的值,如果和上下文的类型匹配,则使用该值。如果valueOf取不到值的话,则需要调用对象的toString()方法,而如果上下文为数值型,则又需要将此字符串转换为数值。由于JavaScript是弱类型的,所以JavaScript引擎需要根据上下文来“猜测”对象的类型,这就使得JavaScript的效率比编译型的语言要差一些。valueOf()的作用是,将一个对象的值转换成一种合乎上下文需求的基本类型,toString()则名副其实,可以打印出对象对应的字符串,当然前提是你已经“重载”了Object的toString()方法。事实上,这种转换规则会导致很多的问题,比如,所有的非空对象,在布尔值环境下,都会被转成true,比如:Js代码1.functionconvertTest(){2.if(newBoolean(false)&&newObject()&&3.newString()&&newArray()){4.print(converttoboolean)5.}6.}7.8.convertTest();//converttoBoolean初学者容易被JavaScript中的类型转换规则搞晕掉,很多情况下会觉得那种写法看着非常别扭,其实只需要掌握了规则,这些古怪的写法会大大的提高代码的性能,我们通过例子来学习这些规则:Js代码1.varx=3;2.vary=x+2;//=323.varz=x+2;//=54.5.print(y);6.print(z);通常可以在JS代码中发现这样的代码:Js代码1.if(datamodel.item){2.//dosomething...3.}else{4.datamodel.item=newItem();5.}这种写法事实上具有更深层次的含义:应该注意到,datamodel.item是一个对象(字符串,数字等),而if需要一个boolean型的表达式,所以这里进行了类型转换。在JavaScript中,如果上下文需要boolean型的值,则引擎会自动将对象转换为boolean类型。转换规则为,如果该对象非空,则转换为true,否则为false.因此我们可以采取这种简写的形式。而在传统的编程语言(强类型)中,我们则需要:Js代码1.if(datamodel.item!=null){2.//dosomething...3.}else{4.datamodel.item=newItem();5.}2.1.4类型的判断前面讲到JavaScript特性的时候,我们说过,JavaScript是一个弱类型的语言,但是有时我们需要知道变量在运行时的类型,比如,一个函数的参数预期为另一个函数:Js代码1.functionhandleMessage(message,handle){2.returnhandle(message);3.}当调用handleMessage的函数传递的handle不是一个函数则JavaScript引擎会报错,因此我们有必要在调用之前进行判断:Js代码1.functionhandleMessage(message,handle){2.if(typeofhandle==function){3.returnhandle(message);4.}else{5.thrownewError(the2ndargumentshouldbeafunction);6.}7.}但是,typeof并不总是有效的,比如下面这种情况:Js代码1.varobj={};2.vararray=[one,two,three,four];3.4.print(typeofobj);//object5.print(typeofarray);//object运行结果显示,对象obj和数组array的typeof值均为”object”,这样我们就无法准确判断了,这时候,可以通过调用instanceof来进行进一步的判断:Js代码1.print(objinstanceofArray);//false2.print(arrayinstanceofArray);//true第一行代码返回false,第二行则返回true。因此,我们可以将typeof操作符和instanceof操作符结合起来进行判断。2.2变量变量,即通过一个名字将一个值关联起来,以后通过变量就可以引用到该值,比如:Js代码1.varstr=Hello,World;2.varnum=2.345;当我们下一次要引用”Hello,Wrold”这个串进行某项操作时,我们只需要使用变量str即可,同样,我们可以用10*num来表示10*2.345。变量的作用就是将值“存储”在这个变量上。2.2.1基本类型和引用类型在上一小节,我们介绍了JavaScript中的数据类型,其中基本类型如数字,布尔值,它们在内存中都有固定的大小,我们通过变量来直接访问基本类型的数据。而对于引用类型,如对象,数组和函数,由于它们的大小在原则上是不受任何限制的,故我们通过对其引用的访问来访问它们本身,引用本身是一个地址,即指向真实存储复杂对象的位置。基本类型和引用类型的区别是比较明显的,我们来看几个例子:Js代码1.varx=1;//数字x,基本类型2.vary=x;//数字y,基本类型3.print(x);4.print(y);5.6.x=2;//修改x的值7.8.print(x);//x的值变为29.print(y);//y的值不会变化运行结果如下:1121这样的运行结果应该在你的意料之内,没有什么特别之处,我们再来看看引用类型的例子,由于数组的长度非固定,可以动态增删,因此数组为引用类型:Js代码1.vararray=[1,2,3,4,5];2.vararrayRef=array;3.4.array.push(6);5.print(arrayRef);引用指向的是地址,也就是说,引用不会指向引用本身,而是指向该引用所对应的实际对象。因此通过修改array指向的数组,则arrayRef指向的是同一个对象,因此运行效果如下:1,2,3,4,5,62.2.2变量的作用域变量被定义的区域即为其作用域,全局变量具有全局作用域;局部变量,比如声明在函数内部的变量则具有局部作用域,在函数的外部是不能直接访问的。比如:Js代码1.varvariable=out;2.3.functionfunc(){4.varvariable=in;5.print(variable);//打印”in”6.}7.8.func();9.print(variable);//打印”out”应该注意的是,在函数内var关键字是必须的,如果使用了变量而没有写va
本文标题:第2章 基本概念{JavaScript内核系列}
链接地址:https://www.777doc.com/doc-3767280 .html