首页 > 代码库 > JavaScript高级程序设计(3)基本概念 上

JavaScript高级程序设计(3)基本概念 上

本章内容:语法、数据类型、流控制语句、函数。

   1.语法

         ECMAScrip的语法和C和其他类C语言(如JAVA和Perl)的语法大同小异。

 

   2.区分大小写

         ECMAScript中的一切(变量、函数名和操作符)都区分大小写。

 

 3.标识符

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

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

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

          (3) 扩展的ASCII或Unicode字母字符,但是不推荐这样做。

   注:ECMAScript标识符采用驼峰大小写格式

         不能把关键字、保留字、true、false和null用作标识符

 

    4.注释

        ECMAScript包括单行注释和块级注释。

       单行注释以两个斜杠开头,如下所示:

//单行注释

 

       块级注释以一个斜杠和一个星号(/*)开头,以一个星号和一个斜杠(*/)结尾。如下所示:

/*
*这是一个多行
*(块级)注释
*/ 

第二三行以星号开头并不是必需的。之所以添加,提高注释的可读性

 

  5.严格模式

      ECMAScript引入了严格模式的概念。是为JavaScript定义了一种不同的解析与执行模型。在严格模式下,ECMAScript中的一些不确定的行为将得到处理,而且对某些不安的操作抛出错误。

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

function doSomething()
{
  "use strict";
   //函数体
}

 

这行代码看起来像是字符串,而且也没有赋值给任何变量,但其实它是一个编译指示,用于告诉支持的JavaScript引擎切换到严格模式。

严格模式下,JavaScript的执行结果会有很大不同。支持严格模式的浏览器包括IE10+、Firefox4+、Safari、Opera12+和Chrome。

 

 6.语句

  ECMAScript中的语句以一个分号结尾;如果省略分号、则由解析器确定语句的结尾。虽然语句的分号不是必需的,但建议任何时候都不要省略它。

var sum = a + b  //没有分号也是有效的语句          不推荐
var diff = a - b;  //   有效的语句        推荐

 

       加上分号可以避免很多错误(例如不完整的输入)开发人员也可以放心地压缩ECMAScript代码,也可以在某些情况下增进代码的性能。

 可以使用C语言风格把多条语句组合到一个代码块中,即代码块以左花括号({)开头,以右花括号(})结尾

if (text)
{
   test = false;
   alert(test);
}

 

虽然条件控制语句(if语句)只在执行多条语句的情况下才要求使用代码块,但最佳实践是始终在控制语句中使用代码块——即使代码块中只有一条语句。

在控制语句中使用代码块可以让偏码意图更加清晰,而且也能降低修改代码时出错的几率。

 

 7.关键字和保留字

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

  技术分享

ECMA-262还描述了另外一组不能用作标识符的保留字。尽管保留字在这门语言中还没有任何特定的用途,但他们有可能在将来被用作关键字。

技术分享

关键字和保留字任然不能作为标识符使用,但是现在可以用作对象的属性名。

   

8.变量

  ECMAScript的变量是松散类型的,所谓松散类型就是可以用来保存任何类型的数据,换句话说,每个变量仅仅是一个用于保存值的占位符而已。

 定义变量时要使用var操作符(注意var是一个关键字),后跟变量名(即一个标识符)。

var message;

 

ECMAScript也支持直接初始化变量,因此在定义变量的同时就可以设置变量的值。

var message = "hi";

 

在此,变量message中保存了一个字符串值 "hi" 。像这样初始化变量并不会把它标记为字符串类型;初始化的过程就是给变量赋一个值那么简单。因此,可以在修改变量值得同时修改值的类型,

var message = "10";
message = 100;

 

变量message一开始保存了一个字符串值 "hi" ,然后该值又被一个数字值100取代。虽然不建议修改变量所保存值的类型,但是这种操作是有效的。

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

function test()
{
 var message = "hi";   //局部变量
}
test();
alert(massage);  //错误!

 

变量message是在函数中使用var定义的。当函数被调用时,就会创建该变量并为其赋值。而在此之后,这个变量又会立即被销毁。因此例子中的下一行代码就会导致错误。

可以省略var操作符,从而创建一个全局变量:

function test()
{
  message = "hi";   //全局变量
}
test();
alert(massage);  //  "hi"

 

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

 虽然省略var操作符可以定义全局变量,但这也不是推荐的做法。因为在局部作用域中定义的全局变量很难维护,如果有意地忽略了var操作符,也会由于相应变量不会马上就有定义而导致不必要的混乱。

 可以使用一条语句定义多个变量,只要像下面这样把每个变量(初始化或不初始化均可)用逗号分隔开即可:

