JavaScript高级程序设计:第三章

基本概念

一、语法:

1.区分大小写:

2.标识符:指变量、函数、属性的名字,或者函数的参数。标识符可以是按照下列格式规则组合起来的一个或多个字符:

(1)第一个字符必须是一个字母、下划线(_)、或者一个美元符号($);

(2)其他字符可以是字母、下划线、美元符号或数字。

概括地说,标识符就是首字母不能是数字的,以字母、数字、下划线和美元符号组合的一个或多个字符。

3.注释:

(1)单行注释以双斜杠开头: //单行注释。

(2)块级注释以/*..*/包围: /* 这是一个

* 块级注释

*/

4.严格模式:严格模式是为JavaScript定义了一种不同的解析与执行模型。要在脚本中启用严格模式,可以在顶部添加如下代码:

“use  strict”

可以在函数上方包含这条编译指示,也可以指定函数在严格模式下执行:

function doSomething(){

         “use strict”

         //函数体

}

5.语句:ECMAScript中的语句以一个分号结尾,如果省略分号,则由解析器确定语句的结尾。如下例所示:

var  sum = a+b  //即使没有分号也是有效的语句——不推荐

var  diff= a-b ;//有效的语句——推荐

二、关键字和保留字:

ECMA-262描述了一组具有特定用途的关键字,这些关键字可用于表示控制语句的开始或结束,或者用于执行特定操作等。按照规则,关键字也是语言保留的,不能用作标识符。以下是ECMAScript的全部关键字:

break                do                      instanceof                typeof

case                  else                   new                           var

catch                finally               return                        void

continue          for                     switch                       while

debugger*       function           this                             with

default             if                        throw

delete               in                       try

ECMA-262还描述了另外一组不能用作标识符的保留字,尽管保留字在这门语言中还没有特定的用途,但是它们有可能在将来被用作关键字。以下是ECMA-262第三版定义的全部保留字:

abstract                    enum                         int                      short

Boolean                    export                       interface          static

byte                           extends                     long                  super

char                           final                  native                        synchronized

class                                   float                          package                    throws

const                         goto                          private                      transient

debugger                           implements     protected                          transient

double                       import              public                       

第五版吧在非严格模式下运行时的保留字缩减为下列这些:

class                                   enum                         extends                     super

const                         export                       import                      

在严格模式下,第五版还对以下保留字施加了限制:

implements              package                    public

interface                   private                      static

let                              protected                          yield

let和yield是第五版新增的保留字;其他保留字都是第三版定义的。一般来说,最好不要使用关键字和保留字作为标识符和属性名,以便与将来的ECMAScript版本兼容。

三、变量

1.ECMAScript的变量是松散类型的,所谓松散类型就是可以用来保留任何类型的数据。换句话说,每个变量仅仅是一个用于保存值的占位符而已。定义变量时要使用var操作符。如下所示:

var  message;

使用var操作符定义的变量将成为定义该变量的作用域中的局部变量。也就是说,如果在函数中使用var定义一个变量,那么这个变量在函数退出之后就会被销毁。例如

function  test(){

         var  message = “hi” ;    //局部变量

}

test() ;

alert(message);//错误!

这里,变量message是在函数中使用var定义的。当函数被调用时,就会创建该变量并为其赋值。而在此之后,这个变量又会立即被销毁,因此例子中的下一行代码就会导致错误。不过,可以像下面这样省略var操作符,从而创建一个全局变量:

function  test(){

         message=“hi”;   //全局变量

}

test();

alert(message);  //“hi”

这个例子省略了var操作符,因而message就成了全局变量。这样,只要调用过一次test()函数,这个变量就有了定义,就可以在函数外部的任何地方被访问到。

四、数据类型

1.typeof操作符:

鉴于ECMAScript是松散类型的,因此需要有一种手段来检测给定变量的数据类型——typeof就是负责提供这方面信息的操作符。对一个值使用typeof操作符可能返回下列某个字符串:

