JavaScript高级程序设计3:第3章 基本概念

3.1 语法

3.1.1 区分大小写

ECMAScript 中的一切(变量、函数名和操作符)都区分大小写。

3.1.2 标识符

所谓标识符,就是指变量、函数、属性的名字,或者函数的参数。标识符可以是按照下列格式规则组合起来的一或多个字符:

(1) 第一个字符必须是一个字母、下划线(_)或一个美元符号($);

(2) 其他字符可以是字母、下划线、美元符号或数字。

ECMAScript 标识符采用驼峰大小写格式。

3.1.3 注释

单行注释和块级注释。

3.1.4 严格模式

要在整个脚本中启用严格模式,可以在顶部添加如下代码:

"use strict";

3.1.5 语句

虽然语句结尾的分号不是必需的,但我们建议任何时候都不要省略它。

3.2 关键字和保留字

一般来说,最好都不要使用关键字和保留字作为标识符和属性名,以便与将来的 ECMAScript 版本兼容。

3.3 变量

ECMAScript 的变量是松散类型的,所谓松散类型就是可以用来保存任何类型的数据。换句话说,每个变量仅仅是一个用于保存值的占位符而已。定义变量时要使用 var 操作符(注意 var 是一个关键字),后跟变量名(即一个标识符),如下所示:var message;

用 var 操作符定义的变量将成为定义该变量的作用域中的局部变量。也就是说,如果在函数中使用 var 定义一个变量,那么这个变量在函数退出后就会被销毁。

function test(){ 
 var message = "hi"; // 局部变量
} 
test(); 
alert(message); // 错误!

3.4 数据类型

ECMAScript 中有 5 种简单数据类型(也称为基本数据类型):Undefined、Null、Boolean、Number和 String。还有 1种复杂数据类型——Object,Object 本质上是由一组无序的名值对组成的。

3.4.1 typeof操作符

用来检测给定变量的数据类型。

 "undefined"——如果这个值未定义;
 "boolean"——如果这个值是布尔值;
 "string"——如果这个值是字符串;
 "number"——如果这个值是数值;
 "object"——如果这个值是对象或 null; 
 "function"——如果这个值是函数。

3.4.2 undefined类型

Undefined 类型只有一个值,即特殊的 undefined。在使用 var 声明变量但未对其加以初始化时,这个变量的值就是 undefined。

对未初始化和未声明的变量执行 typeof 操作符都返回了 undefined 值。

3.4.3 Null类型

Null 类型是第二个只有一个值的数据类型,这个特殊的值是 null。从逻辑角度来看,null 值表示一个空对象指针,而这也正是使用 typeof 操作符检测 null 值时会返回"object"的原因。

如果定义的变量准备在将来用于保存对象,那么最好将该变量初始化为 null 而不是其他值。

3.4.4 Boolean类型

该类型只有两个字面值:true 和 false。

要将一个值转换为其对应的 Boolean 值,可以调用转型函数 Boolean()。

数据类型转换为true的值转换为false的值
Booleantruefalse
String任何非空字符串""(空字符串)
Number任何非零数字值(包括无穷大)0和NaN
Object任何对象null
Undefinedn/a [是 not applicable 的缩写,意思是“不适用”。]undefined

3.4.5 Number类型

1.浮点数值

所谓浮点数值,就是该数值中必须包含一个小数点,并且小数点后面必须至少有一位数字。

在默认情况下,ECMASctipt 会将那些小数点后面带有 6 个零以上的浮点数值转换为以 e 表示法表示的数值(例如,0.0000003 会被转换成 3e-7)。

2.数值范围

如果某次计算的

结果得到了一个超出 JavaScript 数值范围的值,那么这个数值将被自动转换成特殊的 Infinity 值。具体来说,如果这个数值是负数,则会被转换成-Infinity(负无穷),如果这个数值是正数,则会被转换成 Infinity(正无穷)。

如上所述,如果某次计算返回了正或负的 Infinity 值,那么该值将无法继续参与下一次的计算,因为 Infinity 不是能够参与计算的数值。要想确定一个数值是不是有穷的(换句话说,是不是位于最小和最大的数值之间),可以使用 isFinite()函数。

3.NaN

NaN,即非数值(Not a Number)是一个特殊的数值,这个数值用于表示一个本来要返回数值的操作数未返回数值的情况。

1. 任何涉及 NaN 的操作(例如 NaN/10)都会返回 NaN
2. NaN 与任何值都不相等,包括 NaN 本身

针对 NaN 的这两个特点,ECMAScript 定义了 isNaN()函数。这个函数接受一个参数,该参数可以是任何类型,而函数会帮我们确定这个参数是否“不是数值”。isNaN()在接收到一个值之后,会尝试将这个值转换为数值。某些不是数值的值会直接转换为数值,例如字符串"10"或 Boolean 值。而任何不能被转换为数值的值都会导致这个函数返回 true。

alert(isNaN(NaN)); //true 
alert(isNaN(10)); //false(10 是一个数值)
alert(isNaN("10")); //false(可以被转换成数值 10)
alert(isNaN("blue")); //true(不能转换成数值)
alert(isNaN(true)); //false(可以被转换成数值 1)

4.数值转换

有 3 个函数可以把非数值转换为数值:Number()parseInt()parseFloat()。第一个函数,即转型函数 Number()可以用于任何数据类型,而另两个函数则专门用于把字符串转换成数值。

Number()函数的转换规则如下。
1. 如果是 Boolean 值,true 和 false 将分别被转换为 1 和 0。 
2. 如果是数字值,只是简单的传入和返回。
3. 如果是 null 值,返回 0。
4. 如果是 undefined,返回 NaN。
4. 如果是字符串,遵循下列规则:
 (1) 如果字符串中只包含数字(包括前面带正号或负号的情况),则将其转换为十进制数值,即"1"会变成1,"123"会      变成 123,而"011"会变成 11(注意:前导的零被忽略了);
 (2) 如果字符串中包含有效的浮点格式,如"1.1",则将其转换为对应的浮点数值(同样,也会忽略前导零);
 (3) 如果字符串中包含有效的十六进制格式,例如"0xf",则将其转换为相同大小的十进制整数值;
 (4) 如果字符串是空的(不包含任何字符),则将其转换为 0;  
 (5) 如果字符串中包含除上述格式之外的字符,则将其转换为 NaN。
5. 如果是对象,则调用对象的 valueOf()方法,然后依照前面的规则转换返回的值。如果转换的结果是 NaN,则调用对象的 toString()方法,然后再次依照前面的规则转换返回的字符串值。
var num1 = Number("Hello world!"); //NaN 
var num2 = Number(""); //0 
var num3 = Number("000011"); //11 
var num4 = Number(true); //1

由于 Number()函数在转换字符串时比较复杂而且不够合理,因此在处理整数的时候更常用的是parseInt()函数。

parseInt()函数在转换字符串时,更多的是看其是否符合数值模式。它会忽略字符串前面的空格,直至找到第一个非空格字符。如果第一个字符不是数字字符或者负号,parseInt()就会返回 NaN;也就是说,用 parseInt()转换空字符串会返回 NaN(Number()对空字符返回 0)。如果第一个字符是数字字符,parseInt()会继续解析第二个字符,直到解析完所有后续字符或者遇到了一个非数字字符。

var num1 = parseInt("1234blue"); // 1234 
var num2 = parseInt(""); // NaN 
var num3 = parseInt("0xA"); // 10(十六进制数)
var num4 = parseInt(22.5); // 22 
var num5 = parseInt("070"); // 56(八进制数)
var num6 = parseInt("70"); // 70(十进制数)
var num7 = parseInt("0xf"); // 15(十六进制数)

不指定基数意味着让 parseInt()决定如何解析输入的字符串,因此为了避免错误的解析,我们建议无论在什么情况下都明确指定基数

var num1 = parseInt("10", 2); //2 (按二进制解析)
var num2 = parseInt("10", 8); //8 (按八进制解析)
var num3 = parseInt("10", 10); //10 (按十进制解析)
var num4 = parseInt("10", 16); //16 (按十六进制解析)

与 parseInt()函数类似,parseFloat()也是从第一个字符(位置 0)开始解析每个字符。而且也是一直解析到字符串末尾,或者解析到遇见一个无效的浮点数字字符为止。

除了第一个小数点有效之外,parseFloat()与 parseInt()的第二个区别在于它始终都会忽略前导的零。parseFloat()可以识别前面讨论过的所有浮点数值格式,也包括十进制整数格式。但十六进制格式的字符串则始终会被转换成 0。由于 parseFloat()只解析十进制值,因此它没有用第二个参数指定基数的用法

