ECMA-262通过叫做ECMAScript的“伪语言”为我们描述了JavaScript的语法,操作符,数据类型,内置功能等用于构建复杂解决方案的基本概念。下面内容是按ECMAScript的第3版说明。
语法
1. 区分大小写
2. 标识符(采用驼峰大小写格式,例如:myCar)
2.1 第一个字符必须是一个字母、下划线(_)或一个美元符号($)。
2.2 其他字符可以是字母、下划线、美元符号或数字。
3. 注释
3.1单行注释 例如: //,快捷键 -----Ctrl + /
3.2 多行注释 例如:/*
*
*/,快捷键----Ctrl + Shift + /
4.严格模式
ECMASript 5引入了严格模式的概念。严格模式是为了JavaScript定义了一种不同的解析与执行模型。(对不确定行为和不安全操作抛出错误)!在脚本中启用需在顶部添加代码:“use strict”。
5. 关键字和保留字
在实现ECMAScript 3 的 JavaScript 引擎中使用关键字作为标识符,会导致“Identifier Expected”错误。注意:ECMA-262第5版对eval和arguments进行限制。
6.变量
ECMAScript的变量是松散类型,可以用来保存任何类型的数据。可以在修改变量值的同时修改值得类型。用var操作符定义的变量将成为定义该变量的作用域中的局部变量,函数退出后该变量被销毁。
重点:
function test(){
message = “hi”; //全局变量
}
省略了var的message就变成全局变量,只有函数test()被调用,message才能转变为全局变量。
强调点:
虽然省略var操作符可以定义全局变量,但这也不是我们推荐的做法。因为在局部作用域中定义的全局变量很难维护,而且如果有意地忽略了var操作符,也会由于相应变量不会马上就有定义而导致不必要的错误。给未经声明的变量赋值在严格模式下会导致抛出ReferenceError错误。
数据类型
ECMAScript 中有5种简单数据类型(也称为基本数据类型):Undefined、Null、Boolean、Number和String。还有一种复杂数据类型---Object(本质上,由一组无序的名值对组成)。ECMAScript不支持任何自定义类型的机制,所有值最终都是由上述6种数据类型之一。
1. typeof操作符----检测给定变量的数据类型
typeof(num)可能返回下列某个字符串:
- “undefined”—— num未定义
- “boolean”—— num是布尔值
- “string” —— num 是字符串
- “number”——num是数值
- “object”——num是对象或null
- “function”——num是函数
注意: Safari 5 及 之前版本、Chrome 7 及 之前版本在对正则表达式调用typeof操作符时会返回“function”,而其他浏览器在这种情况会返回“object”;
2.数据类型介绍
2.1 Undefined类型
Undefined类型只有一个值,即特殊的undefined。在使用var声明变量但未对其加以初始化时,这个变量值就是undefined。
注意:ECMAScript 第3版中引入undefined,是为了区分空对象指针与未经初始化的变量。
例题: var message;
Console.log(message); //”undefined” Console.log(age); //产生错误 Console.log(typeof message); //”undefined” Console.log(typeof age); //”undefined”
2.2 Null类型
Null类型是第二个只有一个值的数据类型,这个特殊值为null。null值表示一个空对象指针。如果定义的变量准备在将来用于保存对象,最好将该变量初始化为null而不是其他值。只要直接检查null的值就可以知道相应的变量是否已经保存了一个对象。
实际上,undefined值派生自null值,因此ECMA-262规定对它们的相等性测试要返回true;
Console.log(undefined == null); //true
Console.log(undefined === null); //false
2.3 Boolean类型
该类型有两个字面值: true 和 false。ECMAScript中所有类型的值可以调用转型函数Boolean()转化为Boolean等价的值。
数据类型 |
转换为true的值 |
转换为false的值 |
Boolean |
true |
false |
String |
任何非空字符串 |
“”(空字符串) |
Number |
任何非零数字值(包括无穷大) |
0和NaN |
Object |
任何对象 |
Null |
Undefiend |
无 |
undefined |
2.4 Number类型
A)ECMA-262定义不同的数值字面量格式:
1、 十进制
2、 八进制(第一位必须是0,数字序列0~7);如果字面值中的数值超出范围,前导0被忽略后面数值当做十进制解析。
例如:09 —— 9
3、 十六进制 (前两位为Ox,数字序列0~9及A~F)
在算术计算时,所有以八进制和十六进制表示的数值最终被转换为十进制数值。
关于浮点数值计算会产生舍入误差,有一点需要明确:这是使用基于IEEE754数值的浮点计算的通病,ECMAScript并非独此一家,其他使用相同数据值格式的语言也存在这个问题。
B)数值范围
最大值:Number.MIN_VALUE(5e-324),如果超过范围自动转换为Infinity(无穷大)
最小值:Number.MAX_VALUE,如果超过范围自动转换为-Infinity(负无穷)
C)NaN(Not a Number)
用于表示一个本来要返回数值的操作数未返回数值的情况。
NaN特点:
1、 任何涉及NaN的操作,都会返回NaN。(多步计算有可能导致问题)
2、 NaN与任何值都不相等,包括NaN本身。
isNaN()函数
在接受到一个值后会将这个值转换为数值,不能被转换为数值的值都会导致这个函数返回true。
注意:在基于对象调用isNaN()函数时,会首先调用valueOf()方法,然后确定该方法返回的值是否可以转换为数值。如果不能,则基于这个返回值再调用toString()方法,再测试返回值。
D)数值转换
3个函数:
Number(),可以用于任何数据类型
parseInt(),parseFloat()专门用于把字符串转换为数值。
D.1、Number()函数转化规则:
i. 如果是Boolean值,true和false将分别被转 换为1和0.
ii. 如果是数字值,只是简单的传入和返回。
iii. 如果是null值,返回0
iv. 如果是undefined,返回NaN
v. 如果是对象,会首先调用valueOf()方法,然后确定该方法返回的值是否可以转换为数值。如果不能,则基于这个返回值再调用toString()方法,再测试返回值。
vi. 如果是字符串:
数字类型: 如果字符串只包含数字,将其转换为十进制。(“011”—>11(前导0被忽略))
如果字符串中包含有效的浮点格式,转换为对应的浮点数值。(前导0被忽略)
如果字符串中包含有效的十六进制格式,转换为相同大小的十进制整数值。
空字符串: 如果字符串是空的,则将其转换为0
其他:如果字符串中包含上述格式之外的字符,转换为NaN
D.2、parseInt()函数转换规则:
i. 会忽略字符串前面的空格。
ii. 如果第一个字符不是数字或负号,parseInt会返回NaN.
a) 例如:(parseInt(“”)=NaN,而Number(“”)=0)
iii. 如果第一个字符是数字字符,会继续解析第二个字符,直至解析完所有后续字符或遇到了一个非数字字符。
iv. 如果是十六进制或八进制,转换成十进制。
注意:ECMAScript 5 JavaScript引擎中,parseInt()不具有解析八进制的能力,因此前导0被认为无效。
D.3、parseFloat()函数
从第一个字符(位置0)开始解析每个字符,一直解析到字符串末尾,或者解析到遇见一个无效浮点数字字符为止。(字符串中第一个小数点是有效的,而第二个小数点是无效。例如: “22.34.24”=22.34)
2.5 String类型
String类型用于表示有零或多个16位Unicode字符组成的字符序列。由单引号或双引号表示。
A) 字符字面量(转义序列)
(换行), (回车)……注意:这些字符字面量被当做一个字符来解析。
B) 字符串特点
不可变性——字符串一旦创建,它们的值就不能改变。要改变某个变量保存的字符串,首先要销毁原来的字符串,然后再用另外一个包含新值的字符串填充该变量。
C) 转换为字符串
C.1)toString()—null和undefined没有该方法。
C.2)转型函数String(),能够将任何类型的值转换为字符串。
转换规则:
i. 如果值有toString()方法,则调用该方法(没有参数)并返回相应的结果。
ii. 如果值是null,则返回“null”
iii. 如果值是undefined,则返回“undefined”
2.6 Object类型
对象可以通过执行new操作符后跟要创建的对象类型的名称来创建。而创建Object类型的实例并为其添加属性和方法,就可以创建自定义对象。
Object类型是所有它实例的基础,所以Object类型所具有的任何属性和方法也同样存在于更具体对象中。
Object的每个实例都具有下列属性和方法:
i. constructor:保存着用于创建当前对象的函数。
ii. hasOwnProperty:用于检测给定的属性在当前对象实例中(而不是在实例的原型中)是否存在。
iii. isPrototypeOf(object):用于检查传入的对象是否是当前对象的原型。
iv. propertyIsEnumerable(propertyName):用于检查给定的属性是否能够使用for in语句。
v. toLocalString():返回对象的字符串表示,该字符串与执行环境的地区对应。
vi. toString():返回对象的字符串表示。
vii. valueOf()返回对象的字符串、数值或布尔值表示。通常与toString()方法的返回值相同。
3、操作符
在应用于对象时,相应的操作符通常都会调用对象的valueOf()和(或)toString(),以便取得可以操作的值。
3.1 算术操作符
一元操作符——只能操作一个值的操作符
A) 递增和递减操作符
前置(++i):先+1,然后参与运算
和后置(i--):先参与运行,然后+1
B) 一元加和减操作符
对非数值应用一元加操作符时,该操作符会像Number()转型函数一样对这个值转换。
3.2 位操作符
位操作符用于在最基本的层次上,即按内存中表示数值的位来操作数值。ECMAScript中所有数值都以IEEE-754 64位格式存储,但未操作并不会直接操作64位的值。而是先将64位的值转换为32位的整数,然后执行操作,最后再将结果转换会64位。这个转换过程中导致一个严重负效应,即在对特殊的NaN和Infinity值应用为操作时,都会被当做0处理。
对于有符号的整数,32位中的前31位用于表示整数的值,第32位用于表示数值的符号。0是正数,正数以纯二进制格式存储;1是负数,负数采用二进制补码。
二进制补码:
1) 求这个数值绝对值的二进制码
2) 求二进制反码,即将0替换为1,将1替换为0;
3) 得到的二进制反码加1;
3.2.A 按位非(NOT)
按位非操作符由一个波浪线(~)表示,执行按位非的结果就是返回数值的反码。
var num1= 25; alert(~num1)=-26;(按位非本质:操作数的负值减1)
3.2.B 按位与(AND)
按位与操作符由一个和号字符(&)表示,它有两个操作数。从本质上讲按位与操作就是将两个数值的每一位对齐,然后根据规则求值。
规则总结:只在两个数值的对应为都是1时才返回1,任何一位是0,结果都是0;
3.2.C 按位或
按位或操作符由一个竖线符号(|)表示。
规则总结:有一个为1就返回1,而只有两个位都是0的情况下才返回0;
3.2.D 按位异或
按位异或操作符由一个插入符号(^)表示。
规则总结:两个数值对应位上只有一个1时才返回1,如果对应的两位都是1或0,则返回0;
3.2.E 左移
左移操作符(<<),这个操作符会将数值的所有位向左移动指定的位数。
3.2.F 有符号右移(>>)
在位移过程中,原数值中也会出现空位。只不过这次的空位出现在原数值的左侧,符号位的右侧。ECMAScript会用符号位的值来填充所有空位,以便得到一个完整的值。
3.2.G 无符号右移(>>>)
3.3 关系操作符
> 、< 、>= 、<=
3.4 相等操作符
相等(==)和不相等(!=):先强制转换再比较
全等(===)和不全等(!==):仅比较而不转化
3.5 条件操作符
var max = (num1>num2)?num1:num2;
3.6 赋值操作符
*= 、 /= 、%= 、 += 、-=、<<=、>>=、>>>=
流控制语句
- if语句
- do-while语句(后测试循环语句)
在对条件表达式求值之前,循环体内的代码至少会被执行一次。
- while语句(前测试循环语句)
- for语句
具有在执行循环之前初始化变量和定义循环内要执行代码的能力。
说明:初始化变量时,可以不使用var关键字或者在外部执行。
由于ECMAScript中不存在块级作用域,在循环内部定义的变量也可以在外部访问到。
- for – in语句
是一种精准的迭代语句,可以用来枚举对象的属性。遇到null或undefined会跳过。
6. break和continue语句
两者区别: break语句会立即退出循环,强制继续执行循环后面的语句。而continue语句虽然立即退出循环,但退出循环后会从循环的顶部继续执行。
7.with语句
With语句的作用是将代码的作用域设置到一个特定的对象中。(会导致性能下降)
8. switch语句
注意:switch语句在比较值时使用的是全等操作符,因此不会发生类型转换。