undefined——如果这个值未定义;

Boolean——如果这个值是布尔值;

string——如果这个值是字符串;

number——如果这个值是数值;

object——如果这个值是对象或null;

function——如果这个值是函数。

(1)undefined类型:

undefined类型只有一个值,即特殊的undefined。在使用var声明变量但未对其加以初始化时,这个变量的值就是undefined,例如:

var  message;

alert(message == undefined) ;//true

这个例子只声明了变量,但未对其进行初始化。比较这个变量与undefined字面量,结果表明它们是相等的。这个例子与下面的例子是等价的:

var  message = undefined ;

alert(message == undefined) ;//true

这个例子使用了undefined值显示初始化了变量message。但是我们没有必要这么做,因为未经初始化的默认值就会取得undefined值。

(2)null类型:

null类型是第二个只有一个值的数据类型,这个特殊的值是null。从逻辑角度来看,null值表示一个空对象指针,而这也正是使用typeof操作符检测null值时会返回“object”的原因,如下面的例子所示:

var  car = null ;

alert(typeof  car);//“object”

如果要定义的变量准备在将来用于保存对象,那么最好将该变量初始化为null而不是其他值。这样一来,只要直接检查null值就可以知道相应的变量是否已经保存了一个对象的引用,如下面的例子:

if (car !=null){

       // 对car对象执行某些操作

}

实际上,undefined值是派生自null值的,因此ECMA-262规定对它们的相等性测试要返回true:

alert(null == undefined) ;     //true

这里,位于null和undefined之间的操作符总是返回true,不过要注意的是,这个操作符出于比较的目的会转换其操作数。

要注意的是:无论在什么情况下没必要吧一个变量的值显示地设置为undefined,可是同样的规则对null却不适用。只要意在保存对象的变量还没有真正保存对象,就应该明确地让变量保存null值。

(3)boolean类型:

该类型只有两个值:true和false。boolean类型的字面值true和false是区分大小写的。也就是说,True和False都不是boolean值,知识标识符。

(4)number类型:

number类型使用IEEE754格式来表示整数和浮点数值。

①浮点数值:该数值中必须包含一个小数点,并且小数点后面必须至少有一位数字。

 

②数值范围:ECMAScript能够表示的最小数值是5e-324,能够保存的最大数值是1.7976931348623157e+308。如果某次计算的结果超出JavaScript数值范围的值,那么这个数值将被自动换成特殊的Infinity值。具体来说,如果这个数值是负值,就会被转换成-Infinity,如果这个数值是正数,则会被转换成Infinity。

③NaN:

NaN,即非数值(Not  a  Number)是一个特殊的数值,这个数值用于表示一个本来要返回数值的操作数未返回数值的情况。NaN有两个非同寻常的特定。首先,任何涉及NaN的操作都会返回NaN;其次,NaN与任何值都不想等,包括NaN本身。针对NaN的这两个特点,ECMAScript定义了isNaN()函数。这个函数接受一个参数,该参数可以是任何类型,而函数会帮我们确定这个参数是否“不是数值”。isNaN()在接收到一个值之后,会尝试将这个值转换为数值。某些不是数值的值会直接转换为数值,例如字符串“10”或boolean值。而任何不能被转换为数值的值都会导致这个函数返回true。请看下面的例子:

alert(isNaN(NaN));        //true

alert(isNaN(10));          //false (10是一个数值)

alert(isNaN(“10”));        //false (可以被转换成数值10)

alert(isNaN(“blue”));       //true (不能转换成数值)

alert(isNaN(true));          //false(可以被转换成数值)

 

④数值转换:

有3个函数可以吧非数值转换成数值:Number()、parseInt()和parseFloat()。第一个函数可以用于任何数据类型,而另外两个函数则专门用于把字符串转换成数值。

Number()函数的转换规则如下:

·如果是boolean值,true和false将分别被转换成1和0;