var num1 = parseFloat("1234blue"); //1234 (整数)
var num2 = parseFloat("0xA"); //0 
var num3 = parseFloat("22.5"); //22.5 
var num4 = parseFloat("22.34.5"); //22.34 
var num5 = parseFloat("0908.5"); //908.5 
var num6 = parseFloat("3.125e7"); //31250000

3.4.6 String类型

String 类型用于表示由零或多个 16 位 Unicode 字符组成的字符序列,即字符串。

1. 字符字面量

String 数据类型包含一些特殊的字符字面量,也叫转义序列,用于表示非打印字符,或者具有其他用途的字符。

字面量含义
\n换行
\t制表
\b空格
\r回车
\f进纸
\斜杠
'单引号('),在用单引号表示的字符串中使用。例如:'He said, 'hey.''
"双引号("),在用双引号表示的字符串中使用。例如:"He said, "hey.""
\xnn以十六进制代码nn表示的一个字符(其中n为0~F)。例如,\x41表示"A"
\unnnn以十六进制代码nnnn表示的一个Unicode字符(其中n为0~F)。例如,\u03a3表示希腊字符Σ

这些字符字面量可以出现在字符串中的任意位置,而且也将被作为一个字符来解析。

2. 字符串的特点

字符串一旦创建,它们的值就不能改变。

3. 转换为字符串

toString()方法

数值、布尔值、对象和字符串值(没错,每个字符串也都有一个 toString()方法,该方法返回字符串的一个副本)都有 toString()方法。但 null 和 undefined 值没有这个方法。

在调用数值的 toString()方法时,可以传递一个参数:输出数值的基数。

var num = 10; 
alert(num.toString()); // "10" 
alert(num.toString(2)); // "1010" 
alert(num.toString(8)); // "12" 
alert(num.toString(10)); // "10" 
alert(num.toString(16)); // "a"

String()方法

在不知道要转换的值是不是 null 或 undefined 的情况下,还可以使用转型函数 String(),这个函数能够将任何类型的值转换为字符串。String()函数遵循下列转换规则:

(1)如果值有 toString()方法,则调用该方法(没有参数)并返回相应的结果;

(2) 如果值是 null,则返回"null";

(3) 如果值是 undefined,则返回"undefined"。

要把某个值转换为字符串,可以使用加号操作符把它与一个字符串("")加在一起。

###3.4.7 Object类型

ECMAScript 中的对象其实就是一组数据和功能的集合。对象可以通过执行 new 操作符后跟要创建的对象类型的名称来创建。而创建 Object 类型的实例并为其添加属性和(或)方法,就可以创建自定义对象,如下所示:

var o = new Object();

Object 类型是所有它的实例的基础。换句话说,Object 类型所具有的任何属性和方法也同样存在于更具体的对象中。

Object 的每个实例都具有下列属性和方法。
constructor:保存着用于创建当前对象的函数。对于前面的例子而言,构造函数(constructor)就是 Object()。 hasOwnProperty(propertyName):用于检查给定的属性在当前对象实例中(而不是在实例的原型中)是否存在。其中,作为参数的属性名(propertyName)必须以字符串形式指定(例如:o.hasOwnProperty("name"))。
isPrototypeOf(object):用于检查传入的对象是否是传入对象的原型(第 5 章将讨论原型)。
propertyIsEnumerable(propertyName):用于检查给定的属性是否能够使用 for-in 语句(本章后面将会讨论)来枚举。与 hasOwnProperty()方法一样,作为参数的属性名必须以字符串形式指定。
toLocaleString():返回对象的字符串表示,该字符串与执行环境的地区对应。
toString():返回对象的字符串表示。
valueOf():返回对象的字符串、数值或布尔值表示。通常与 toString()方法的返回值相同。

3.5 操作符

3.5.1 一元操作符

只能操作一个值的操作符叫做一元操作符。

1. 递增和递减操作符

执行前置递增和递减操作时,变量的值都是在语句被求值以前改变的。

var age = 29; 
var anotherAge = --age + 2; 
alert(age); // 输出 28 
alert(anotherAge); // 输出 30

后置递增和递减与前置递增和递减有一个非常重要的区别,即递增和递减操作是在包含它们的语句被求值之后才执行的。

var num1 = 2; 
var num2 = 20; 
var num3 = num1-- + num2; // 等于 22 
var num4 = num1 + num2; // 等于 21

