我最近开始看这本书,内容比较详细,很难全部记住
因此我将书中知识点记录下来,以便日后查阅
第1章 JavaScript简介
1.1 JavaScript 简史
1.2 JavaScript 实现
1.2.1 核心(ECMAScript)
1.2.2 文档对象模型(DOM)
1.2.3 浏览器对象模型(BOM)
1.3 JavaScript 版本
1.4 小结
- JavaScript是一种专为与网页交互而设计的脚本语言,由三个不同部分组成:
- ECMAScript,由ECMA-262定义,提供核心语言功能
- 文档对象模型(DOM),提供访问和操作网页内容的方法和接口
- 浏览器对象模型(BOM),提供与浏览器交互的方法和接口
第2章 在 HTML 中使用 JavaScript
2.1 ”字符串,可使用转义字符“”:alert("< /script>");
包含外部 JavaScript 文件- scr 属性是必须的
- 带有 src 属性的之间包含额外的JavaScript代码(会被忽略)
- src 属性可指向当前 HTML 页面所在域之外的某个域中的完整 URL
- 只要不存在 defer 和 async 属性,浏览器都会按照
2.1.1 标签的位置
- 为了避免页面出现时的延迟,现代Web应用程序一般都把全部 JavaScript 引用放在元素中页面内容的后面
2.1.2 延迟脚本
- defer 只适用于外部脚本文件
- 设置defer属性,相当于告诉浏览器立即下载,但延迟执行,包含的脚本将延迟到浏览器遇到标签后再执行
- HTML5规范要求脚本按照出现的先后顺序执行:第一个延迟脚本将会先于第二个延迟脚本执行,而这两个脚本会先于 DOMContentLoaded 事件(详见第13章)
- 现实中延迟脚本并不一定会按照顺序执行,也不一定会在 DOMContentLoaded 事件触发之前执行,因此最好只包含一个延迟脚本
- 把延迟脚本放在页面顶部仍是最佳选择
2.1.3 异步脚本
- async 只适用于外部脚本文件
- 告诉浏览器立即下载文件,目的是不让页面等待两个脚本下载和执行,从而异步加载页面的其他内容
- 标记为 async 的脚本并不保证按照指定它们的先后顺序执行,要确保互不依赖
- 异步脚本一定会在 load 事件之前执行,但与 DOMContentLoaded 事件不一定
2.1.4 在 XHTML 中的用法
2.2 嵌入代码与外部文件
- 最好的做法还是尽可能使用外部文件来包含JavaScript代码:
- 可维护性
- 可缓存:加快页面加载速度
- 适应未来
2.3 文档模式
- 通过使用文档类型(doctype)切换来实现
- 最初的两种文档模式:
- 混杂模式
- 标准模式
- 如果在文档开始处没有发现文档类型声明,则所有浏览器都会默认开启混杂模式(混杂模式下不同浏览器差异大,不推荐)
2.4 <noscript> 元素
- 用来在不支持 JavaScript 的浏览器中显示替代内容:
- 浏览器不支持脚本
- 浏览器支持脚本,但脚本被禁用
第3章 基本概念
3.1 语法
3.1.1 区分大小写
- ECMAScript中的一切都区分大小写
3.1.2 标识符
- 所谓标识符就是指变量、函数、属性的名字、函数的参数
- 第一个字符必须是一个字母、下划线( _ ) 或一个美元符号( $ )
- 其他字符可以是字母、下划线、美元符号或数字
- 标识符采用驼峰大小写格式
- 不能把关键字、保留字、true、false和null用作标识符
注释
- 使用 C 风格的注释,包括单行注释和块级注释
- //单行注释
- /*
- *多行(块级)注释
- *(以星号开头可提高注释的可读性,但不是必须的)
- */
3.1.4 严格模式
- 对某些不安全的操作会抛出错误
- 在整个脚本中,可在顶部添加如下代码启用严格模式:
- "use strict";
- 这行代码时编译指示,告诉JavaScript引擎切换到严格模式
- 在函数内部上方包含这条指示,可指定函数在严格模式下执行
- 严格模式下JavaScript的执行结果会有很大不同
3.1.5 语句
- 以分号结尾(增进代码性能)
- 若省略分号,则由解析器确定语句的结尾(有效但不推荐)
- 可以把多条语句组合到一个代码块中(用{ }包含起来)
- 条件控制语句(如if语句)最好始终在控制语句中使用代码块
3.2 关键字和保留字
3.3 变量
- ECMAScript 的变量是松散型的,可以用来保存任何类型的数据(每个变量仅仅是一个用于保存值的占位符而已)
- 可以在修改变量值的同时修改值的类型(有效但不推荐)
- 定义变量使用 var 操作符
- 支持直接初始化变量如 var a = "hi";
- 未经初始化的变量会保存一个特殊值——undefined
- 如果在函数中用 var 定义一个变量,这个变量在函数退出后就会被销毁
- 可以省略 var 操作符来创建一个全局变量(在局部作用域中定义的全局变量难以维护,不推荐)
- 可以用一条语句定义多个变量,用逗号分隔开
- 可以使用一条语句完成不同类型初始化变量的操作)
- 严格模式下,不能定义名为 eval 或 arguments 的变量,否则会导致语法错误
3.4 数据类型
- 5种简单数据类型(基本数据类型):
- Undefineded
- Null
- Boolean
- Number
- String
- 1种复杂数据类型:Object
- Object本质上是由一组无序的名值对组成的
- 不支持任何创建自定义类型的机制
3.4.1 typeof 操作符
- 检测给定变量的数据类型
- "undefined":值未定义
- "boolean":值是布尔值
- "string":值是字符串
- "number":值是数值
- "object":值是对象或null
- 特殊值null会被认为是一个空的对象引用
- "function":值是函数
- 从技术角度讲,函数是对象,不是数据类型,但有必要区分函数和其他对象
- 操作数可以是变量,也可以是数值字面量
- typeof 是一个操作符而不是函数,圆括号可以使用但不是必需的
3.4.2 Undefined 类型
- Undefined类型只有一个值:特殊的undefined
- 在使用 var 声明变量但未初始化时,这个变量的值就是undefined
- 引入这个值是为了正式区分空对象指针与未经初始化的变量
- 包含undefined值的变量与未定义的变量是不一样的
- 对于未声明的变量只能执行一项操作:typeof(会返回undefined值)
3.4.3 Null 类型
- Null类型只有一个值:特殊的null
- 从逻辑角度看,null值表示一个空对象指针(因此用typeof检测null值会返回"object")
- 只要意在保存对象的变量还没有真正保存对象,就要明确地让该变量保存null值,只要直接检查null值就可以知道相应的变量是否已经保存了一个对象的引用
- undefined值是派生自null值的,因此规定对它们的相等性测试要返回true
3.4.4 Boolean 类型
- 只有两个字面值:true和false
- 与数字值不是一回事,true不一定等于1,false不一定等于0
- true和false区分大小写
- 所有类型的值都有与这两个Boolean值等价的值
- 要将一个值转换为其对应的Boolean值,可以调用转型函数 Boolean()
数据类型 | 转换为true的值 | 转换为false的值 |
---|---|---|
Boolean | true | false |
String | 任何非空字符串 | " "(空字符串) |
Number | 任何非零数值(包括无穷大) | 0和null |
Object | 任何对象 | null |
Undefined | n/a(或N/A) | undefined |
- n/a(或N/A)是 not applicable 的缩写,意识是“不适用”
3.4.5 Number 类型
- 十进制整数可以直接在代码中输入
- 八进制字面值第一位必须是0,然后是八进制数字序列0~7
- 如果字面值中的数值超出了范围,则前导0回被忽略,后面的数值被当作十进制数值解析
- 八进制字面量在严格模式下是无效的
- 十六进制字面值前两位必须是0x,后跟十六进制数字( 0~9 及 A~F )
- 字母A~F可以大写也可以小写
- 在进行算术计算时,所有数值最终将被转换为十进制数值
- 可以保存正零(+0)和负零(-0),二者相等
浮点数值
- 小数点前面可以没有整数,但不推荐这种做法
- 浮点数值所占内存空间时整数的两倍,因此如果小数点后面没有跟任何数字(如1.)或浮点数值本身就是一个整数(如1.0),这个数值就会作为整数值来保存
- 对于极大或极小的数值,可以用e(或E)表示法(科学记数法)表示的浮点数值表示
- 3.125e7实际含义就是 "3.125*107"
- 默认情况下,ECMAScript会将小数点后面带6个零以上的浮点数值转换为以e表示法表示的数值
- 浮点数值最高精度是17位小数,但在进行算术计算时其精确度远远不如整数
- 如0.1 + 0.2的结果是0.30000000000000004
- 永远不要测试某个特定的浮点数值
数值范围
- ECMASript能够表示的最小数值保存在 Number.MIN_VALUE 中,能够表示的最大数值保存在 Number.MAX_VALUE 中
- 得到的超出数值范围的值将会被自动转换成特殊的 Infinity 值
- 正数转换为 Infinity,负数转换为 -Infinity
- Infinity不能够参与计算
- 想确定一个数值是否是有穷的可以使用isFinity()函数
- 参数有穷时会返回true
- Number.NEGATIVE_INFINITY 和 Number.POSITIVE_INFINITY 分别保存着 -Infinity 和 Infinity
NaN
- 即非数值(Not a Number),是一个特殊的数值
- 用于表示一个本来要返回数值的操作数未返回数值的情况(这样就不会抛出错误)
- 任何涉及NaN的操作(如NaN/10)都会返回NaN
- NaN与任何值都不相等,包括NaN本身
- isNaN()函数能确定参数是否“不是数值”,任何不能转换为数值的值都会导致这个函数返回true
- Boolean值可以转换为数值
- isNaN()也适用于对象,详见3.5节
数值转换
- Number()
- 适用于任何数据类型
- 转换规则如下:
- Boolean值,true和false分别转换为1和0
- 数字值,只是简单的传入和返回
- null值,返回0
- undefined,返回NaN
- 字符串,遵循下列规则
- 只包含数字(包括带正负号的情况),则转换为十进制数(会忽略前导0)
- 包含有效的浮点格式,则转换为对应的浮点数值(也会忽略前导0)
- 包含有效的十六进制格式,则转换为相同大小的十进制整数值
- 空字符串,则转换为0
- 包含上述格式之外的字符,则转换为NaN
- 对象,则调用对象的valueOf( )方法,然后依照前面的规则转换返回的值。若转换结果是NaN,则调用对象的toString( )方法,然后再次依照前面的规则转换返回的字符串值
- parseInt()
- 专门用于把字符串转换成数值
- 会忽略字符串前面的空格,直到找到第一个非空格字符
- 如果第一个字符不是数字字符或者负号,就会返回NaN
- 也就是说转换空字符串会返回NaN
- 如果第一个字符是数字字符,会继续解析第二个字符,直到解析完所有后续字符或遇到非数字字符
- 如 "1234blue" 转换为1234; "22.5" 转换为22
- 如果第一个字符不是数字字符或者负号,就会返回NaN
- 能够识别出各种整数格式
- 以 "0x" 开头会当作十六进制整数
- 以 "0" 开头且后跟数字字符会当作八进制整数
- 可以提供第二个参数:转换时使用的基数(即多少进制)
- 如parseInt("0xAF", 16); //175
- 实际上指定了16作为第二个参数,可以省略 "0x"
- 为避免出错,建议任何情况下都明确指定基数
- parseFloat()
- 专门用于把字符串转换成数值
- 字符串中第一个小数点是有效的,而第二个就是无效的了,后面的字符串会被忽略
- 如 "22.34.5" 转换为22.34
- parseInt()只解析十进制值,十六进制格式的字符串会被转换成0
- 若字符串包含的是一个可以解析为整数的数(没有小数点或小数点后都是零),会返回整数
3.4.6 String 类型
- 字符串可以由双引号("")或单引号('')表示,两种形式没有区别
字符字面量
- String 数据类型包含一些特殊的字符字面量,也叫转义序列,用于表示非打印字符,或者具有其他用途的字符
- 多个字符长的转义序列表示一个字符
- 任何字符串的长度都可以通过访问其length属性取得
- 如:alert(text.length);
- 如果字符串中包含双字节字符,则length属性可能不会精确地返回字符串中的字符数目
转换为字符串
- toString( ) 方法
- 数值、布尔值、对象和字符串都有 toString( ) 方法
- null 和 undefined 没有这个方法
- 在调用数值的 toString( ) 方法时可以传递一个参数:输出数值的基数(默认情况下以十进制格式返回数值的字符串表示)
- String( ) 函数
- 在不知道要转换的值是不是 null 或 undefined 的情况下可使用转型函数 String( ),能够将任何类型的值转换为字符串
- 遵循下列转换规则
- 如果值有toString( ) 方法,则调用该方法(没有参数)并返回结果
- 如果值是 "null" 则返回 "null"
- 如果值是 "undefined" 则返回 "undefined"
3.4.7 Object 类型
- ECMAScript中的对象其实就是一组数据和功能的集合,对象可以通过执行 new 操作符后跟要创建的对象类型的名称来创建
- 创建 Object 类型的实例并为其添加属性和(或)方法,就可以创建自定义对象
- 如:var o = new Object ( );
- 可以省略圆括号,但不推荐
- Object 的每个实例都具有下列属性和方法:
- constructor:保存着用于创建当前对象的函数
- hasOwnProperty(propertyName):用于检查给定的属性在当前对象实例中(而不是在实例的原型中)是否存在
- 作为参数的属性名(propertyName)必须以字符串形式指定,例如:o.hasOwnProperty("name");
- isPrototypeOf(object):用于检查传入的对象是否是当前对象的原型(第5章将讨论原型)
- propertyIsEnumerable(propertyName):用于检查给定的属性是否能够使用 for-in 语句来枚举
- 作为参数的属性名必须以字符串形式指定
- toLocaleString( ):返回对象的字符串表示,该字符串与执行环境的地区对应
- toString( ):返回对象的字符串表示
- valueOf( ):返回对象的字符串、数值或布尔值表示,通常与 toString( ) 方法的返回值相同
- 从技术角度讲,ECMA-262中对象的行为不一定适用于JavaScript中的其他对象
3.5 操作符
- ECMA-262 描述了一组用于操作数据值的操作符,包括算术操作符、位操作符、关系操作符和相等操作符
3.5.1 一元操作符
- 只能操作一个值的操作符叫做一元操作符,是最简单的操作符
递增和递减操作符
- 分为前置型和后置型
- 对任何值都适用
- 包含有效数字字符的字符串,先将其转换为数字值,再执行加减1操作。字符串变量变成数值变量
- 不包含有效数字字符的字符串,将变量的值设为NaN。字符串变量变成数值变量
- 布尔值false,先将其转换为0再执行加减1操作。布尔值变量变成数值变量
- 布尔值true,先将其转换为1在执行加减1操作。布尔值变量变成数值变量
- 浮点数值,执行加减1操作
- 对象,先调用对象的 valueOf( ) 方法以取得一个可供操作的值,然后对该值应用前述规则,如果结果是 NaN ,则在调用 toString( ) 方法后再应用前述规则。对象变量变成数值变量
一元加和减操作符
- 一元加操作符
- 一元加操作以一个加号( + )表示,放在数值前面,对数值不会产生任何影响
- 在对非数值应用一元加操作符时,会像Number( )转型函数一样对这个值进行转换
- 一元减操作符
- 一元减操作符应用于数值时,该值会变成负数
- 应用于非数值时,遵循与一元加操作符相同的规则,最后再将得到的数值转换为负数
3.5.2 位操作符
- 用于在最基本的层次上,即按内存中表示数值的位来操作数值
- 对数值应用位操作符时,后台会发生如下转换过程:64位的数值被转换成32位数值,然后执行位操作,最后再将32位的结果转换回64位数值
- 对特殊的 NaN 和 Infinity 值应用位操作时,这两个值都会被当成0来处理
- 对非数值应用位操作符时,会自动使用Number( )函数将该值转换为一个数值,然后再应用位操作。得到的结果将是一个数值
按位非 (NOT)
- 按位非操作符由一个波浪线( ~ )表示,执行结果就是返回数值的反码
- 按位非操作的本质:操作数的负值减1
按位与 (AND)
- 按位与操作符由一个和号字符( & )表示,有两个操作符数
- 从本质上讲,就是将两个数值的每一位对其,对相同位置上两个数执行 AND 操作
按位或 (OR)
- 按位或操作符由一个竖线符号( | )表示,同样也有两个操作数
- 类似按位与操作,对应位置上两个数执行 OR 操作
按位异或 (XOR)
- 按位异或操作符由一个插入符号( ^ )表示,也有两个操作数
- 这个操作在两个数值对应位上只有一个1时才返回1,如果对应的两位都是1或都是0,则返回0
左移
- 左移操作符由两个小于号( << )表示
- 这个操作符会将数值的所有位向左移动指定的位数
- 如将数值2(二进制码为10)向左移动5位,结果是64(二进制码为1000000)
- 代码表示为:2 << 5;
- 左移操作会以0来填充移动产生的空位
- 左移不会影响操作数的符号位
有符号的右移
- 有符号的右移操作符由两个大于号( >> )表示
- 这个操作符会将数值向右移动指定的位数,但保留符号位(即正负号标记)
- 移动产生的空位出现在原数值左侧、符号位右侧,用符号位的值来填充空位
无符号右移
- 无符号右移操作符由三个大于号( >>> )表示
- 这个操作符会将数值的所有32位都向右移动
- 对正数来说,无符号右移与有符号右移相同
- 对负数来说,结果不一样
- 以0来填充空位
3.5.3 布尔操作符
- 布尔操作符共有3个:非( NOT )、与( AND )、或( OR )
逻辑非
- 逻辑非操作符由一个感叹号( ! )表示
- 可以应用于任何值,首先会将操作数转换为一个布尔值,然后再求反
- 对象,返回 false
- 空字符串,返回 true
- 非空字符串,返回 false
- 数值0,返回 true
- 任意非0数值(包括Infinity),返回 false
- null,返回 true
- NaN,返回 true
- undefined,返回 true
- 逻辑非操作符也可以用于将一个值转换为与其对应的布尔值,同时使用两个逻辑非操作符就会模拟Boolean()转型函数的行为,最终结果相同
逻辑与
- 逻辑与操作符由两个和号( && )表示,有两个操作数
- 可以应用于任何类型的操作数,当其中一个操作数不是布尔值的情况下,不一定返回布尔值
- 如果第一个操作数是对象,则返回第二个操作数
- 如果第二个操作数是对象,则只有在第一个操作数的求值结果为 true 的情况下才会返回该对象
- 如果两个操作数都是对象,则返回第二个操作数
- 如果第一个操作数是 null,则返回 null
- 如果第一个操作数是 NaN,则返回 NaN
- 如果第一个操作数是 undefined,则返回 undefined
- 逻辑与操作属于短路操作,即如果第一个操作数是 false,那么就不会再对第二个操作数求值(因此第二个操作数未定义也不会报错)
- 不能在逻辑与操作中使用未定义的值
逻辑或
- 逻辑或操作符由两个竖线符号( || )表示,有两个操作数
- 与逻辑与相似,如果有一个操作数不是布尔值的情况下,不一定返回布尔值
- 如果第一个操作数是对象,则返回第一个操作数
- 如果第一个操作数的求值结果为 false,则返回第二个操作数
- 如果两个操作数都是对象,则返回第一个操作数
- 如果第两个操作数都是 null,则返回 null
- 如果第两个操作数都是 NaN,则返回 NaN
- 如果第两个操作数都是 undefined,则返回 undefined
- 逻辑或操作符也是短路操作符,如果第一个操作数是 true,那么就不会再对第二个操作数求值
- 可以利用逻辑或来避免为变量赋 null 或 undefined 值:
- 例如: var myObject = preferredObject || backupObject;
- 变量 preferredObject 中包含优先赋给变量 myObject 的值,变量 backupObject 负责在 preferredObject 中不包含有效值的情况下提供后备值
3.5.4 乘性操作符
- ECMAScript 定义了三个乘性操作符:乘法、除法和求模
- 操作数为非数值的情况下会执行自动的类型转换
乘法
- 乘法操作符由一个星号( * )表示,用于计算两个数值的乘积
- 在处理特殊值的情况下,遵循下列特殊规则:
- 如果操作数都是数值,执行常规的乘法计算
- 如果有一个操作数是 NaN,则结果是 NaN
- 如果是 Infinity 与 0 相乘,则结果是 NaN
- 如果是 Infinity 与非 0 数值相乘,则结果是 Infinity 或 -Infinity (取决于有符号操作数的符号)
- 如果是 Infinity 与 Infinity 相乘,则结果是 Infinity
- 如果有一个操作数不是数值,则在后台调用 Number( ) 将其转换为数值,再应用以上规则
除法
- 除法操作符由一个斜线符号( / )表示,执行第二个操作数除第一个操作数的计算
- 对特殊值也有特殊的处理规则:
- 如果操作数都是数值,执行常规的除法计算
- 如果有一个操作数是 NaN,则结果是 NaN
- 如果是 Infinity 被 Infinity 除,则结果是 NaN
- 如果是零被零除,则结果是 NaN
- 如果是非零的有限数被零除,则结果是 Infinity 或 -Infinity (取决于有符号操作数的符号)
- 如果是 Infinity 被任何非零数值除,则结果是 Infinity 或 -Infinity (取决于有符号操作数的符号)
- 如果有一个操作数不是数值,则在后台调用 Number( ) 将其转换为数值,再应用以上规则
求模
- 求模(余数)操作符由一个百分号( % )表示
- 对特殊值遵循特殊的处理规则:
- 如果操作数都是数值,执行常规的除法计算,返回除得的余数
- 如果被除数是无穷大值而除数是有限大的数值,则结果是NaN
- 如果被除数是有限大的数值而除数是零,则结果是NaN
- 如果是 Infinity 被 Infinity 除,则结果是NaN
- 如果被除数是有限大的数值而除数是无穷大的数值,则结果是被除数
- 如果被除数是零,则结果是零
- 如果有一个操作数不是数值,则在后台调用 Number( ) 将其转换为数值,然后再应用上面的规则
3.5.5 加性操作符
- 包括加法和减法
- 在 ECMAScipt 中,这两个操作符由一系列特殊行为
加法
- 如果两个操作数都是数值,执行常规的加法计算,然后根据下列规则返回结果:
- 如果有一个操作数是 NaN,则结果是 NaN
- 如果是 Infinity 加 Infinity ,则结果是 Infinity
- 如果是 - Infinity 加 - Infinity ,则结果是 - Infinity
- 如果是 Infinity 加 - Infinity ,则结果是 NaN
- 如果是 +0 加 +0 ,则结果是 +0
- 如果是 -0 加 -0 ,则结果是 -0
- 如果是 +0 加 -0 ,则结果是 +0
- 如果有一个操作数是字符串
- 如果两个操作数都是字符串,则将第二个操作数与第一个操作数拼接起来
- 如果只有一个操作数是字符串, 则将另一个操作数转换为字符串,然后再将两个字符串拼接起来
- 如果有一个操作数是对象、数值或布尔值,则调用它们的 toString( )方法取得相应的字符串值,然后再应用前面关于字符串的规则
- 对于 undefined 和 null ,则分别调用 String( )函数并取得字符串 "undefined" 和 "null"
减法
- 减法操作符同样需要遵守一些特殊规则:
- 如果两个操作符都是数值,则执行常规的算术减法操作并返回结果
- 如果有一个操作数是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( ) 方法并将得到的字符串转换为数值
3.5.6 关系操作符
- 小于 ( < )、大于 ( > )、小于等于 ( <= ) 和大于等于 ( >= )
- 这几个操作符都返回一个布尔值
- 当关系操作符的操作数使用了非数值时,也要进行数据转换或完成某些奇怪的操作
- 如果两个操作数都是数值,则执行数值比较
- 如果两个操作数都是字符串,则比较两个字符串对应的字符编码值
- 如果一个操作数是数值,则将另一个操作数转换为一个数值,然后执行数值比较
- 如果一个操作数是对象,则调用对象的 valueOf ( ) 方法,用得到的结果按照前面的规则执行比较。如果对象没有 valueOf ( ) 方法,则调用其 toString( ) 方法,并用得到的结果按照前面的规则执行比较
- 如果一个操作数是布尔值,则先将其转化为数值,然后再执行比较
- 任何操作数与 NaN 进行比较,结果都是 false
3.5.7 相等操作符
- 两组操作符
- 相等和不相等————先转换再比较
- 全等和不全等————仅比较而不转换
相等和不相等
- 相等操作符由两个等于号( == )表示,不相等由感叹号后跟等于号( != )表示
- 这两个操作符都会先强制转型,再比较相等性
- 再转换不同类型数据时,遵循下列基本规则:
- 如果有一个操作数是布尔值,则在比较相等性之前先将其转换为数值————false为0,true为1
- 如果一个操作数是字符串, 另一个操作数是数值,在比较相等性之前先将字符串转换为数值
- 如果一个操作数是对象,另一个操作数不是,则调用对象的 value0f( ) 方法,用得到的基本类型值按照前面的规则进行比较
- 这两个操作符在进行比较时则要遵循下列规则
- null 和 undefined 是相等的
- 要比较相等性之前,不能将 null 和 undefined 转换成其他任何值
- 如果有一个操作数是 NaN ,则相等操作符返回 false ,而不相等操作符返回 true
- 重要提示:即使两个操作数都是 NaN,相等操作符也返回 false,因为按照规则,NaN 不等于 NaN
- 如果两个操作数都是对象,则比较它们是不是同一 个对象。如果两个操作数都指向同一个对象,则相等操作符返回 true ;否则,返回 false
全等和不全等
- 全等操作符由3个等于号( === )表示,只在两个操作数未经转换就相等的情况下返回 true
- 不全等操作符由一个叹号后跟两个等于号( !== )表示,在两个操作数未经转换就不相等的情况下返回 true
- null == undefined 会返回 true ,但 null === undefined 会返回 false
3.5.8 条件操作符
- var max = ( num1 > num2 ) ? num1 : num2 ;
3.5.9 赋值操作符
- 简单的赋值操作符由等于号( = )表示
- 在等于号( = )前面添加乘性操作符、加性操作符或位操作符,就可以完成复合赋值操作
3.5.10 逗号操作符
- 使用逗号操作符可以在一条语句中执行多个操作
- 如: var num1 = 1 , num2 = 1 , num3 = 3 ;
- 逗号操作符还可以用于赋值,总会返回表达式中最后一项
- var num = ( 5 , 1 , 4 , 0 ) ; // num 的值为0
3.6 语句
3.6.1 if 语句
if 语句语法:
if ( condition ) statement1 else statement2
- 其中的 condition (条件) 可以是任意表达式,而且对这个表达式求值的结果不一定是布尔值,ECMAScipt 会自动调用 Boolean( ) 转换函数将结果转换为布尔值
推荐始终使用代码块
3.6.2 do-while 语句
- 后测试循环语句,在对表达式求值之前,循环体内的代码至少会被执行一次
do-while 语句语法:
do { statement } while (expression) ;
3.6.3 while 语句
- 前测试循环语句
while 语句语法:
while (expression) statement
3.6.4 for 语句
- 前测试循环语句
for 语句语法:
for (initialization; expression; post-loop-expression) statement
- while 循环做不到的,for 循环也做不到
初始化表达式、控制表达式和循环后表达式都是可选的。全部省略将会创造一个无限循环
3.6.5 for-in 语句
- for-in 语句是一种精准的迭代语句,可以用来枚举对象的属性
for-in 语句语法:
for (property in expression) statement
示例:
for (var propName in window) { document.write(propName); }
- 该例子中使用 for-in 循环来显示了BOM 中 window 对象的所有属性值,每次执行循环时,都会将 window 对象中存在的一个属性名赋值给变量propName,直到对象中所有属性都被枚举一遍为止
- ECMAScipt 对象的属性没有顺序,通过 for-in 循环输出的属性名的顺序是不可预测的
如果表示要迭代的对象的变量值为 null 或 undefined,for-in 语句不执行循环体,故建议在使用 for-in 循环前先检测该对象的值不是 null 或 undefined
3.6.6 label 语句
- 使用 label 语句可以在代码中添加标签,以便将来使用
label 语句语法:
label: statement
示例:
start: for (var i=0; i < count; i++) { alert( i ); }
- 这个例子中定义的 start 标签可以在将来由 break 或 continue 语句使用
- 加标签的语句一般都要与 for 语句等循环语句配合使用
3.6.7 break 和 continue 语句
- break 和 continue 语句用于在循环中精确地控制代码的执行
- break 语句会立即退出循环,强制继续执行循环后面的语句
- continue 语句也是立即退出循环,但退出循环后会从循环的顶部继续执行
- break 和 continue 语句都可以与 label 语句联合使用,从而返回代码中特定的位置
3.6.8 with 语句
- with 语句的作用是将代码的作用域设置到一个特定的对象中
with 语句语法:
with (expression) statement;
示例:
var qs = location.seach.substring(1); var hostName = location.hostname; var url = location.href;
可以改写成:
with (location) { var qs = seach.substring(1); var hostName = hostname; var url = href; }
- 使用 with 语句关联了 location 对象,这意味着在with 语句的他内部,每个变量首先被认为是一个局部变量,而如果在局部环境中找不到该变量的定义,就会查询location对象中是否有同名的属性。如果发现了同名属性,则以location对象属性的值作为变量的值
- 严格模式下不允许使用 with 语句,否则视为语法错误
大量使用 with 语句会导致性能下降
3.6.9 switch 语句
- switch 语句与 if 语句的关系最为密切
switch 语句语法:
switch (expression) { case value: statement break; case value: statement break; case value: statement break; case value: statement break; default: statement }
- switch 语句中每一种情形( case )的含义是:如果表达式等于这个值(value),则执行后面的表达式(statement)
- break 关键字会导致代码执行流跳出 switch 语句,如果省略了 break 关键字,会导致执行完当前 case 后继续执行下一个 case
- 最后的 default 关键字则用于表达式不匹配前面任何一种情形的时候,执行机动代码(因此也相当于一个 else 语句)
- 可以在 switch 语句中使用任何数据类型,每个 case 的值可以是常量、变量甚至是表达式
switch 语句在比较值时使用的时全等操作符
3.7 函数
- 通过函数可以封装任意多条语句,可以在任何时候调用
函数的基本语法:
function functionName (arg0, arg1, ... , argN) { statements }
ECMAScript 中的函数定义时不必指定是否返回值,但任何函数在任何时候都可以通过 return 语句来实现返回值
function sum(num1, num2) { return num1 + num2; }
- return 语句也可以不带有任何返回值,此时将返回 undefined
- 函数会在执行完 return 语句后立即退出,即 return 语句后的代码永远都不会被执行
- 严格模式下对函数有一些限制:
- 不能把函数命名为 eval 或 arguments
- 不能把参数命名为 eval 或 arguments
- 不能出现两个命名参数同名的情况
3.7.1 理解参数
- 即使定义的函数只接收两个参数,调用时也未必一定要传递两个参数(命名的参数只是提供便利,并不是必需的)
- ECMAScript 中的参数在内部是用一个数组来表示的,函数接收到的始终是这个数组,而不关心数组中有多少元素
- 在函数体内可以通过 argument 对象来访问这个参数数组,从而获取传递给函数的每一个参数
- 其实,argument 对象只是与数组类似(它并不是 Array 的实例)
- argument 的值永远与对应命名参数的值保持同步
- 没有传递值的命名参数将自动被赋予 undefined 值
- ECMAScript 中的所有参数传递的都是值,不可能通过引用传递参数
3.7.2 没有重载
- 由于不存在函数签名的特性,ECMAScript 函数不能重载