·如果是数字值,只是简单的传入和返回;

·如果是null值,返回0;

·如果是undefined,返回NaN。

·如果是字符串,遵循以下规则:

                  如果字符串只包含数字,则将其转换为十进制数值,即“1”变成1,“123”变成123,而“011”会变成11(前导的零被忽略了);

                  如果字符串中包含有效的浮点格式,如“1.1”,则将其转换为对应的浮点数值(同样,也会忽略前导零);

                  如果字符串中包含有效的十六进制格式,例如“0xf”,则将其转换为相同大小的十进制整数值;

                  如果字符串是空的,则将其转换为0;

                  如果字符串中包含除上述格式之外的字符,则将其转换为NaN。

·如果是对象,则调用对象的valueOf()方法,然后依照前面的规则转换返回的值。如果转换的结果是NaN,则调用对象的toString()方法,然后再次依照前面的规则转换返回的字符串值。具体例子:

var  num1 = Number(“Hello  world!”);    //NaN

var  num2 = Number(“”);                //0

var  num3 = Number(“000011”);          //11

var  num4 = Number(true);               //1

由于Number()函数在转换字符串时比较复杂而且不够合理,因此在处理整数的时候更常用的是parseInt()函数。parseInt()函数在转换字符串时,更多的看其是否符合数值模式。它会忽略字符串前面的空格,直至找到第一个非空格字符。如果第一个字符不是数字字符或负号,parseInt()就会返回NaN,如果第一个字符是数字字符就会继续解析第二个字符,知道解析完所有后续字符或者遇到了一个非数字字符。parseInt()函数可以提供第二个参数,转换时使用的技术。如果知道要解析的值是十六进制格式的字符串,那么指定基数16作为第二个参数,可以保证得到正确的结果,例如:

var  num = parseInt(“0xAF”, 16);             //175

如果指定了16作为第二个参数,字符串前面可以不带“0x”,如下所示:

var  num1 = parseInt(“AF”, 16);              //175

    与parseInt()函数类似,parseFloat()也是从第一个字符开始解析每个字符。而且也是一直解析到字符串末尾,或者解析到遇见一个无效的浮点数数字为止。也就是说,字符串中的第一个小数点是有效的,第二个小数点就是无效的了,因此它后面的字符串将被忽略。parseFloat()可以识别所有浮点数值格式,也包括十进制整数格式,但是十六进制格式的字符串则始终会被转换成0。

(5)string类型:

string类型用于表示由零个或多个16为unicode字符组成的字符序列,即字符串。字符串可以用单引号或双引号表示,用双引号表示的字符串和用单引号表示的字符串完全相同。

①字符字面量:

string数据类型包含一些特殊的字符字面量,也叫转义序列,用于表示非打印字符,或具有其他用途的字符。

 

\n              换行

\t              制表

\b              空格

\r              回车

\f              进纸

\\              斜杠

\’               单引号,在用单引号表示的字符串中使用。

\”              双引号,在用双引号表示的字符串中使用。

\xnn         以十六进制代码nn表示的一个字符。

\unnnn     以十六进制代码nnnn表示的一个unicode字符。

 

这些字符字面量可以出现在字符串中的任意位置,而且也将被作为一个字符来解析,如下面的例子:

var  text = “This is the letter sigma : \ u03a3. ” ;

 

②字符串的特点:

ECMAScript中的字符串是不可变的,也就是说,字符串一旦创建,它们的值就不能改变。要改变某个变量保存的字符串,首先要销毁原来的字符串,然后再用另一个包含新值的字符串填充该变量,例如:

var  lang = “java”

lang = lang + “Script” ;

 

③转换为字符串:

要把一个值转换为一个字符串有两种方式。第一种是使用几乎每个值都有的toString()方法,这个方法唯一要做的就是返回相应值的字符串表现。例如:

var  age = 11;

var  ageAsString = age.toString();                  //字符串“11”

var  found = true;

var  foundAsString = found.toString();          //字符串“true”

数值、布尔值、对象和字符串值都有toString()方法。但是null和undefined值没有这个方法。

在不知道要不要转换的值是不是null或undefined的情况下,可以使用String(),这个函数能够将任何类型的值转换为字符串。String()函数遵循下列转换规则:

如果值有toString()方法,则调用该方法并返回相应的结果;

如果值是null,则返回“null”;

如果值是undefined,则返回“undefined”。

(6)object类型:

ECMAScript中的对象其实就是一组数据和功能的集合。对象可以通过执行new操作符后跟要创建的对象类型的名称来创建。而创建object类型的实例并为其添加属性和方法。object类型所具有的任何属性和方法也同样存在于更具体的对象中:

①  constructor:保存着用于创建当前对象的函数。对于前面的例子而言,构造函数就是object()。

②  hasOwnProperty(propertyName):用于检查给定的属性在当前对象实例中是否存在。

③  isPrototypeOf(object):用于检查传入的对象是否是另一个对象的原型。

④propertyIsEnumerable(propertyName):用于检查给定的属性是否能够使用for-in语句来枚举。与hasOwnProperty()方法一样,作为参数的属性名必须以字符串形式指定。

⑤toLocaleString():返回对象的字符串表示,该字符串与执行环节的地区对应。

⑥toString():返回对象的字符串表示。

⑦valueOf():返回对象的字符串、数值或布尔值表示。通常与toString()方法的返回值相同。

 

五、操作符

1.一元操作符:只能操作一个值的操作符叫一元操作符。

递增和递减操作符:

递增和递减操作符各有两个版本:前置型:++ x / --x   (先 加/减 再执行其他操作)

后置型:x++/x- -    (先 执行其他操作之后再 加/减)

这四个操作符对任何值都适用,也就是它们不仅适用于整数,还可以用于字符串、布尔值、浮点数值和对象。在应用于不同的值时,递减和递增操作符遵循以下规则:

①在应用与一个包含有效数字字符的字符串时,先将其转换为数字值,再执行加减1的操作,字符串变量变成数值变量。

②在应用于一个不包含有效数字字符的字符串时,将变量的值设置为NaN。字符串变量变成数值变量。

③在应用于布尔值false时,先将其转换为0再执行加减1的操作。布尔值变量变成数值变量。

④在应用于布尔值true时,先将其转换为1再执行加减1的操作。布尔值变量变成数值变量。

⑤在应用于浮点数值时,执行加减1的操作。

⑥在应用于对象时,先调用对象的valueOf()方法以取得一个可供操作的值,然后对该值应用前述规则。如果是NaN,则在调用toString()方法后再应用前述规则,对象变量变成数值变量。

2.一元加和减操作符:一元加操作符以一个加号表示,放在数值前面,对数值不会产生任何影响。一元减操作符主要用于表示负数,例如将1转换成-1.在对非数值应用一元加减操作符时,该操作符会像Number()转型函数一样对这个值执行转换。

3.位操作符:位操作符用于在最基本的层次上,即按内存中表示数值的位来操作数值。

4.布尔操作符:在一门编程语言中,布尔操作符的重要性堪比相等操作符。布尔操作符一共有3个:非(NOT)、与(AND)和或(OR)。

①逻辑非:逻辑非操作符由一个叹号(!)表示,可以应用与任何值。逻辑非操作符遵循下列规则:

         如果操作数是一个对象,返回false;

         如果操作数是一个空字符串,返回true;

         如果操作数是一个非空字符串,返回false;

         如果操作数是数值0,返回true;

         如果操作数是任意非0数值(包括Infinity),返回false;

         如果操作数是null,返回true;

         如果操作数是NaN,返回true;

         如果操作数是undefined,返回true。

②逻辑与:逻辑与操作符由两个和号(&&)表示,有两个操作数,如:var  result = true&&false;