这 4 个操作符对任何值都适用,也就是它们不仅适用于整数,还可以用于字符串、布尔值、浮点数值和对象。在应用于不同的值时,递增和递减操作符遵循下列规则。

(1)在应用于一个包含有效数字字符的字符串时,先将其转换为数字值,再执行加减 1 的操作。字符串变量变成数值变量。
(2)在应用于一个不包含有效数字字符的字符串时,将变量的值设置为 NaN(第 4 章将详细讨论)。字符串变量变成数值变量。
(3)在应用于布尔值 false 时,先将其转换为 0 再执行加减 1 的操作。布尔值变量变成数值变量。
(4)在应用于布尔值 true 时,先将其转换为 1 再执行加减 1 的操作。布尔值变量变成数值变量。
(5)在应用于浮点数值时,执行加减 1 的操作。
(6)在应用于对象时,先调用对象的 valueOf()方法(第 5 章将详细讨论)以取得一个可供操作的值。然后对该值应用前述规则。如果结果是 NaN,则在调用 toString()方法后再应用前述规则。对象变量变成数值变量。
var s1 = "2"; 
var s2 = "z"; 
var b = false; 
var f = 1.1; 
var o = { 
 valueOf: function() { 
 return -1; 
 } 
}; 
s1++; // 值变成数值 3 
s2++; // 值变成 NaN 
b++; // 值变成数值 1 
f--; // 值变成 0.10000000000000009(由于浮点舍入错误所致)
o--; // 值变成数值-2

2. 一元加和减操作符

主要用于基本的算术运算,也可以用于转换数据类型

在对非数值应用一元加操作符时,该操作符会像 Number()转型函数一样对这个值执行转换

var s1 = "01"; 
var s2 = "1.1"; 
var s3 = "z"; 
var b = false; 
var f = 1.1; 
var o = { 
 valueOf: function() { 
 return -1; 
 } 
}; 
s1 = +s1; // 值变成数值 1 
s2 = +s2; // 值变成数值 1.1 
s3 = +s3; // 值变成 NaN 
b = +b; // 值变成数值 0 
f = +f; // 值未变,仍然是 1.1 
o = +o; // 值变成数值-1

在将一元减操作符应用于数值时,该值会变成负数。而当应用于非数值时,一元减操作符遵循与一元加操作符相同的规则,最后再将得到的数值转换为负数.

var s1 = "01"; 
var s2 = "1.1"; 
var s3 = "z"; 
var b = false; 
var f = 1.1; 
var o = { 
 valueOf: function() { 
 return -1; 
 } 
}; 
s1 = -s1; // 值变成了数值-1 
s2 = -s2; // 值变成了数值-1.1 
s3 = -s3; // 值变成了 NaN 
b = -b; // 值变成了数值 0 
f = -f; // 变成了-1.1 
o = -o; // 值变成了数值 1

3.5.2 位操作符

1. 按位非

按位非操作符由一个波浪线(~)表示,执行按位非的结果就是返回数值的反码。

var num1 = 25; // 二进制 00000000000000000000000000011001 
var num2 = ~num1; // 二进制 11111111111111111111111111100110 
alert(num2); // -26

2. 按位与

按位与操作符由一个和号字符(&)表示,它有两个操作符数。

25 = 0000 0000 0000 0000 0000 0000 0001 1001 
3 = 0000 0000 0000 0000 0000 0000 0000 0011 
 --------------------------------------------- 
 AND = 0000 0000 0000 0000 0000 0000 0000 0001

3. 按位或

按位或操作符由一个竖线符号(|)表示,同样也有两个操作数。

25 = 0000 0000 0000 0000 0000 0000 0001 1001 
3 = 0000 0000 0000 0000 0000 0000 0000 0011 
-------------------------------------------- 
OR = 0000 0000 0000 0000 0000 0000 0001 1011

4. 按位异或

按位异或操作符由一个插入符号(^)表示,也有两个操作数。

25 = 0000 0000 0000 0000 0000 0000 0001 1001 
3 = 0000 0000 0000 0000 0000 0000 0000 0011 
 --------------------------------------------- 
 XOR = 0000 0000 0000 0000 0000 0000 0001 1010

5. 左移

左移操作符由两个小于号(<<)表示,这个操作符会将数值的所有位向左移动指定的位数。

var oldValue = 2; // 等于二进制的 10 
var newValue = oldValue << 5; // 等于二进制的 1000000,十进制的 64

