1 语法
1.1 区分大小写
ECMAScript中的一切(变量、函数名和操作符)都区分大小写。
1.2 严格模式
ECMAScript 5 引入了严格模式(strict mode)的概念。严格模式是为JavaScript定义了一种不同的解析与执行模型。
在严格模式下,ECMAScript 3 中的一些不确定的行为将得到处理,而且对某些不安全的操作也会抛出错误。
要在整个脚本中启用严格模式,可以再顶部添加如下代码:
"use strict"
指定函数在严格模式下执行:
function doSomething(){
"use strict";
//函数体
}
2 关键字和保留字
关键字
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 第五版非严格模式:class、enum、extends、super、const、export、import
ECMA-262 第五版严格模式增加以下限制:implements、package、public、interface、private、static、let、protected、yield
3 变量
ECMAScript的变量是松散类型的,所谓松散类型就是可以用来保存任何类型的数据。换句话说,每个变量仅仅是一个用于保存值得占位符而已。
var message;
像这样未经过初始化的变量,会保存一个特殊的值——undefined
给未经声明的变量赋值在严格模式下会导致抛出PeferenceError错误
4 数据类型
ES 5
5种简单数据类型(也称为基本数据类型):Undefined、Null、Boolean、Number、String
1种复杂数据类型——Object,Object本质上是由一组无序的名值对组成的。
ES 6 新增一种数据类型——符号对象(Symbol)
4.1 typeof 操作符
typeof 用来检测给定变量的数据类型
"undefined"——如果这个值未定义
"boolean"——如果这个值是布尔值
"string"——如果这个值是字符串
"number"——如果这个值是数值
"object"——如果这个值是对象或null
"function"——如果这个值是函数
调用typeof null会返回"object",因为特殊值null被认为是一个空的对象引用。
4.2 Undefined 类型
Undefined类型只有一个值,即特殊的undefined。在使用var声明变量但未对其加以初始化时,这个变量的值就是undefined
var message;
console.log(message == undefined); //true
字面量undefined的主要目的是用于比较,为了正式区分空对象指针与未经初始化的变量
4.3 Null 类型
Null类型是第二个只有一个值的数据类型,这个特殊的值是null。从逻辑角度来看,null值表示一个空对象指针,而这也正式使用typeof操作符检测null值时会返回"object"的原因
var car = null;
console.log(typeof null); //object
如果定义的变量准备在将来用于保存对象,那么最好将该变量初始化为null而不是其他值。这样一来,只要直接检查null值就可以知道相应的变量是否已经保存了一个对象的引用。
实际上,undefined值是派生自null值得,因此ECMA-262规定对他们的相等性测试要返回true
console.log(null == undefined); //true
4.4 Boolean 类型
Boolean类型只有两个字面值:true和false
Boolean类型的字面值true和false是区分大小写的
可以对任何数据类型的值调用Boolean()函数,而且总会返回一个Boolean值
数据类型 | 转换为true的值 | 转换为false的值 |
---|---|---|
Boolean | true | false |
String | 任何非空字符串 | "" (空字符串) |
Number | 任何非零数字值 | 0和NaN |
Object | 任何对象 | null |
Undefined | N/A | undefined |
n/a (N/A),是not applicable的缩写,意思是"不适用"。
4.5 Number类型
Number类型使用IEEE754格式来表示整数和浮点数值(双精度值)。为支持各种数值类型ECMA-262定义了不同的数值字面量格式。
十进制
var intNum == 55;
八进制
八进制字面值的第一位必须是零(0),然后是数字序列(0~7)。如果字面值中的数值超出了范围,那么_前导零_ 将被忽略,后面的数值将被当做十进制十进制数值解析
var octalNum1 = 070; //八进制的56
var octalNum2 = 079; //无效的八进制数值——解析为79
var octalNum3 = 08; //无效的八进制数值——解析为8
八进制字面量在严格模式下是无效的,会导致支持该模式的JavaScript引擎抛出错误。
十六进制
十六进制字面值的前两位必须是0x,后跟任何十六进制数字(0~9 及 A~F)。字母A~F可以大写,也可以小写
var hexNum1 = 0xA; //十六进制的10
var hexNum2 = 0x1f; //十六进制的31
在进行算数计算时,所有以八进制和十六进制表示的数值最终都将被转换成十进制数值
4.5.1 浮点数值
保存浮点数值需要的内存空间是保存整数值得两倍,如果小数点后面没有跟任何数字,或者浮点数值本身表示的就是一个整数(如1.0),那么该值将会被转换成整数
var floatNum1 = 1; //小数点后面没有数字——解析为1
var floatNum2 = 10.0; //整数——解析为10
对于那些极大或极小的数值,可以用e表示法(即科学计数法)表示浮点数值。用e表示法表示的数值等于e前面的数值乘以10的指数次幂。
var floatNum1 = 3.125e7; //等于31250000
var floatNum2 = 3e-7; //等于0.0000003
浮点数值得最高精度是17位小数,但在进行算术计算时其精度远远不如整数。例如,0.1加0.2的结果是0.30000000000000004
4.5.2 数值范围
由于内存的限制,ECMAScript并不能保存世界上所有的数值。
最小数值 Number.MIN_VALUE //5e-324
最大数值 Number.MAX_VALUE //1.7976931348623157e+308
如果某次计算的结果得到了一个超出JavaScript数值范围的值,那么这个值将被自动转换成特殊的Infinity值
正无穷大 Infinity
负无穷大 -Infunity
isFinite()函数可以判断一个数值是否又穷的
4.5.3 NaN
NaN,即非数值(Not a Number),是一个特殊的数值,这个数值用于本来要返回数值的操作数未返回数值的情况(这样就不会抛出错误了)
任何涉及NaN的操作(例如NaN/10)都会返回NaN
NaN与任何值都不相等,包括NaN本身
console.log(NaN == NaN); //false
ECMAScript定义了isNaN()函数,这个函数接受一个参数,该参数可以是任何类型,而函数会帮我们确定这个函数是否"不是数值"
isNaN()也适用于对象,基于对象调用isNaN()函数时,会先调用对象的valueOf()方法,再确定该方法返回的值是否可以转换为数值。如果不能,则基于这个返回值再调用toString()方法,在测试返回值
4.5.4 数值转换
Number()
、parseInt()
、parseFloat()
4.6 String类型
4.6.1 字符字面量
String数据类型包含一些特殊的字符字面量,也叫转义序列,用于表示非打印字符,或者具有其他用途的字符。
n:换行
t:制表
b:退格
r:回车
f:进纸
x_nn_:以十六进制代码_nn_表示的一个字符(其中_n_为0~F)。例如,x41表示"A"
u_nnnn_:以十六进制代码_nnnn_表示的一个Unicode字符(其中_n_为0~F)。例如,u03a3表示希腊字符Σ
任何字符串的长度都可以通过访问其length属性取得:
var text = "This is the letter sigma: \u03a3.";
console.log(text.length); //输出28
这个属性返回的字符数包括16位字符的数目。如果字符串中包含双字节字符,那么length属性可能不会精确地返回字符串中的字符数目。
4.6.2 字符串的特点
ECMAScript中的字符串是不可变的。字符串一旦创建,它们的值就不能改变。要改变某个变量保存的字符串,首先要销原来的字符串,然后再用另一个包含新值的字符串填充该变量
4.6.3 转换为字符串
要把一个值转换为一个字符串有两种方法:
几乎每个值都有的
toString()
方法
null和undefined值没有这个方法
toString()
方法接受一个参数:输出数值的基数,toString()
可以输出以二进制、八进制、十六进制,乃至其他任意有效进制格式表示的字符串值(默认基数为10)
String()
函数能够将任何类型的值转换为字符串
如果值有
toString()
方法,则调用该方法(没有参数)并返回相应的结果;
如果值是null
,则返回"null";
如果值是undefined
,则返回"undefined"。
4.7 Object 类型
ECMAScript中的对象其实就是一组数据和功能的集合。对象可以通过执行new操作符后跟要创建的对象类型的名称来创建。
var o = new Object(); //无传参时可以省略括号,但不推荐这么做
Object的每个实例都具有下列属性和方法:
constructor
:保存着用于创建当前对象的函数。对于前面的例子而言,构造函数(constructor)就是Object()hasOwnProperty(propertyName)
:用于检查给定的属性在当前对象实例中(而不是在实例的原型中)是否存在。其中,作为参数的属性名(_propertyName_)必须以字符串形式指定(例如:o.hasOwnProperty("name")
)isPrototypeOf(Object)
:用于检查传入的对象是否是当前对象的原型propertyIsEnumerable(propertyName)
:用于检查给定的属性是否能够使用for-in
语句来枚举。与hasOwnProperty()
方法一样,作为参数的属性名必须以字符串形式指定toLocaleString()
:返回对象的字符串表示,该字符串与执行环境的地区对应toString()
:返回对象的字符串表示valueOf()
:返回对象的字符串、数值或布尔值表示。通常与toString()
方法的返回值相同
由于在ECMAScript中Object
是所有对象的基础,因此所有对象都具有这些基本的属性和方法。
5 操作符
5.1 一元操作符
只能操作一个值的操作符叫做一元操作符
5.1.1 递增和递减操作符
执行前置递增和递减操作符时,变量的值都是在语句被求值以前改变的
(在计算机领域,这种情况通常被称作副效应)
var age = 29;
var antherAge = --age + 2;
console.log(age); //输出28
console.log(anotherAge); //输出30
执行后置递增和递减操作符时,变量的值都是在语句被求值之后改变的
var num1 = 2;
var num2 = 20;
var num3 = num1-- + num2; //等于22
var num4 = num1 + num2; //等于21
递增递减操作符对任何值都适用
5.1.2 一元加和减操作符
在对非数值应用一元加(减)操作符时,该操作符会像Number()
函数一样对这个值执行转换。
5.2 位操作符
......
5.3 布尔操作符
5.3.1 逻辑非
逻辑非操作符由一个叹号(!
)表示,可以应用于ECMAScript中的任何值。无论这个值是什么数据类型,这个操作符都会返回一个布尔值。
同时使用两个逻辑非操作符,实际上就会模拟Boolean()
转型函数的行为
5.3.2 逻辑与
逻辑与操作符由两个和号(&&
)表示,有两个操作数
逻辑与操作可以应用于任何类型的操作数,而不仅仅是布尔值。在有一个操作数不是布尔值的情况下,逻辑与操作就不一定返回布尔值:
如果第一个操作数是对象,则返回第二个操作数
如果第二个操作数是对象,则只有在第一个操作数的求值结果为
true
的情况下才会返回该对象如果两个操作数都是对象,则返回第二个操作数
如果第一个操作数是
null
,则返回null
如果第一个操作数是
NaN
,则返回NaN
如果第一个操作数是
undefined
,则返回undefined
逻辑与操作属于短路操作,如果第一个操作数能够解决结果,那么久不会再对第二个操作数求值
var found = true;
var result = (found && someUndefinedVariable); //这里会发生错误
console.log(result); //这一行不会执行
上面代码中,当执行逻辑与操作符时会发生错误,因为变量someUndefinedVariable没有声明
var found = false;
var result = (found && someUndefinedVariable); //不会发生错误
console.log(result); //会执行("false")
5.3.3 逻辑或
逻辑或操作符由两个竖线符号(||
)表示,有两个操作数
与逻辑与相似,如果有一个操作数不是布尔值,逻辑或也不一定返回布尔值:
如果第一个操作数是对象,则返回第一个操作数
如果第一个操作数的求值结果为
false
,则返回第二个操作数如果两个操作数都是对象,则返回第一个操作数
如果两个操作数都是对象,则返回第一个操作数
如果两个操作数都是
null
,则返回null
如果两个操作数都是
undefined
,则返回undefined
逻辑或操作符也是短路操作符。也就是说,如果第一个操作数的求值结果为true,就不会对第二个操作数求值了
5.6 关系操作符
小于(<)、大于(>)、小于等于(<=)、大于等于(>=)
当关系操作符的操作数使用了非数值时,会进行数据转换或完成某些奇怪的操作:
如果两个操作数都是数值,则执行数值比较
如果两个操作数都是字符串,则比较两个字符串对应的字符编码值
如果一个操作数是数值,则将另一个操作数转换为一个数值,然后执行数值比较
如果一个操作数是对象,则调用这个对象的
valueOf()
方法,用得到的结果按照前面的规则执行比较。如果对象没有valueOf()
方法,则调用toString()
方法,并用得到的结果根据前面的规则执行比较如果一个操作数是布尔值,则先将其转换为数值,然后再执行比较
任何操作数与
NaN
比较,都会返回false
5.7 相等操作符
5.7.1相等和不相等
如果两个操作数数据类型不同,则会先转换数据类型(通常称为强制转型)再比较
null
和undefined
是相等的要比较相等性之前,不能将
null
和undefined
转换成其他任何值有一个操作符为
NaN
时,相等操作符返回false
,NaN
不等于NaN
如果两个操作数都是对象,则比较它们是不是同一个对象
5.7.2 全等和不全等
除了在比较之前不转换操作数之外,全等和不全等操作符没有什么区别
5.8 条件操作符
variable = boolean_expression ? true_value : false_value;
var max = (num1 > num2) ? num1 : num2;
5.9 赋值操作符
等于号(=)
5.10 逗号操作符
逗号(,)
6语句
6.1 if语句
if(1 > 25){
console.log();
}else{
console.log();
}
6.2 do-while语句
var i = 0;
do{
i += 2;
}while(i < 10);
console.log(i);
6.3 while语句
var i = 0;
while(1 < 10){
i += 2;
}
6.4 for语句
var count = 10;
for(var i = 0; i < count; i++){
console.log(i);
}
由于ECMAScript中不存在块级作用域,因此在循环内部定义的变量也可以在外部访问到
for语句中的初始化表达式、控制表达式和循环后表达式都是可选的。将这三个表达式全部省略,就会创建一个无限循环
6.5 for-in语句
for-in语句是一种精准的迭代语句,可以用来枚举对象的属性
for(var propName in window){
document.write(propName);
}
ECMAScript对象的属性没有顺序。因此,通过
for-in
循环输出的属性名的顺序是不可预测的
6.6 label语句
使用label语句可以在代码中添加标签,以便将来使用
start: for(var i = 0; i < count; i++){
console.log(i);
}
这个例子中定义的start标签可以在将来有
break
或continue
语句引用。加标签的语句一般都要与for语句等循环语句配合使用
6.7 break和continue语句
break
和continue
语句用于在循环中精确地控制代码的执行
var num = 0;
outermost:
for(var i = 0; i < 10; i++){
for(var j = 0; j < 10; j++){
if(i == 5 && j == 5){
break outermost;
}
num++;
}
}
console.log(num); //55
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
//如果两个循环都自然结束,num的值应该是100
6.8 with语句(舍弃!)
严格模式下不允许使用with语句,否则将视为语法错误。
由于大量使用with语句会导致性能下降,同时也会给调试代码造成困难,因此不建议使用with语句
6.9 switch语句
var num = 25;
switch (true){
case num < 0:
console.log("0");
break;
case num >= 0 && num <= 10:
console.log("0");
break;
default:
console.log("0");
}
switch
语句在比较值时使用的是全等操作符,因此不会发生类型转换
7 函数
函数中的return
语句可以不带有任何返回值。在这种情况下,函数在停止执行后将返回undefined
值。
推荐的做法是要么让函数始终都返回一个值,要么永远都不要返回值。否则,如果函数有时候返回值,有时候不返回值,会给调试代码带来不便
7.1 理解参数
ECMAScript中的参数在内部是用一个数组来表示的。函数接收到的始终都是这个数组,而不关心数组中包含哪些参数(如果有参数的话)。
在函数体内可以通过
arguments
对象来访问这个参数数组
ECMAScript函数有一个重要的特点:命名的参数只提供便利,但不是必须的。
命名参数可以与arguments
对象一起使用,arguments
的值永远与对应命名参数的值保持同步。
没有传递值的命名参数将自动被赋予undefined
值。
严格模式下不允许重写命名参数或者
arguments
的值,虽然可以执行,但是命名参数与arguments
对应的值将不再同步
7.2 没有重载
ECMAScript函数不能像传统意义上那样实现重载。ECMAScript函数没有签名,因为其参数是由包含零或多个值的数组来表示的。而没有函数签名,真正的重载是不可能做到的。
如果定义了两个名字相同的函数,则该名字只属于后定义的函数,先定义的函数将被覆盖
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。