遵循以下规则:

         如果第一个操作数是对象,则返回第二个操作数;

         如果第二个操作数是对象,则只有在第一个操作数的求值结果为true的情况下才会返回该对象;

         如果两个操作数都是对象,则返回第二个操作数;

         如果有一个操作数是null,则返回null;

         如果有一个操作数是NaN,则返回NaN;

         如果有一个操作数是undefined,则返回undefined。

③逻辑或:逻辑或操作符由两个竖线符号(||)表示,遵循以下规则:

         如果第一个操作数是对象,则返回第一个操作数;

         如果第一个操作数的求值结果为false,则返回第二个操作数;

         如果两个操作数都是null,则返回null;

         如果两个操作数都是NaN,则返回NaN;

如果两个操作数都是undefined,则返回undefined。

5.乘性操作符:

①乘法:由一个星号(*)表示,用于计算两个数值的乘积。遵循下列规则:

         如果操作数都是数值,执行常规的乘法计算,即两个正数或两个负数相乘的结果还是正数,而如果只有一个操作数有符号,那么结果就是负数。如果乘积超过了ECMAScript数值的表示范围,则返回Infinity或 –Infinity;

         如果一个操作数是NaN,则结果是NaN;

         如果是Infinity与0相乘,则结果是NaN;

         如果是Infinity与Infinity相乘,则结果是Infinity;

         如果有一个操作数不是数值,则在后台调用Number()将其转换为数值,然后再应用上面的规则。

 

②除法:

除法操作符由一个斜线符号(/)表示,执行第二个操作数除第一个操作数的计算。遵循以下规则:

         如果操作数都是数值,执行常规的除法计算,即两个正数或两个负数相除的结果还是正数,而如果只有一个操作数有符号,那么结果就是负数。

         如果有一个操作数是NaN,则结果是NaN;

         如果是Infinity被Infi除,则结果是NaN;

         如果是零被零除,则结果是NaN;

         如果是非零的有限数被零除,则结果是Infinity或 –Infinity,取决于有符号操作数的符号;

         如果是Infinity被任何非零数值除,则结果是Infinity或 –Infinity,取决于有符号操作数的符号;

         如果有一个操作数不是数值,则在后台调用Number()将其转换为数值然后再应用上面的规则。

 

③求模:求模(余数)操作符由一个百分号(%)表示,遵循以下特殊规则:

         如果操作数都是数值,执行常规的除法计算,返回除得的余数;

         如果被除数是无穷大值而除数是有限大的数值,则结果是NaN;

         如果被除数是有限大的数值而除数是零,则结果是NaN;

         如果是Infinity被Infinity除,则结果是NaN;

         如果被除数是有限大的数值而除数是无穷大的数值则结果是被除数;

         如果被除数是零,则结果是零;

         如果有一个操作数不是数值,则在后台调用Number()将其转换为数值,然后再应用上面的规则。

6.加性操作符

①加法:加法操作符(+)的用法如下:

var  result = 1+2 ;

如果两个操作符都是数值,执行常规的加法计算,然后根据下列规则返回结果:

         如果有一个操作数是NaN,则结果是NaN;

         如果是Infinity加Infinity,则结果是Infinity;

         如果是 –Infinity加 –Infinity,则结果是 –Infinity;

         如果是Infinity 加 –Infinity,则结果是NaN;

         如果是+0加+0,则结果是+0;

         如果是 -0 加 -0,则结果是 -0;

         如果是+0加 -0,则结果是+0;

不过,如果有一个操作数是字符串,那么就要应用以下规则:

         如果两个操作数都是字符串,则将第二个操作数与第一个操作数拼接起来;

         如果只有一个操作数是字符串,则将另一个操作数转换为字符串,然后再将两个字符串拼接起来。

如果有一个操作数是对象、数值或布尔值,则调用它们的toString()方法获得相应的字符串值,然后再应用前面关于字符串的规则。

②减法:减法操作符(-)是另一个极为常用的操作符,其用法如下:

var  result = 2 – 1;

遵循以下规则:

         如果有两个操作符都是数值,则执行常规的算术减法操作并返回结果;

         如果有一个操作数是NaN,则结果是NaN;

         如果是Infinity减Infinity,则结果是NaN;

         如果是 –Infinity减 –Infinity,则结果是NaN;

         如果是Infinity减 –Infinity,则结果是Infin;

         如果是-Infinity减Infinity,则结果是-Infinity;

         如果是+0减+0,则结果是+0;

         如果是+0减-0,则结果是-0;

         如果是-0减-0,则结果是+0;

         如果有一个操作数值字符串、布尔值、null或undefined,则先在后台调用Number()函数将其转换为数值,然后再根据前面的规则执行减法计算。如果转换的结果是NaN,则减法的结果是NaN;

         如果有一个操作数是对象,则调用对象的valueOf()方法以取得表示该对象的数值。

7.关系操作符:

小于(<)、大于(>)、小于等于(<=)和大于等于(>=)这几个关系操作符用于对两个值进行比较,当关系操作符的操作数使用了非数值时,也要进行数据转换或完成某些奇怪的操作,以下是相应规则:

         如果两个操作数都是数值,则执行数值比较;

         如果两个操作数都是字符串,则比较两个字符串对应的字符编码值;

         如果一个操作数是数值,则将另一个操作数转换为另一个数值,然后执行数值比较。

         如果一个操作数是对象,则调用这个对象的valueOf()方法,用得到的结果按照前面的规则执行比较。

         如果一个操作数是布尔值,则先将其转换为数值,然后再执行比较。

8.相等操作符

①相等和不相等:ECMAScript中的相等操作符由两个等于号(==)表示,如果两个操作数相等,则返回true。而不相等操作符由叹号后跟等于号(!=)表示,如果两个操作数不等,则返回true。遵循以下规则:

         如果有一个操作数是布尔值,则在比较相等性之前先将其转换为数值——false转换为0,而true转换为1;

         如果有一个操作数是字符串,另一个操作数是数值,在比较相等性之前先将字符串转换为数值;

         如果有一个操作数是对象,另一个操作数不是,则调用对象的valueOf()方法,用得到的基本类型值按照前面的规则进行比较;

         null和undefined是相等的;

         如果有一个操作数是NaN,则相等操作符返回false,而不相等操作符返回true。重要提示:即使两个操作数都是NaN,相等操作符也返回false;因为按照规则,NaN不等于NaN。

         如果两个操作数都是对象,则比较它们是不是同一个对象。如果两个操作数都指向同一个对象,则相等操作符返回true;否则,返回false。

②全等和不全等

全等操作符由3个等于号(===)表示,不全等操作符由一个叹号后跟两个等于号(!==)表示,它在两个操作数未经转换就不想等的情况下返回true。

9.条件操作符:条件操作符遵循与Java中的条件操作符相同的语法形式。例如:

var  max = (num1 > num2)? num1 : num2;

在这个例子中,max中会保存一个最大的值。这个表达式的意思是:如果num1大于num2(关系表达式返回true),则将num1的值赋给max;如果num1小于或等于num2(关系表达式返回false),则将num2的值赋给max。

10.赋值操作符:简单的赋值操作符由等于号(=)表示,其作用就是把右侧的值赋给左值的变量,如下面的例子:

var  num = 10;

每个主要算术操作符都有对应的复合赋值操作符。这些操作符如下:

乘/赋值(*=);

除/赋值(/=);

模/赋值(%=);

加/赋值(+=);

减/赋值(-=);

左移/赋值(<<=);

有符号右移/赋值(>>=);

无符号右移/赋值(>>>=);

11.逗号操作符:使用逗号操作符可以在一条语句中执行多个操作,如下面的例子:

var  num=1,num=2,num=3;

逗号操作符多用于声明多个变量,除此之外,逗号操作符还可以用于赋值。

