摘自js高程
3.1 语法
ECMA的语法大量借鉴了C以及C语言(如Java和Perl)的语法。因此,熟悉这些开发人员在接受ECMAScript更加宽松的语法时候,一定会有一种轻松自在的感受。
3.1.1 区分大小写
要理解第一个概念是ECMAScript中的一切(变量、函数名和操作符)都区分大小写。这也就意味着,变量名test和变量名Test分别表示两个不同的变量,而函数名不能使用typeof,因为他是一个关键字,但是typeof则完全是一个有效的函数名。
3.1.2 标识符
所谓标识符,就是指变量、函数、属性的名字,或者函数的参数。标识符可以按照下列规则组合起来一个或者多个字符:
- 第一个字符必须是一个字母、下滑线(_)或者一个美元符号($)。
其他字符可以是字母,下滑线美元符号或者数字。
表示附中字母也可以包括扩展的ASCII或者Unicode字母字符,但是我们不推荐这样做。
按照惯例,ECMAScript表示符采用驼峰大小写格式,也就是第一个字母小写,剩下的每个单词的首字母大写。
不能把关键字、保留字、true、false和null用作标识符。
3.1.3 注释
ECMAScript采用了C风格的注释,包括当行注释和块注释。单行注释已两个斜杠开头,如下所示:
// 单行注释
块级注释以一个斜杠和一个星号开头,以一个星号和一个斜杠结尾,如下所示:
/*
*
*/
虽然上面注释中的第二行和第三行都是以一个星号开头,但这不是必须的。之所以添加那两个星号,纯粹是为了提高注释的可读性。
3.1.4 严格模式
ECMAScript 5引入严格模式(strict mode)概念。严格模式是为JavaScript定义一种不同的解析与执行模式。在严格模式下,ECMAScript 3中的一些不确定行为将得到处理,而且对于某些不安全的操作也会抛出错误。要在整个脚本中使用严格模式,可以在顶部添加如下代码:
"use strict";
在行代码看起来像是字符串,而且也没有赋值给任何变量,但其实就是一个编译指示(pragma),用于高速支持的JavaScript引擎切换到严格模式。这是为了不破坏ECMAScript3语法而特意选定的语法。
function doSometing(){
"use strict";
//函数体
}
严格模式下,JavaScript的执行结果会用很大的不同。
3.1.5 语句
ECMAScript中的语句以一个分号结尾;如果省略了分号,则由解析器确定语句的结尾,如下例子所示:
var sum = a + b //即使没有分号也是有效的语句--不推荐
var diff = a - b; //有效语句--推荐
虽然语句结尾的分号不是必须的,但是我们建议任何时候都不要省略它。因为加上分号可以避免很多错误,开发人员也可以放心的通过删除多余空格来压缩ECMAScript代码(代码结尾处没有分号会导致压缩错误).。另外,加上分号也会在某种情况下增进代码性能,因为这样解析器就不必花时间推测应该在哪里插入分号了。
可以使用C风格的语法把多条语句组合到一个代码块中,即代码块中以花括号({)开头,以右花括号(})结尾:
if(test){
test = false;
alert(test);
}
虽然条件控制语句(如if语句)只在执行多条语句的情况下才要求使用代码块,但是最佳实践是始终在控制语句中使用代码块–解释代码块中只有一条语句,例如
if(test)
alert(test); //有效但是容易出错,不要使用
if(test){
alert(test); //推荐使用
}
在控制语句中使用代码块可以让编码意图更加清晰,而且也能降低修改代码试出错的概率。
关键字和保留字
ECMAScript-262描述了一组具有用途的关键字,这些关键字可用于表示控制语句的开始和结束,或者用于执行特定操作等。按照规则,关键字也是语言保留的,不能用作标识符。以下就是ECMAScript的全部关键字(带*号上标是第5版新增加的关键字):
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 | volatile |
double | import | public |
第5版把在非严格模式下运行时保留字缩减为下列这些:
class | enum | extends | super |
---|---|---|---|
const | export | import |
在严格模式下,第五版对以下保留字缩减为下列这些:
implements | package | public | interface |
---|---|---|---|
private | static | let | protected |
yield |
注意,let和yeild是第5版新增加的保留字;其他保留字都是第3版定义的。为了最大程度的保证兼容性。
在实现ECMAScript3的JavaScript引擎中使用关键字作为标识符,会导致”Identifier Expected”错误。而使用保留字作为表示符可能会也可能不会导致相同的错误,具体取决于特定的引擎。
第5版对使用关键字和保留字的规则进行了少量的修改。关键字和保留字虽然不能作为标识符使用,但是现在可以用作对象的属性名。一般来说,最好都不要使用关键字和保留字作为标识符和属性名,以便将来和ECMAScript版本进行兼容。
除了上面列出的保留字和关键字。ECMA-262对第5版对eval和arguments还施加了限制。在严格模式下,这两个名字不能作为标识符或者属性名,否则会抛出错误。
3.3 变量
ECMAScript的变量时松散型的,所谓松散类型就是可以用来保存任何类型的数据。换句话说,每个变量仅仅是一个用于保存占位符而已。定义变量时要使用var操作符(注意var是一个关键字),后跟变量名(即一个标识符),如下所示:
var message;
这行代码定义了一个名为message变量,该变量可以用来保存任何值(像这样未经初始化的变量,会保存一个特殊值—undefined)。ECMAScript也支持直接初始化变量,因此定义变量的同时就可以设置变量的值,如下所示:
var message = "Hi";
在此,变量message中保存了一个字符串”hi”。像这样初始化变量并不会把它标记为字符串类型;初始化过程找那个的过程就是给变量赋一个值那么简单。因此,可以在修改变量值的同时修改值的类型,如下所示:
在这个例子中,变量message一开始保存了一个字符串”hi”,然后该值又被一个数字值100取代。虽然我们不建议修改变量所保存值的类型,但这种操作在ECMAScript中完全有效。
有一点必须注意,即用var操作符定义的变量将成为该变量作用域中的局部变量。也就是说,如果在函数中使用var定义一个变量,那么这个变量在函数退出后就会被销毁,例如:
function test(){
var message = "hi"; //局部变量
}
test();
alert(message); //错误
这里,变量message是在函数中使用var定义的。当函数调用时,就会创建该变量并未器赋值。而在此之后,这个变量又会被立即销毁,因此例子中的下一行代码就会导致错误。向下面这样省略var操作符,从而创建一个全局变量。
function test(){
message = "hi";
}
test();
alert(message); // "hi"
这个例子省略了var操作符,因而message就成了全局变量。这样,只要调用过test()函数,这个变量就有了定义,就可以在函数外部的任何地方被访问到。
虽然省略var操作符可以定义全局变量,但是这也不是我们推荐的做法。因为在局部作用域中定义的全局变量很难维护,因而如果有意忽略了var操作符,也会由于相应变量不会马上就定义而导致不必要的混乱。给为经声明的变量赋值在严格模式下会导致抛出ReferenceError错误。
可以使用一条语句定义多个变量,只要像下面这样把每个变量(初始化或不初始化均可)用逗号分隔开即可:
var message = "hi",
found = false,
age = 20;
这个例子中定义并初始化了3个变量。同样由于ECMAScript是松散类型的,因而使用不同类型初始化变量的操作可以放在一条语句中来完成。虽然代码里的换行和变量缩进不是必须的,但这样可以提高可读性。
在严格模式下不能,不能定义名为eval或arguments的变量,否则会导致语法错误。