var message = "hi",
    found = false,
    age = 29;

 

这个例子定义并初始化了3个变量。同样由于ECMAScript是松散类型的,因而使用不同类型初始化变量的操作可以放在一条语句中完成。

 

   9.数据类型 

   ECMAScript中有5中简单数据类型(也称之为基本数据类型):Undefined、Null、Boolean、Number和String。还有一种复杂数据类型——Object,Object本质上是由一组无序的名值对组成的。

   typeof操作符:

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

      "undefined"——未定义;

      "boolean"——布尔值;

      "string"——字符串;

      "number"——数值;

      "object"——对象或null;

      "function"——函数;

    下面是几个使用typeof操作符的例子:

var message  = "some string";
alert(typeof message);        // "string"
alert(typeof(message));      // "string"
alert(typeof 95);                 //"number"
alert(typeof null) //object 特殊值null被认为是一个空的对象引用。

 

这几个例子说明,typeof操作符的操作数可以是尽量(message),也可以是数值字面量。注意,typeof是一个操作符而不是函数,因此例子中的圆括号尽管可以使用,但不是必需的。

 

Undefined类型:

   Undefined类型只有一个值,即特殊的undefined。

   未初始化和未声明的变量执行typeof操作符都返回undefined值。

 

Null类型:

   Null类型也只有一个值,就是Null。

   null表示一个空对象指针,而这也是使用typeof操作符检测null值时会返回 "object" 的原因。

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

 

Boolean类型:

  Boolean有两个字面值,是true和false。区分大小写,否则是标识符。

  要将一个值转换为其对应的Boolean值,可以调用转型函数Boolean()。可以对任何数据类型的值调用Boolean()函数,总会返回一个Boolean值。至于返回值是true还是false,取决于转换值的数据类型和实际值。

 各种数据类型及其对应的转换规则:

技术分享

技术分享

 

 Number类型:

  表示整数和浮点数值(双精度数值)

  数值字面量格式:

   十进制:可以直接在代码里输入;

   八进制(以8位基数):第一位必须是零(0),然后是八进制数字序列(0~7)。如果字面值超出范围,那么前导零将被忽略,后面的数值将被当做十进制数值解析。

   十六进制(以16位基数):前两位是0x,后跟任何十六进制数字(0~9及A~F)。字母A~F大小写都可。

var intNum = 55;                           //整数

var octalNum1 = 070;                    //八进制的56
var octalNum2 = 079;                    //无效的八进制数值 ——解析为79
var octalNum3 = 08;                      //无效的八进制数值 ——解析为8 

var hexNum1 = 0xA;                      //十六进制的10
var hexNum2 = 0x1f;                     //十六进制的31

 

 在进行算数计算时,所有以八进制和十六进制表示的数值最终都将被转换成十进制数值。

 

 浮点数值:

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

   不要测试某个特定的浮点数值。因为浮点数值计算会产生舍入误差的问题。

 

 数值范围:

  如果超出JavaScript数值范围的值,那么这个数值将被自动转换成特殊的Infinity值。该值就无法继续参与下一次的计算,Infinity不能够参与计算的数值

  确定一个数值是不是位于最小和最大的数值之间,可以使用 isFinite() 函数。这个函数位于之间时会返回true。

var result = Numver.MAX_VALUE + Numver.MAX_VALUE;
alert(isFinite(result));      //false

 

 尽管在计算中很少出现某些值超出表示范围的情况,但在执行极小或极大数值的计算时。检测监控这些值是可能的,是必需的。

 

NaN:

 即非数值(Not a Number)是一个特殊的数值。用来表示一个本来要返回数值的操作数未返回数值的情况。

 两个特点:①任何涉及NaN的操作(NaN/10)都会返回NaN,在多步计算中有可能导致问题。

               ②NaN与任何值都不相等,包括NaN本身,会返回false。

 针对这两个特点,ECMAScript定义了isNaN()函数。这个函数接受一个参数,该参数可以是任何类型。确定这个参数是否 "不是数值"。

 isNaN() 在接收到一个值之后,会接受将这个值转换为数值。某些不是数值的值会直接转换为数值,而不能被转换为数值都会导致这个函数返回true。