####6. 有符号的右移

有符号的右移操作符由两个大于号(>>)表示,这个操作符会将数值向右移动,但保留符号位(即正负号标记)。有符号的右移操作与左移操作恰好相反,即如果将 64 向右移动 5 位,结果将变回 2:

var oldValue = 64; // 等于二进制的 1000000 
var newValue = oldValue >> 5; // 等于二进制的 10 ,即十进制的 2

7. 无符号右移

无符号右移操作符由 3 个大于号(>>>)表示,这个操作符会将数值的所有 32 位都向右移动。对正数来说,无符号右移的结果与有符号右移相同。仍以前面有符号右移的代码为例,如果将 64 无符号右移 5 位,结果仍然还是 2:

var oldValue = 64; // 等于二进制的 1000000 
var newValue = oldValue >>> 5; // 等于二进制的 10 ,即十进制的 2

var oldValue = -64; // 等于二进制的 11111111111111111111111111000000 
var newValue = oldValue >>> 5; // 等于十进制的 134217726

3.5.3 布尔操作符

布尔操作符一共有 3 个:非(NOT)、与(AND)和或(OR)。

1. 逻辑非

逻辑非操作符由一个叹号(!)表示,可以应用于 ECMAScript 中的任何值。逻辑非操作符首先会将它的操作数转换为一个布尔值,然后再对其求反。

alert(!false); // true 
alert(!"blue"); // false 
alert(!0); // true 
alert(!NaN); // true 
alert(!""); // true 
alert(!12345); // false

同时使用两个逻辑非操作符,实际上就会模拟 Boolean()转型函数的行为。其中,第一个逻辑非操作会基于无论什么操作数返回一个布尔值,而第二个逻辑非操作则对该布尔值求反,于是就得到了这个值真正对应的布尔值。

alert(!!"blue"); //true 
alert(!!0); //false 
alert(!!NaN); //false 
alert(!!""); //false 
alert(!!12345); //true

2. 逻辑与

逻辑与操作符由两个和号(&&)表示,有两个操作数。

逻辑与操作可以应用于任何类型的操作数,而不仅仅是布尔值。在有一个操作数不是布尔值的情况下,逻辑与操作就不一定返回布尔值;此时,它遵循下列规则:

 如果第一个操作数是对象,则返回第二个操作数;
 如果第二个操作数是对象,则只有在第一个操作数的求值结果为 true 的情况下才会返回该对象;
 如果两个操作数都是对象,则返回第二个操作数;
 如果有一个操作数是 null,则返回 null;  如果有一个操作数是 NaN,则返回 NaN;  如果有一个操作数是 undefined,则返回 undefined。

3. 逻辑或

逻辑或操作符由两个竖线符号(||)表示,有两个操作数。

与逻辑与操作相似,如果有一个操作数不是布尔值,逻辑或也不一定返回布尔值;此时,它遵循下列规则:

 如果第一个操作数是对象,则返回第一个操作数;
 如果第一个操作数的求值结果为 false,则返回第二个操作数;
 如果两个操作数都是对象,则返回第一个操作数;
 如果两个操作数都是 null,则返回 null;  如果两个操作数都是 NaN,则返回 NaN;  如果两个操作数都是 undefined,则返回 undefined。

3.5.4 乘性操作符

1. 乘法

在处理特殊值的情况下,乘法操作符遵循下列特殊的规则:
 如果操作数都是数值,执行常规的乘法计算,即两个正数或两个负数相乘的结果还是正数,而如果只有一个操作数有符号,那么结果就是负数。如果乘积超过了 ECMAScript 数值的表示范围,则返回 Infinity 或-Infinity;
 如果有一个操作数是 NaN,则结果是 NaN; 
 如果是 Infinity 与 0 相乘,则结果是 NaN;  如果是 Infinity 与非 0 数值相乘,则结果是 Infinity 或-Infinity,取决于有符号操作数的符号;
 如果是 Infinity 与 Infinity 相乘,则结果是 Infinity;  如果有一个操作数不是数值,则在后台调用Number()将其转换为数值,然后再应用上面的规则。

2. 除法

 如果操作数都是数值,执行常规的除法计算,即两个正数或两个负数相除的结果还是正数,而如果只有一个操作数有符号,那么结果就是负数。如果商超过了 ECMAScript 数值的表示范围,则返回 Infinity 或-Infinity;
 如果有一个操作数是 NaN,则结果是 NaN;
 如果是 Infinity 被 Infinity 除,则结果是 NaN;
 如果是零被零除,则结果是 NaN; 
 如果是非零的有限数被零除,则结果是 Infinity 或-Infinity,取决于有符号操作数的符号;
 如果是 Infinity 被任何非零数值除,则结果是 Infinity 或-Infinity,取决于有符号操作数的符号;
 如果有一个操作数不是数值,则在后台调用 Number()将其转换为数值,然后再应用上面的规则.

3. 求模

 如果操作数都是数值,执行常规的除法计算,返回除得的余数;
 如果被除数是无穷大值而除数是有限大的数值,则结果是 NaN;
 如果被除数是有限大的数值而除数是零,则结果是 NaN;
 如果是 Infinity 被 Infinity 除,则结果是 NaN;
 如果被除数是有限大的数值而除数是无穷大的数值,则结果是被除数;
 如果被除数是零,则结果是零;
 如果有一个操作数不是数值,则在后台调用 Number()将其转换为数值,然后再应用上面的规则。

3.5.5 加性操作符

1. 加法

如果两个操作符都是数值,执行常规的加法计算,然后根据下列规则返回结果:
 如果有一个操作数是 NaN,则结果是 NaN;
 如果是 Infinity 加 Infinity,则结果是 Infinity;
 如果是-Infinity 加-Infinity,则结果是-Infinity;
 如果是 Infinity 加-Infinity,则结果是 NaN; 
 如果是+0 加+0,则结果是+0;
 如果是-0 加-0,则结果是-0;
 如果是+0 加-0,则结果是+0。
不过,如果有一个操作数是字符串,那么就要应用如下规则:
 如果两个操作数都是字符串,则将第二个操作数与第一个操作数拼接起来;
 如果只有一个操作数是字符串,则将另一个操作数转换为字符串,然后再将两个字符串拼接起来。

var result1 = 5 + 5; // 两个数值相加
alert(result1); // 10

var result2 = 5 + "5"; // 一个数值和一个字符串相加
alert(result2); // "55"

var num1 = 5; 
var num2 = 10; 
var message = "The sum of 5 and 10 is " + num1 + num2; 
alert(message); // "The sum of 5 and 10 is 510"

2. 减法

 如果两个操作符都是数值,则执行常规的算术减法操作并返回结果;
 如果有一个操作数是 NaN,则结果是 NaN;
 如果是 Infinity 减 Infinity,则结果是 NaN;
 如果是-Infinity 减-Infinity,则结果是 NaN;
 如果是 Infinity 减-Infinity,则结果是 Infinity;
 如果是-Infinity 减 Infinity,则结果是-Infinity; 
 如果是+0 减+0,则结果是+0; 
 如果是+0 减-0,则结果是-0;
 如果是-0 减-0,则结果是+0;
 如果有一个操作数是字符串、布尔值、null 或 undefined,则先在后台调用 Number()函数将其转换为数值,然后再根据前面的规则执行减法计算。如果转换的结果是 NaN,则减法的结果就是 NaN;
 如果有一个操作数是对象,则调用对象的 valueOf()方法以取得表示该对象的数值。如果得到的值是 NaN,则减法的结果就是 NaN。如果对象没有 valueOf()方法,则调用其 toString()方法并将得到的字符串转换为数值。
var result1 = 5 - true; // 4,因为 true 被转换成了 1 
var result2 = NaN - 1; // NaN 
var result3 = 5 - 3; // 2 
var result4 = 5 - ""; // 5,因为"" 被转换成了 0 
var result5 = 5 - "2"; // 3,因为"2"被转换成了 2 
var result6 = 5 - null; // 5,因为 null 被转换成了 0

3.5.6 关系操作符

与 ECMAScript 中的其他操作符一样,当关系操作符的操作数使用了非数值时,也要进行数据转换或完成某些奇怪的操作。以下就是相应的规则。

 如果两个操作数都是数值,则执行数值比较。
 如果两个操作数都是字符串,则比较两个字符串对应的字符编码值。
 如果一个操作数是数值,则将另一个操作数转换为一个数值,然后执行数值比较。
 如果一个操作数是对象,则调用这个对象的 valueOf()方法,用得到的结果按照前面的规则执行比较。如果对象没有 valueOf()方法,则调用 toString()方法,并用得到的结果根据前面的规则执行比较。
 如果一个操作数是布尔值,则先将其转换为数值,然后再执行比较。

