与其说是JavaScript基础,不如叫ECMAScript基础,因为关于语法、类型、控制语句、函数等都是ECMAScript标准制定的。
ECMAScript版次目前是第5版次,但是目前主流浏览器支持版次并不一致,正如我们在第一篇简介中介绍的一样,ECMA-262第4版没有发布就夭折了,所以现在主流浏览器支持的是第三和第五版,需要是我们会特别指出区别。
ECMAScript语法大量借鉴了C及其他类C语言(如Java和Perl)的语法。i
1.同C一样,Javascript的变量是区分大小写的。标识符、注释、语句也同C类似,特别指出的是:Javascript 语句的末尾不加分号也可以正常执行,但不建议这样做。
ECMAScript 5 引进了严格模式(strict mode)的概念。严格模式是位javascript定义了一种不同的解析与执行模型。在严格模式下,ECMAScript 3 中的一些不确定的行为将得到处理,而且对某些不安全的操作也会抛出错误。要在整个脚本中启动严格模式,可以在顶部添加如下代码:
“use strict”;
这行代码看起来想字符串,而且没有赋值给任何变量,但其实他是一个编译指示,用于告诉支持的JavaScript引擎切换到杨哥模式。
ECMAScript的变量是松散类型的,可以用来保存任何类型的数据。定义变量是使用var操作符。
同C一样ECMAScript也有局部变量,在函数内生命的变量是局部变量,函数外无法访问。但如果函数体内不是用var声明的变量就全局变量,因此函数体外可以访问。但是在严格模式下,给未经生命的变量赋值会返回ReferenceError异常。
3.数据类型
ECMAScript有五种简单数据类型(也称为基本数据类型):Undefined、Null、Boolean、Number、String。还有一种复杂数据类型:Object。
使用typeof操作符返回字符串可能有:undefined、boolean、string、number、object、function。对null使用typeof操作符会返回“object”,因为特殊值null被认为是一个空的对象引用。
Undefined类型只有一个值,就是undefined。在使用var声明变量但未对其加以初始化时,这个变量就是undefined。
Null类型也只有一个值,就是null。null==undefined返回是true。
Boolean类型有两个值,true和false。使用转型函数Boolean() 可以讲一个值转换成其对应的Boolean值。转换规则如下:
数据类型 | 转换成ture的值 | 转换成false的值 |
Boolean | true | false |
String | 任何非空字符串 | “”(空字符串) |
Number | 任何非零数字值 | 0和NaN |
Object | 任何对象 | null |
Undefined | undefined |
Number类型使用IEEE754格式来表示整数和浮点数值。整数可以用8进制和16进制表示,其中8进制前导是0,16进制前导是0x。注意,在严格模式下8进制格式是无效的,会抛出异常。浮点数值可以使用科学表示法来表示,如var floatNum=3.14e6;注意IEEE754数值的通病是精度问题,如0.2+0.1=0.300000000000000004,所以0.2+0.1!=0.3。ECMAScript能够表示的最小数值保存在Number.MIN_VALUE中。最大值保存在Number.MAX_VALUE中。Number.NEGATIVE_INFINITY和Number.POSITIVE_INFINNITY保存着负和正的超出范围的值,分别为:-Infinity和Infinity。有一个函数可以判断数值是否有限:isFinite()。NaN即非数值。首先,任何涉及NaN的操作都会返回NaN,这个特点是在多部计算中有可能导致的问题。其次,NaN与任何值都不相等。包括NaN。所以NaN!=NaN。函数:isNaN()可以判断参数是否不是数值。
有三个函数可以把非数值转换成数值:Number() parseInt() parseFloat()。使用parseInt()方法建议放入两个参数,第二个参数用来确定第一个参数代表的进制。
String类型用单引号和双引号并没有区别。ECMAScript中字符串是不可变的,也就是说一旦字符串创建,他们的值就不能改变。要改变某个变量保存的字符串,首先要销毁原来的字符串,然后再用另一个包含新值的字符串填充该变量。把一个值转换成字符串使用该值自带的toString方法(类似java),但是null和undefined是没有这个方法的。那么就要使用String()方法。null返回“null”,undefined返回“undefined”。
Object类型其实就是一组数据和功能的集合。同java中java.lang.Object方法一样,是所有对象的父类。其中包含的属性和方法如下:
在ECMAScript中Object是所有对象的基础,因此所有对象都具有这些基本的属性和方法。
一元操作符:++/--/+/-同C语言。
位操作符:非~ / 与& / 或| / 异或^ / 左移<< / 有符号右移>> / 无符号右移>>>
布尔操作符:非!/ 与&& / 或||
乘性操作符:乘法* / 除法/ / 求模%
加性操作符:加法+ / 减法-
关系操作符:大于> / 小于< / 大于等于>= / 小于等于<=
相等操作符:相等和不相等== != 先转换再比较 / 全等和不全等 === !== 仅比较不转换
条件操作符: ?:同java
赋值操作符: = 在等号前面再添加乘性操作符、加性操作符或位操作符就可以完成复合赋值操作。
逗号操作符:逗号操作符多用于声明多个变量。
if语句、do-while语句、while语句、for语句、for-in语句、label语句、break、continue语句、with语句、switch语句
需要特别讲一下的是label语句,这个语句相信是来自汇编或C的,用于在代码中添加标签,以便将来使用,一般都配合break和continue使用(是因为没有goto语句)。因为break和continue都只能跳出最近的一次循环,配合label就可以想跳出多少个循环就跳出多少个循环了,一般label放在for之前。
"use strict"; 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++; } } console.log(num);
想一下这段代码会返回什么?答案是95.因为i==5 j==5的时候跳出了循环,i继续增加变成6,j继续从0开始,导致i5 j5、i5j6、i5j7、i5j8、i5j9五次没有执行。
with语句不建议使用因为会影响效率,而且增加了调试难度。
其他语句和c或java并无二致。
ECMAScript函数的参数与大多数其他语言中函数的参数不同,ECMAScript的函数不介意传递进来多少个参数,也不在乎传递进来参数是什么类型。ECMAScript中参数在内部是用一个数组表示的。函数接收到的始终都是这个数组,而不关心数组中有哪些参数。在函数体内可以通过arguments对象来访问这个数组,进而获取到传递给函数的每一个参数。
其实arguments只是与数组类似,并不是Array的实例。
ECMAScript中所有参数传递的都是值,不可能通过引用传递参数。
因为ECMAScript函数没有函数签名,所以ECMAScript函数没有重载。我们可以通过判断arguments的长度来变相的来实现重载。
function doAdd(){ if(arguments.length == 1){ console.log(arguments[0] + 10); }else if(arguments.length == 2){ console.log(arguments[0] + arguments[1]); } } var arg0 = 10; var arg1 = 20; doAdd(arg0); //返回20 doAdd(arg0, arg1); //返回30
ECMAScript中包含了所有基本的语法、操作符、数据类型、已经完成基本计算任务所必须的对象。但是没有对取得输入和产生输出的机制做规定。目前大多数实现所遵循的都是ECMA-262的第三版,但已经有一部分开始实现第5版了。
ECMAScript的基本要素有: