JavaScript从入门到精通(二)——JavaScript基本语言元素(ECMAScript基础)

一、语法概况

  • 大小写敏感;
  • 弱类型——变量不需要指定某个特定的类型;
  • 分行符“;”可有可无(但最好养成总是使用分行符的习惯 ^_^);
  • 用 {} 指示代码段;
  • 注释方法与C++相同:单行 //;多行 /*    */

更多内容请参见http://www.ecma-international.org;或者您可以直接在这里下载ECMA-262

二、关键字

break else new var case finally return void
catch for switch while continue function this with
default if throw delete in try do instanceof typeof

  为了以后的扩展,ECMA还规定了以下预保留字(Future Reserved Word):

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 volatile
double import public

  使用这些FRW并不会报错,当然,是在相关功能被实现之前。

三、变量

  1.定义

  变量的定义很简单,由于不需要指定类型,只需用一个var即可:

var myVar = 666;

  还可以用同一个var定义多个变量:

var nVar1 = 1, sVar2 = "test", bVar3 = false; // 变量类型并不一定相同

  需要注意的是,变量的类型并不是维持声明时指定的类型不变:

var nVar1 = 1;
alert(nVar1 === 1); // 输出true
nVar1 = "1";
alert(nVar1 === 1); // 输出false

  变量的命名只需要遵循以下两个原则:

  • 首字符为:字母,_,$其中的任何一个;
  • 剩下的字符可以是:字母,数字,_,$中的任意组合(当然还要排除关键字和预保留字)。

  最后,到底是用骆驼法(Camel Notation)还是匈牙利法(Hungarian Type Notation)就全看你的习惯了。

  2.变量值

  一个变量可以赋予两类值:

  • 值类型(Primitive Values):存储在栈(Stack)
  • 引用型(Reference Values):存储在堆(Heap)

  其中值类型总共有五种,它们分别是:Undefined,Null,Boolean,Number,String。令人惊讶的是,在大多数语言中String都是引用型,因为字符串的长度是可变的。然而ECMAScript则打破了这一常规,将String定义为值类型。

  下面对于五种值类型详细说明:

  Undefined:

  该类型只有一个值:undefined,表示定义但为初始化的变量。需要注意的是,未指定返回值的函数实际上返回了undefined。

function func() {}
alert(func() == undefined); // --> true

  Null:

  该类型只有一个值:null,表示一个不存在的对象。undefined是继承自null的值,因此有:

alert(null == undefined); // --> true

  Boolean:

  该类型有两个值:true/false。在C++中,false和0是可以相互转化的。但是在Javascript中,false不可以转化为0,但当需要的时候0可以转化为false。

  Number:

  数制的表示与C++相同,0××表示8进制,0x×××表示16进制。需要注意的是,所有的算数操作均返回10进制的值。

  ECMAScript中浮点数是以64-bit IEEE 754格式保存,虽说定义与C++基本相同:

var fNum = 0.77; // also could be 7.7e-1

  但是,在fNum参与计算之前,它一直是一个字符串!

  关于Number类型,还有几个比较重要的常量:

  Number.MAX_VALUENumber.MIN_VALUENumber.POSITIVE_INFINITYNumber.NEGATIVE_INFINITYNaN。前面两个个顾名思义,就不做过多解释。对于无穷大实际上有一个Infinity值来表示,POSITIVE_INFINITY实际上是+Infinity,而NEGATIVE_INFINITY则是-Infinity。最后一个NaN表示的是:Not a Number,即非数字。一般当转换成数字失败时,返回NaN。但是有一点却非常奇怪:

alert(NaN == NaN); // --> false

  String:

  这是唯一不定长的原始数据类型。定义格式与Java相同。在C++中用单引号表示字符,而双引号表示字符串。但是在ECMAScript中,两种方式均表示字符串。

四、操作符

  1.算数

+ - * / %

  分别表示加减乘除和取余,这与C++相同。

  2.比较

> < >= <= == != === !===

  这几个操作符,需要解释的是最后四个:

  ==和===的区别是,前者在比较前会进行类型转换(Equal),而后者不会(Indentical Equal);!=和!==也是同样的规则。比如:


var nVar = 1, sVar = "1";
alert(nVar == sVar); // --> true
alert(nVar === sVar); // –> false

  3.位操作

~ & | ^ << >> >>>

  分别表示位否(NOT)/与(AND)/或(OR)/异或(XOR)/左移(Left Shift)/右移(Right Shift)/无符号右移(Unsigned Right Shift)。

  4.前缀后缀

++ --

  5.逻辑