alert(isNaN(NaN));                                  //true
alert(isNaN(10));                                   //false(10是一个数值)
alert(isNaN("10"));                                 //false(可以被转换成数值10)
alert(isNaN("blue"));                               //true(不能转换成数值)
alert(isNaN(true));                                 //false(可以被转换成数值1)

 

 

数值转换:

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

 

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

   ①如果是Boolean值,true和false将分别被转换为 1 和 0 。

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

   ③如果是null值,返回0。

   ④如果是underfined,返回NaN。

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

      1.如果字符串中只包含数字(包括前面带正号或负号的情况),则将其转换为十进制数值。"123"会变成123 ;

      2.如果字符串中包含有效的浮点格式,"1.1" ,则将其转换为对应的浮点数值;

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

      4.如果字符串是空的(不包括任何字符),则将其转换为0;

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

   ⑥如果是对象,则调用对象的valueof()方法,然后依照前面的规则转换返回的值。如果转换结果是NaN,则调用对象的toString()方法,然后再次依照前面的规则转换返回的字符串值。

var num1 = Number("Hello world!");                        //NaN
var num2 = Number(" ");                                   //0
var num3 = Number("0000011");                             //11
var num4 = Number(true);                                  //1

 

 

 parseInt()函数转换规则:

   ①忽略字符串前面的空格,直至找到第一个非空格字符;

   ②如果第一个字符不是数字字符或者符号,返回NaN。

   ③如果字符串以 "0x" 开头且后跟数字字符,则将其当做一个十六进制整数;

   ④如果字符串以 "0" 开头且后跟数字字符,则会将其当做一个八进制数来解析。

var num1  = parseInt("12345blue");                 //12345
var num2  = parseInt(" ");                         //NaN
var num3  = parseInt("0xA");                       //10(十六进制数)
var num4  = parseInt(22.5);                        //22
var num5  = parseInt("070");                       //56(八进制数)
var num6  = parseInt("70");                        //70(十进制数)
var num7  = parseInt("0xf");                       //15(十六进制数)

 

 使用parseInt()解析像八进制字面量的字符串时,ECMAScript3(八进制)和5(十进制)存在分歧。

 消除这个困惑,可以为这个函数提供第二个参数:转换时使用的基数(即多少进制)。指定基数会影响到转换的输出结果:

var num1  = parseInt("10", 2);                   //2(按二进制解析)
var num2  = parseInt("10", 8);                   //8 (按八进制解析)
var num3   = parseInt("10", 10);                  //10(按十进制解析)
var num4   = parseInt("10", 16);                  //16(按十六进制解析)

 

为了避免错误的解析,建议无论在什么情况下都明确指定基数。

 

 parseFloat函数转换规则:

  ①第一个小数点有效,第二个小数点无效。后面字符串将被忽略;

  ②始终都会忽略前导的零;

  ③十六进制的字符串转换为0;

  ④只解析十进制值,因此它没有用第二个参数指定数的用法;

  ⑤如果字符串包含的是一个可解析为整数的数(没有小数点,或者小数点后都是零),parseFloar()会返回整数。

 

var num1 = parseFloat("1234blue");          //1234(整数)
var num2 = parseFloat("0xA");               //0
var num3 = parseFloat("22.5");              //22.5
var num4 = parseFloat("22.34.5");           //22.34
var num5 = parseFloat("0908.5");            //908.5
var num6 = parseFloat("3.125e7");           //31250000

 

 string类型:

   用于表示由零或多个16位Unicode字符组成的字符序列,即字符串。字符串可以由双引号(")或单引号(‘)表示。

   用双引号表示的字符串和单引号的字符串完全相同,不过双引号开头必须以双引号结尾,单引号也如此。

字符字面量:

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

技术分享

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

 字符串特点:

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

转换为字符串:

  toString()方法:返回相应值的字符串表现。

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

 toString()可以输出以二进制、八进制、十六进制乃至其他任意有效进制格式表示的字符串值。

 String()转型函数:这个函数能够让将任何类型的值转换为字符串;

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

  如果值是null,则返回 "null";

  如果值是nudefined,则返回 "undefined"。

 

 object类型:

 对象其实就是一组数据和功能的集合。对象可以通过执行new操作符后跟要创建的对象类型的名称来创建。

 Object类型所具有的任何属性和方法也同样存在于更具体的对象中。

 后面章节详细讲解。

JavaScript高级程序设计(3)基本概念 上