六、语句

1.if语句:

语法如下:

if ( condition ) statement1 else statement2

其中的condition可是是任意表达式;而且对这个表达式求值的结果不一定是布尔值。

if语句代码可以是一行也可以是一个代码块。不过推崇的最佳实践是始终使用代码块,即使要执行的只有一行代码。因为这样可以消除误会。

2.do-while语句:

do-while语句是一种后测试循环语句,即在循环体中的代码执行之后,才会测试出口的条件。以下是do-while语句的语法:

do {

         statement

} while ( expression ) ;

下面是一个实例:

var  I = 0 ;

do {

         i + =2 ;

} while ( i <10 );

alert ( i ) ;

在这个例子中,只要变量i的值小于10,循环就会一直继续下去。而且变量i的值最初为0,每次循环都会递增2。

3.while语句:

while语句属于前测试循环语句,也就是说,在循环体内的代码被执行之前,就会对出口条件求值。因此循环体内的代码有可能永远不会被执行。以下是while语句的语法:

while(expression)statement

下面是一个示例:

var  i=0 ;

while ( i<10 ){

         i+=2;

}

 

4.for语句:

for语句也是一种前测试循环语句,但它具有在执行循环之前初始化变量和定义循环后要执行的代码的能力。以下是for语句的语法:

for(initialization ;expression ;post-loop-expression) statement

下面是一个示例:

var  count = 10 ;

for ( var i=0 ; i<count ; i++) {

         alert( i ) ;

}

以上代码定义了变量i的初始值为0。只有当条件表达式(i<count)返回true的情况下才会进入for循环,因此也只有可能不会执行循环体重的代码。如果执行了循环体中的代码,则一定会对循环后的表达式(i++)求值,即递增i的值。这个for循环语句与下面的while语句功能相同:

var  count = 10 ;

var  i=0 ;

while ( i<count ){

         alert( i) ;

         i++ ;

}

在for循环变量的初始化表达式中,也可以不使用var关键字。

5.for-in语句:

for-in语句是一种精准的迭代语句,可以用来枚举对象的属性。以下是for-in语句的语法:

for (property in expression)statement

下面是一个示例:

for(var propName in window){

         document.write(propName);

}

ECMAScript对象的属性没有顺序。因此,通过for-in循环输出的属性名的顺序是不可预测的。

但是,如果表示要迭代的对象的变量值为null或undefined,for-in语句会抛出错误。ECMAScript5更正了这一行为,对这种情况不再抛出错误,而只是不执行循环体。为了保证最大限度的兼容性,建议在使用for-in循环之前,先检测确认该对象的值不是null或undefined。

6.label语句:

使用label语句可以在代码中添加标签,以便将来使用。以下是label语句的语法:

label:statement

下面是一个示例:

start:for(var i=0 ; i<count ; i++){

         alert(i);

}

这个例子中定义的start标签可以在将来由break或continue语句引用。加标签的语句一般都要与for语句等循环语句配合使用。

7.break和continue语句:

break和continue语句用于在循环中精确地控制代码的执行。其中,break语句会立刻退出循环,强制继续执行循环后面的语句。而continue语句虽然也是立即退出循环,但退出循环后会从循环的顶部继续执行,请看下面的例子:

var num = 0 ;

for ( var i=1; i<10 ; i++) {

         if ( i%5==0){

                  break;

         }

         num++;

}

alert(num) ;          //4

这个例子中的for循环会将变量i从1递增至10。在循环体内,有一个if语句检查i的值是否可以被5整除。如果是,则执行break语句退出循环。另一方面,变量num从0开始,用于记录循环执行的次数。在执行break语句之后,要执行的下一行代码是alert()函数,结果显示4。也就是说,在变量i等于5时,循环总共执行了4次;而break语句的执行,导致了循环在num再次递增之前就退出了。如果在这里吧break替换为continue的话,则可以看到另一种结果:

var num = 0 ;