! && ||

  分别表示逻辑否(NOT)/与(AND)/或(OR)。

  6.赋值

= += -= += /= %= <<= >>= >>>=

  7.条件

(condition) ? expression1 : expression2;

  当condition成立时,运行expression1,否则运行expression2。这是一个被广泛试用的操作符,可以简化代码。

  8.new/delete

var oMyObject = new Object();
......
delete oMyObject;

  new/delete像C++中一样,用来创建和删除类的实例。需要注意的是,delete只能删除由程序员创建的对象。

  9.instanceof

  判断对象是否为某个类的实例:

function ClassA() {}
var o = new Object();
var a = new ClassA();
document.writeln(o instanceof ClassA); // --> false
document.writeln(a instanceof ClassA); // --> true

  10.typeof

  返回指定对象的类型。该操作符只有可能返回五个值,它们分别是:undefined,boolean,number,string,object。前四个自不用多说了,如果返回值是最后一个object,则表示操作对象要么是一个对象的引用,要么是null。因为null一直是被作为对象的站位符看待的,所以null的类型是object也不必奇怪。

  11.void

  这个操作符可以让任何表达式返回undefined。这通常用于阻止返回不该返回的值。例如,在a标签的href中调用javascript时,为了避免页面被重写,可以这样撰写代码:

<a href="javascipt:void(window.open('about:blank'));" mce_href="javascipt:void(window.open('about:blank'));">CLICK</a>

五、语句

  1.条件

if (condition) {...} else if (condition2) {...} else {...}

  上面的代码展示了if条件语句的语法。需要注意的是,尽量养成用{}的习惯,即使代码块只有一行。这是为了避免出现逻辑混乱。如果代码过长,逻辑嵌套很多,则需要一些编码技巧了。如,在for或if的最后一个}加注释,注明条件,这也是避免逻辑混乱的方法。

  2.循环

do {...} whilte (condition)while (condition) {...}for (init;condition;step) {...}for (prop in expression) {...}

  需要说明的是最后一个迭代循环。条件中的expression可以是一个对象,那么语句的意思就是遍历这个对象的所有成员;也可以是一个数组,则语句的意识是遍历这个数组的所有元素。例如:

for (var prop in window) {
  alert(prop + " : " + window[prop]);
}

  这段代码可以遍历window对象的所有成员,并逐一显示其名称和内容。
  此外在循环体中使用的 breakcondition 语句也与C++/Java基本相同:

outter:
for (var prop in window) {
  for (innerProp in prop) {
    if (innerProp == "myProp") {
      break outter;
    }
  }
}

  可以设置标签(Label)以控制循环的流程。

  3.with语句

with (obj) {
  alert(prop); // output the value of obj.prop
}

  速度很慢,尽量不要用。

  4.switch语句

switch (obj) {
  case val1:
    break;
  case val2:
    break;
  default:
}

  在ECMAScript中,case条件既可以是常量,也可以是变量。

 六、函数

  函数是ECMAScript的核心!

function myFunc(arg1, arg2, ..., argn) {
  ...
}

   你可以像上面一样定义函数,和C++/Java不同的是,ECMAScript函数不可重载。重名的函数会被覆盖。更为关键的是,向ECMAScript函数传递的参数不限数量,不论定义时有多少参数。你可以通过arguments(Array)变量访问所有的参数。例如:

function myFunc() {
  for (var arg in this.arguments) {
    alert(arg);
  }

}

  上面的代码可以输出函数myFunc的所有参数。如果定义了参数列表,而传递的参数数量与定义的数量不同,则丢失的参数自动赋值为undefined,多出来的参数被忽略。
  需要注意的是,在ECMAScript中,函数也是对象(注意上面一段代码中的this),你可以通过类方式定义函数:

var myFunc = new Function( arg1, arg2, ..., argn, funcBody );

  例如:

var myFunc = new Function( arg1, "alert(arg1);" );

  但是这种定义方式非常慢,所以通常不建议使用。

  闭包(Closures)

  闭包是指,函数体中使用了为经计算的变量,即引用了函数体以外的变量。比如在函数中使用全局变量:

var nVar = 10;
function myFunc(num1, num2) {
  function doAddition() {
    return num1 + num2 + nVar;
  }
  return doAddition();
}

  上面的代码中,内层函数doAddition就是一个闭包。它的定义并没有一个参数,所有参与计算的变量均来自外部运行环境(capture from the execute environment)。

参考:

[1] Professional JavaScript for Web Developers, 2005, by Nicholas C. Zakas


33 Responses to “JavaScript从入门到精通(二)——JavaScript基本语言元素(ECMAScript基础)

Leave a comment 写上一句?