3.5.7 相等操作符

1. 相等和不相等

这两个操作符都会先转换操作数(通常称为强制转型),然后再比较它们的相等性。

 如果有一个操作数是布尔值,则在比较相等性之前先将其转换为数值——false 转换为 0,而true 转换为 1;
 如果一个操作数是字符串,另一个操作数是数值,在比较相等性之前先将字符串转换为数值;
 如果一个操作数是对象,另一个操作数不是,则调用对象的 valueOf()方法,用得到的基本类型值按照前面的规则进行比较;这两个操作符在进行比较时则要遵循下列规则。
 null 和 undefined 是相等的。
 要比较相等性之前,不能将 null 和 undefined 转换成其他任何值。
 如果有一个操作数是 NaN,则相等操作符返回 false,而不相等操作符返回 true。重要提示:即使两个操作数都是 NaN,相等操作符也返回 false;因为按照规则,NaN 不等于 NaN。
 如果两个操作数都是对象,则比较它们是不是同一个对象。如果两个操作数都指向同一个对象,则相等操作符返回 true;否则,返回 false。

2. 全等和不全等

它只在两个操作数未经转换就相等的情况下返回 true。

3.5.8 条件操作符

variable = boolean_expression ? true_value : false_value;

3.5.9 赋值操作符

简单的赋值操作符由等于号(=)表示,其作用就是把右侧的值赋给左侧的变量。

3.5.10 逗号操作符

3.6 语句

3.6.1 if语句

if (condition) statement1 else statement2

3.6.2 do-while语句

do-while 语句是一种后测试循环语句,即只有在循环体中的代码执行之后,才会测试出口条件。换句话说,在对条件表达式求值之前,循环体内的代码至少会被执行一次。

3.6.3 while语句

while 语句属于前测试循环语句,也就是说,在循环体内的代码被执行之前,就会对出口条件求值。因此,循环体内的代码有可能永远不会被执行。

3.6.4 for语句

for 语句也是一种前测试循环语句,但它具有在执行循环之前初始化变量和定义循环后要执行的代码的能力。

for (initialization; expression; post-loop-expression) statement
在 for 循环的变量初始化表达式中,也可以不使用 var 关键字。该变量的初始化可以在外部执行,例如:
var count = 10; 
var i; 
for (i = 0; i < count; i++){ 
 alert(i); 
}

由于 ECMAScript 中不存在块级作用域,因此在循环内部定义的变量也可以在外部访问到.

var count = 10; 
for (var i = 0; i < count; i++){
 alert(i); 
} 
alert(i); //10

3.6.5 for-in语句

for-in 语句是一种精准的迭代语句,可以用来枚举对象的属性。

如果表示要迭代的对象的变量值为 null 或 undefined,for-in 语句会抛出错误。ECMAScript 5 更正了这一行为;对这种情况不再抛出错误,而只是不执行循环体。为了保证最大限度的兼容性,建议在使用 for-in 循环之前,先检测确认该对象的值不是 null 或 undefined。

3.6.6 label语句

使用 label 语句可以在代码中添加标签,以便将来使用。

start: for (var i=0; i < count; i++) { 
 alert(i); 
} 
这个例子中定义的 start 标签可以在将来由 break 或 continue 语句引用。加标签的语句一般都要与 for 语句等循环语句配合使用。

3.6.7 break和continue语句

break 和 continue 语句用于在循环中精确地控制代码的执行。其中,break 语句会立即退出循环,强制继续执行循环后面的语句。而 continue 语句虽然也是立即退出循环,但退出循环后会从循环的顶部继续执行。

3.6.8 with语句

with 语句的作用是将代码的作用域设置到一个特定的对象中。

由于大量使用 with 语句会导致性能下降,同时也会给调试代码造成困难,因此在开发大型应用程序时,不建议使用 with 语句。

3.6.9 switch语句

switch 语句与 if 语句的关系最为密切,而且也是在其他语言中普遍使用的一种流控制语句。

switch 语句中的每一种情形(case)的含义是:“如果表达式等于这个值(value),则执行后面的语句(statement)”。而 break 关键字会导致代码执行流跳出 switch 语句。如果省略 break 关键字,就会导致执行完当前 case 后,继续执行下一个 case。最后的 default 关键字则用于在表达式不匹配前面任何一种情形的时候,执行机动代码(因此,也相当于一个 else 语句)。