for ( var i=1; i<10 ; i++) {

         if ( i%5==0){

                  continue;

         }

         num++;

}

alert(num) ;          //8

例子的结果显示8,也就是循环总共执行了8次。当变量i等于5时,循环会在num再次递增之前退出,但接下来执行的是下一次循环,即i的值等于6的循环。于是循环又继续执行,知道i等于10时自然结束。而num的最终值之所以是8,因为continue语句导致它少递增了一次。

break和continue语句都可以与label语句联合使用,从而返回代码中特定的位置。这种联合使用的情况多发生在循环嵌套的情况下:

var  num = 0 ;

outermost :

for ( var  i=0; i<10 ; i++){

         for ( var  j=0 ; j<10 ; j++){

                  if ( i==5&&j==5){

                          break  outermost ;

                  }

                  num++ ;

         }

}

alert ( num ) ;     //55

在这个例子中,outermost标签标示外部的for语句。如果每个循环正常执行10次,则num++语句就会正常执行100次。换句话说,如果两个循环都自然结束,num的值应该是100。但内部循环中的break语句带了一个参数:要返回到的标签。添加这个标签的结果将导致break语句不仅会退出内部的for语句(即使用变量j的循环),而且也会退出外部的for语句(即使用变量i的循环)。为此,当变量i和j都等于5时,num的值正好是55.同样,continue语句也可以像这样与label语句联用,如下面的例子:

var  num = 0 ;

outermost :

for ( var  i=0; i<10 ; i++){

         for ( var  j=0 ; j<10 ; j++){

                  if ( i==5&&j==5){

                          continue  outermost ;

                  }

                  num++ ;

         }

}

alert ( num ) ;     //95

这种情况下,continue语句会强制继续执行循环——退出内部循环,执行外部循环。当j是5时,continue语句执行,而这也就意味着内部循环少执行了5次,因此num的结果是95.

8.with语句:

with语句的作用是将代码的作用域设置到一个特定的对象中。语法如下:

with (expression ) statement ;

定义with语句的目的主要是为了简化多次编写同一个对象的工作,如下面的例子所示:

var  qs = location . search . substring ( 1 ) ;

var  hostname = location . hostname ;

var  url = location . href ;

上面几行代码都包含了location对象。如果使用with语句,可以把上面的代码改写成:

with ( location ) {

         var  qs = search . substring ( 1 ) ;

         var  hostname = hostname ;

         var  url = href ;

}

这个例子中,使用with语句关联了location给对象。意味着在with语句的代码快内部,每个变量首先被认为是局部变量,如果在局部环境中找不到该变量的定义,就会查询location对象中是否有同名的属性。如果有,则已location对象属性的值作为变量的值。

严格模式下不允许使用with语句,否则将视为语法错误。

9.switch语句:

语法如下:

switch  ( expression ) {

case  value : statement

         break ;

case  value: statement

         break ;

case  value : statement

         break ;

default : statement

}

switch语句中的每一种情形(case)的含义是:“如果表达式等于这个值(value),则执行后面的语句(statement)”。而break关键字会导致代码执行流跳出switch语句。如果省略break关键字,就会导致执行完当前case后,继续执行下一个case。最后default关键字则用于表达式不匹配前面任何一种情形时。

七、函数

函数对任何语言来说都是一个核心的概念,通过函数可以封装任意多条语句,而且可以在任何地方、任何时候调用执行。

1.理解参数:ECMAScript函数的参数与大多数其他语言中函数的参数有所不同。ECMAScript中的参数在内部使用一个数组来完成的,因此ECMAScript函数不介意传递进来多少个参数,也不在乎传进来的参数是什么数据类型。实际上,函数体内可以通过argument对象来访问这个参数数组,从而获取传递给函数的每一个参数。

2.没有重载:ECMAScript函数不能像传统意义上那样实现重载。

转载于:https://www.cnblogs.com/koto/p/5084471.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值