Table of Contents
第 3 章 基本概念
1.语法
1.变量名、函数、操作符区分大小写
2.标识符
- 第一个字符必须是一个字母、下划线或一个美元符号;
- 其他字符可以是字母、下划线、美元符号或数字;
- 标识符中的字母也可以包含扩展的ASCII或Unicode字母字符。
3.注释
使用//或/**/作为注释。
4.严格模式
可以在脚本的开头添加“use strict”;让整个脚本启用严格模式,或者在函数内部上方添加以让函数使用严格模式:
function doSomething() {
"use strict";
//函数体
}
5.语句
语句可以用或者不用;作为结尾;
2.关键字和保留字
3.变量
定义变量时可以使用var关键字也可以不使用。使用var关键字的话创建的变量为当前作用域中的局部变量,退出当前作用域这个变量就销毁了。不使用var关键字则声明的是一个全局变量,退出当前作用域后仍然可以访问这个变量。
严格模式下不能定义名为eval或arguments的变量。
4.数据类型
5种基本数据类型:Undefined,Null,Boolean,Number和String。
1种复杂数据类型,Object,本质上是一种无序的名值对。
1.typeof操作符
typeof是操作符而不是函数,所以可以省略括号。
返回值
- ‘undefined’,如果这个值未定义(声明了变量,但是未赋予具体的值);
- ‘boolean’
- ‘string’
- ‘number’
- ‘object’,如果这个值是对象或者null,因为null被认为是一个空的对象的引用;
- ‘function’,如果这个对象是函数;
在ECMAScript中,函数是对象,不是一种数据类型,但是函数有一些特殊的属性,因此typeof将其特别区分了出来。
2.Undefined类型
Undefined表示声明了但是未初始化的变量,用来正式区分空对象指针null。
未初始化的变量只能执行一项操作,那就是typeof操作符。
未声明的变量typeof操作符也会返回undefined。
3.Null类型
null用来专门指代要用来保存对象,但是还未赋值的空指针。
undefined值派生自null值,因此ECMA-262规定它们的相等性测试要返回true。
当一个变量是用来保存对象引用的,就应该将其初始化为null。
4.Boolean类型
一定要使用true和false,大小写不能搞错。
各种数据类型转换为Boolean类型的规则:
数据类型 | 转换为true的值 | 转换为false的值 |
Boolean | true | false |
String | 任何非空字符串 | “”(非空字符串) |
Number | 任何非零数字值(包括无穷大) | 0和NaN |
Object | 任何对象 | null |
Undefined | undefined只有一个值,只能转为false | undefined |
null不能转换为Boolean,而undefined可以。
5.Number类型
严格模式下八进制字面量无效。
如果数值可以用整型表示,那么JavaScript引擎会尽量将其用整型表示以节省空间;
所以Number的实现是一个32位int或者一个double。
特殊值:
- Number.MIN_VALUE 5e-324
- Number.MAX_VALUE 1.7976931348623157e+308
- Infinity, -Infinity,计算结果的数值如果超出了这些范围,那么就用Infinity或-Infinity表示;另外提供isFinite函数来判断一个值是否是有限的;另外也可以使用Number.NEGATIVE_INFINITFY和Number.POSITIVE_INFINITY;
- NaN,表示一个本来要返回数值的操作数未返回数值的情况,比如任何数值除以非数值。任何涉及NaN的操作结果都会返回NaN。可以用isNan函数判断是否为NaN,任何不能被转换为数值的值都会被isNaN函数返回false。对于Object类型,isNaN会先尝试调用其valueOf方法,判断该函数返回值是否可以转换为数值,如果不能再调用其toString方法,再测试其返回值是否能转换为数值。
数值转换
有3个函数可以把非数值转换为数值:Number(),parseInt()和parseFloat()。第一个函数可以用于任何类型,而后两个则专门用于字符串。
Number函数的转换规则:
- 对于Boolean输入,true和false分别被转换为1和0;
- 对于null输入,返回0;
- 对于undefined,返回NaN;
- 对于字符串,如果不能转换为数字,则将其转换为NaN;
- 对于对象,先尝试转换其valueOf方法返回值,再尝试转换其toString方法返回值;
空字符串会被转换为0。空字符串”不是null也不是undefined。
对于’12blue’这种字符串,Number会转换为NaN,而parseInt会转换为12。
ECMAScript 3 JavaScript引擎支持八进制字面量,而ECMAScript 5 JavaScript引擎不支持。
parseInt函数可以通过第二个参数来指定解析字面量时使用的进制。
6.String类型
String类型用于表示由零或多个16位Unicode字符组成的字符串序列。
转义序列
- ‘\xnn’ 以十六进制nn表示的一个字符,如’\x41’表示’A’
- ‘\unnnn’以十六进制代码nnnn表示的一个Unicode字符,如\u03a3表示希腊字母Σ。
length属性可以返回字符串中字符数。
ECMAScript中的字符串是不可改变的。
除了null和undefined方法没有toString方法,其他类型都有toString方法。
String()方法则可以对任何类型使用,该方法会调用输入对象的toString方法,对于null和undefined则会分别返回’null’和’undefined’。
7.Object类型
通过new操作符可以创建新的对象。
var o = new Object();
如果不需要给构造函数传递参数,可以省略掉后面的括号。
每个Object类型都具有下面的属性和方法:
- constructor,构造函数;
- hasOwnProperty(propertyName),检查给定的属性是否在当前对象实例中存在,propertyName必须是以字符串形式作为参数;
- isPrototypeOf(object),检查传入的对象是否是当前对象的原型;
- propertyIsEnumerable(propertyName),检查给定的属性是否能够使用for-in语句,propertyName必须是以字符串形式作为参数;
- toLocaleString,返回对象的字符串表示,该字符串与执行环境的地区对应;
- toString,返回对象的字符串表示;
- valueOf,返回对象的字符串、数值或布尔值表示。通常与toString方法返回值相同。
对于DOM和BOM中的对象,他们属于宿主对象,由宿主环境提供实现和定义,他们不属于ECMA-262定义的对象,所以宿主对象可能不会继承Object。
5.操作符
1.一元操作符
递增和递减操作符
一元加和减操作符 一元加和减操作符会返回一个数值型的结果。
2.位操作符
JavaScript会将整型数值转为32位有符号数然后再进行位操作,最后将位操作结果再转为double。
NaN和Infinity会被当做0处理。
无符号右移>>>
有符号右移>>
3.布尔操作符
4.乘性操作符
ECMAScript定义二楼3个乘性操作符:乘法、除法和求模。引擎会将非数值类型的操作数转换为数值类型。
- Infinity和0相乘结果位NaN;
- Infinify除以Infinity,结果为NaN;
- 0除0,结果为NaN;
- 非零的有限数除以零,结果为Infinitfy或-Infinity;
5.加性操作符
- Infinitfy加-Infinity,结果为NaN;
- +0加-0,结果为+0;
- Infinity减Infinity,结果为NaN;
- +0减+0,结果为+0;
- -0减+0,结果为-0;
- -0减-0,结果为+0;
如果有一个操作数是字符串,那么两个操作数都得转换为字符串。
6.关系操作符
操作数中有数值类型时需要都转换为数值进行比较;
否则按照字符串逐个字符进行比较。
7.相等操作符
相等和不相等,先转换再比较
- 有布尔值,需要都转换为数值;
- 一个是字符串,另一个是数值,需要都转为数值;
- 一个是对象,另一个不是,需要调用对象的valueOf方法再比较;
比较规则
- null 和undefined相等
- 比较相等性之前,不能将null和undefined转为其他任何值
- 有NaN,相等操作符返回false,不相等操作符返回true
- 如果两个数都是对象,则比较他们是不是同一个对象,如果都指向同一个对象,则相等操作符返回true,否则返回false
全等(===)和不全等(!==),仅比较而不转换
8.条件操作符
9.赋值操作符
10.逗号操作符
逗号操作符会返回表达式中的最后一项。
6.语句
1.for-in语句
可以使用for (property in expression) statement或者for (var property in expression) statement,为了保证使用局部变量,最好把var加上。
如果要迭代的对象的值为null或undefined,ECMAScript不会执行这个循环。老旧版本则会抛出异常,所以为了兼容性最好在执行之前测试对象是否为null或undefined。
2.label语句
定义一个break和continue可以调整的标签。
label: statement
3.break和continue语句
break和continue可以联合label,指定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++;
}
}
alert(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++;
}
}
alert(num); //95
4.with语句
with(expression) statement;
使用with语句关联对象后,代码的作用域被设置到这个特定的对象中,代码中的变量先被认为是局部变量,如果局部环境没有定义这个变量,再查找这个对象中是否有这个变量。
严格模式不允许使用with语句。
var qs = location.search.substring(1);
var hostName = location.hostname;
var url = location.href;
可以通过with语句简化为
with(location){
var qs = search.substring(1);
var hostName = hostname; //unavailable when viewing from a local file
var url = href;
}
5.switch语句
ECMAScript的switch语句特色在于可以使用任何类型,甚至可以使用表达式。
switch语句在比较值时使用的是全等操作符,因此不会发生类型转换。
7.函数
严格模式对函数的限制:
- 不能把函数命名为eval或arguments
- 不能把参数命名为eval或arguments
- 不能出现两个命名参数同名的情况;
ECMAScript函数定义的参数个数与调用时传递的参数个数可以不同,调用时传递的参数会保存在arguments数组里(数组长度与调用时传递的参数个数一致)。在函数内部可以通过arguments数组访问函数参数列表。通过arguments访问的函数参数和通过命名参数访问的函数参数效果是一样的,他们的值总会保持同步(但他们的内存空间是独立的),但是如果调用时只传了一个参数,那么修改arguments[1]是不会将变化反映到第二个命名参数的。
严格模式下对arguments的重写操作无效,即对arguments的修改不会反映到命名参数上。
未传递值的命名参数的值默认为undefined。
ECMAScript函数不能实现重载。
两个名字相同的函数,后面的函数会覆盖掉前面的函数。
ECMAScript中的所有参数传递的都是值,不可能通过引用传递参数。
这个按值传递参数,相当于ECMAScript不能实现C++中的那种通过引用传递参数的功能:
int increment(int &x);
近期评论