可以在switch 语句中使用任何数据类型(在很多其他语言中只能使用数值),无论是字符串,还是对象都没有问题。其次,每个 case 的值不一定是常量,可以是变量,甚至是表达式。

switch 语句在比较值时使用的是全等操作符,因此不会发生类型转换。

3.7 函数

ECMAScript 中的函数使用 function 关键字来声明,后跟一组参数以及函数体。

位于 return 语句之后的任何代码都永远不会执行。

function sum(num1, num2) { 
 return num1 + num2; 
 alert("Hello world"); // 永远不会执行
}

return 语句也可以不带有任何返回值。在这种情况下,函数在停止执行后将返回 undefined值。这种用法一般用在需要提前停止函数执行而又不需要返回值的情况下。

function sayHi(name, message) { 
 return; 
 alert("Hello " + name + "," + message); //永远不会调用
}

3.7.1 理解参数

ECMAScript 中的参数在内部是用一个数组来表示的。

函数接收到的始终都是这个数组,而不关心数组中包含哪些参数(如果有参数的话)。如果这个数组中不包含任何元素,无所谓;如果包含多个元素,也没有问题。实际上,在函数体内可以通过 arguments 对象来访问这个参数数组,从而获取传递给函数的每一个参数。

命名的参数只提供便利,但不是必需的。

是 arguments 对象可以与命名参数一起使用

3.7.2 没有重载

如果在 ECMAScript 中定义了两个名字相同的函数,则该名字只属于后定义的函数。

3.8 总结

 ECMAScript 中的基本数据类型包括 Undefined、Null、Boolean、Number 和 String。

 与其他语言不同,ECMScript 没有为整数和浮点数值分别定义不同的数据类型,Number 类型可用于表示所有数值。

 ECMAScript 中也有一种复杂的数据类型,即 Object 类型,该类型是这门语言中所有对象的基础类型。

 严格模式为这门语言中容易出错的地方施加了限制。

 ECMAScript 提供了很多与 C 及其他类 C 语言中相同的基本操作符,包括算术操作符、布尔操作符、关系操作符、相等操作符及赋值操作符等。

 ECMAScript 从其他语言中借鉴了很多流控制语句,例如 if 语句、for 语句和 switch 语句等。ECMAScript 中的函数与其他语言中的函数有诸多不同之处。

 无须指定函数的返回值,因为任何 ECMAScript 函数都可以在任何时候返回任何值。

 实际上,未指定返回值的函数返回的是一个特殊的 undefined 值。

 ECMAScript 中也没有函数签名的概念,因为其函数参数是以一个包含零或多个值的数组的形式传递的。

 可以向 ECMAScript 函数传递任意数量的参数,并且可以通过 arguments 对象来访问这些参数。

 由于不存在函数签名的特性,ECMAScript 函数不能重载。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
JavaScript高级程序设计(第3版)》是一本权威的JavaScript编程指南,涵盖了JavaScript语言的各个方面和高级特性。本书由Nicholas C. Zakas撰写,是一位知名的JavaScript专家和作者。 该书详细介绍了JavaScript的基本语法、数据类型、控制流程等基础知识,并深入探讨了函数、对象、正则表达式等高级特性。此外,本书还介绍了DOM操作、事件处理、Ajax、JSON等Web开发相关的内容。读者可以通过学习本书,系统地掌握JavaScript的各个方面,从而能够编写出可维护、高效、优雅的JavaScript代码。 《JavaScript高级程序设计(第3版)》以清晰、易懂的语言讲解了复杂的概念,并配有丰富的示例代码和实际案例,帮助读者理解和应用所学知识。本书不仅适合初学者,也适合有一定JavaScript基础的开发者作为参考手册使用。 随着Web技术的快速发展,JavaScript已经成为构建现代Web应用的重要工具之一。《JavaScript高级程序设计(第3版)》为读者提供了全面、深入的学习和理解JavaScript的资源。无论是对于Web开发者还是对于想要了解JavaScript的任何人来说,这本书都是一本不可或缺的经典之作。 总之,《JavaScript高级程序设计(第3版)》是一本内容丰富、权威性强的JavaScript编程指南,它深入讲解了JavaScript的各个方面和高级特性,对于理解和应用JavaScript具有很高的参考价值。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值