《JavaScript 高级程序设计》学习笔记

我最近开始看这本书,内容比较详细,很难全部记住
因此我将书中知识点记录下来,以便日后查阅

第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是一种专为与网页交互而设计的脚本语言,由三个不同部分组成:
    1. ECMAScript,由ECMA-262定义,提供核心语言功能
    2. 文档对象模型(DOM),提供访问和操作网页内容的方法和接口
    3. 浏览器对象模型(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种简单数据类型(基本数据类型):
      1. Undefineded
      2. Null
      3. Boolean
      4. Number
      5. 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()
      • 适用于任何数据类型
      • 转换规则如下:
        1. Boolean值,true和false分别转换为1和0
        2. 数字值,只是简单的传入和返回
        3. null值,返回0
        4. undefined,返回NaN
        5. 字符串,遵循下列规则
          • 只包含数字(包括带正负号的情况),则转换为十进制数(会忽略前导0)
          • 包含有效的浮点格式,则转换为对应的浮点数值(也会忽略前导0)
          • 包含有效的十六进制格式,则转换为相同大小的十进制整数值
          • 空字符串,则转换为0
          • 包含上述格式之外的字符,则转换为NaN
        6. 对象,则调用对象的valueOf( )方法,然后依照前面的规则转换返回的值。若转换结果是NaN,则调用对象的toString( )方法,然后再次依照前面的规则转换返回的字符串值
    • parseInt()
      • 专门用于把字符串转换成数值
      • 会忽略字符串前面的空格,直到找到第一个非空格字符
        • 如果第一个字符不是数字字符或者负号,就会返回NaN
          • 也就是说转换空字符串会返回NaN
        • 如果第一个字符是数字字符,会继续解析第二个字符,直到解析完所有后续字符或遇到非数字字符
          • 如 "1234blue" 转换为1234; "22.5" 转换为22
      • 能够识别出各种整数格式
        • 以 "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( ),能够将任何类型的值转换为字符串
      • 遵循下列转换规则
        1. 如果值有toString( ) 方法,则调用该方法(没有参数)并返回结果
        2. 如果值是 "null" 则返回 "null"
        3. 如果值是 "undefined" 则返回 "undefined"

    3.4.7 Object 类型

    • ECMAScript中的对象其实就是一组数据和功能的集合,对象可以通过执行 new 操作符后跟要创建的对象类型的名称来创建
    • 创建 Object 类型的实例并为其添加属性和(或)方法,就可以创建自定义对象
      • 如:var o = new Object ( );
      • 可以省略圆括号,但不推荐
    • Object 的每个实例都具有下列属性和方法:
      1. constructor:保存着用于创建当前对象的函数
      2. hasOwnProperty(propertyName):用于检查给定的属性在当前对象实例中(而不是在实例的原型中)是否存在
        • 作为参数的属性名(propertyName)必须以字符串形式指定,例如:o.hasOwnProperty("name");
      3. isPrototypeOf(object):用于检查传入的对象是否是当前对象的原型(第5章将讨论原型)
      4. propertyIsEnumerable(propertyName):用于检查给定的属性是否能够使用 for-in 语句来枚举
        • 作为参数的属性名必须以字符串形式指定
      5. toLocaleString( ):返回对象的字符串表示,该字符串与执行环境的地区对应
      6. toString( ):返回对象的字符串表示
      7. 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 )

    逻辑非

    • 逻辑非操作符由一个感叹号( ! )表示
    • 可以应用于任何值,首先会将操作数转换为一个布尔值,然后再求反
      1. 对象,返回 false
      2. 空字符串,返回 true
      3. 非空字符串,返回 false
      4. 数值0,返回 true
      5. 任意非0数值(包括Infinity),返回 false
      6. null,返回 true
      7. NaN,返回 true
      8. undefined,返回 true
    • 逻辑非操作符也可以用于将一个值转换为与其对应的布尔值,同时使用两个逻辑非操作符就会模拟Boolean()转型函数的行为,最终结果相同

    逻辑与

    • 逻辑与操作符由两个和号( && )表示,有两个操作数
    • 可以应用于任何类型的操作数,当其中一个操作数不是布尔值的情况下,不一定返回布尔值
      1. 如果第一个操作数是对象,则返回第二个操作数
      2. 如果第二个操作数是对象,则只有在第一个操作数的求值结果为 true 的情况下才会返回该对象
      3. 如果两个操作数都是对象,则返回第二个操作数
      4. 如果第一个操作数是 null,则返回 null
      5. 如果第一个操作数是 NaN,则返回 NaN
      6. 如果第一个操作数是 undefined,则返回 undefined
    • 逻辑与操作属于短路操作,即如果第一个操作数是 false,那么就不会再对第二个操作数求值(因此第二个操作数未定义也不会报错)
    • 不能在逻辑与操作中使用未定义的值

    逻辑或

    • 逻辑或操作符由两个竖线符号( || )表示,有两个操作数
    • 与逻辑与相似,如果有一个操作数不是布尔值的情况下,不一定返回布尔值
      1. 如果第一个操作数是对象,则返回第一个操作数
      2. 如果第一个操作数的求值结果为 false,则返回第二个操作数
      3. 如果两个操作数都是对象,则返回第一个操作数
      4. 如果第两个操作数都是 null,则返回 null
      5. 如果第两个操作数都是 NaN,则返回 NaN
      6. 如果第两个操作数都是 undefined,则返回 undefined
    • 逻辑或操作符也是短路操作符,如果第一个操作数是 true,那么就不会再对第二个操作数求值
    • 可以利用逻辑或来避免为变量赋 null 或 undefined 值:
      • 例如: var myObject = preferredObject || backupObject;
      • 变量 preferredObject 中包含优先赋给变量 myObject 的值,变量 backupObject 负责在 preferredObject 中不包含有效值的情况下提供后备值

    3.5.4 乘性操作符

    • ECMAScript 定义了三个乘性操作符:乘法、除法和求模
    • 操作数为非数值的情况下会执行自动的类型转换

    乘法

    • 乘法操作符由一个星号( * )表示,用于计算两个数值的乘积
    • 在处理特殊值的情况下,遵循下列特殊规则:
      1. 如果操作数都是数值,执行常规的乘法计算
      2. 如果有一个操作数是 NaN,则结果是 NaN
      3. 如果是 Infinity 与 0 相乘,则结果是 NaN
      4. 如果是 Infinity 与非 0 数值相乘,则结果是 Infinity 或 -Infinity (取决于有符号操作数的符号)
      5. 如果是 Infinity 与 Infinity 相乘,则结果是 Infinity
      6. 如果有一个操作数不是数值,则在后台调用 Number( ) 将其转换为数值,再应用以上规则

    除法

    • 除法操作符由一个斜线符号( / )表示,执行第二个操作数除第一个操作数的计算
    • 对特殊值也有特殊的处理规则:
      1. 如果操作数都是数值,执行常规的除法计算
      2. 如果有一个操作数是 NaN,则结果是 NaN
      3. 如果是 Infinity 被 Infinity 除,则结果是 NaN
      4. 如果是零被零除,则结果是 NaN
      5. 如果是非零的有限数被零除,则结果是 Infinity 或 -Infinity (取决于有符号操作数的符号)
      6. 如果是 Infinity 被任何非零数值除,则结果是 Infinity 或 -Infinity (取决于有符号操作数的符号)
      7. 如果有一个操作数不是数值,则在后台调用 Number( ) 将其转换为数值,再应用以上规则

    求模

    • 求模(余数)操作符由一个百分号( % )表示
    • 对特殊值遵循特殊的处理规则:
      1. 如果操作数都是数值,执行常规的除法计算,返回除得的余数
      2. 如果被除数是无穷大值而除数是有限大的数值,则结果是NaN
      3. 如果被除数是有限大的数值而除数是零,则结果是NaN
      4. 如果是 Infinity 被 Infinity 除,则结果是NaN
      5. 如果被除数是有限大的数值而除数是无穷大的数值,则结果是被除数
      6. 如果被除数是零,则结果是零
      7. 如果有一个操作数不是数值,则在后台调用 Number( ) 将其转换为数值,然后再应用上面的规则

    3.5.5 加性操作符

    • 包括加法和减法
    • 在 ECMAScipt 中,这两个操作符由一系列特殊行为

    加法

    • 如果两个操作数都是数值,执行常规的加法计算,然后根据下列规则返回结果:
      1. 如果有一个操作数是 NaN,则结果是 NaN
      2. 如果是 Infinity 加 Infinity ,则结果是 Infinity
      3. 如果是 - Infinity 加 - Infinity ,则结果是 - Infinity
      4. 如果是 Infinity 加 - Infinity ,则结果是 NaN
      5. 如果是 +0 加 +0 ,则结果是 +0
      6. 如果是 -0 加 -0 ,则结果是 -0
      7. 如果是 +0 加 -0 ,则结果是 +0
    • 如果有一个操作数是字符串
      1. 如果两个操作数都是字符串,则将第二个操作数与第一个操作数拼接起来
      2. 如果只有一个操作数是字符串, 则将另一个操作数转换为字符串,然后再将两个字符串拼接起来
    • 如果有一个操作数是对象、数值或布尔值,则调用它们的 toString( )方法取得相应的字符串值,然后再应用前面关于字符串的规则
    • 对于 undefined 和 null ,则分别调用 String( )函数并取得字符串 "undefined" 和 "null"

    减法

    • 减法操作符同样需要遵守一些特殊规则:
      1. 如果两个操作符都是数值,则执行常规的算术减法操作并返回结果
      2. 如果有一个操作数是NaN,则结果是NaN
      3. 如果是 Infinity 减 Infinity ,则结果是 NaN
      4. 如果是 - Infinity减 -Infinity,则结果是 NaN
      5. 如果是 Infinity 减 - Infinity,则结果是 Infinity
      6. 如果是 - Infinity减 Infinity ,则结果是 - Infinity
      7. 如果是 +0 减 +0 ,则结果是 +0
      8. 如果是 -0 减 +0 ,则结果是 -0
      9. 如果是 -0 减 -0 ,则结果是 +0
      10. 如果有一个操作数是字符串、布尔值、null 或 undefined ,则先在后台调用 Number () 函数将其转换为数值,然后再根据前面的规则执行减法计算
        • 如果转换的结果是 NaN ,则减法的结果就是 NaN
      11. 如果有一个操作数是对象,则调用对象的 valueOf ( ) 方法以取得表示该对象的数值
        • 如果得到的值是NaN,则减法的结果就是NaN
        • 如果对象没有 valueOf ( ) 方法,则调用其 toString( ) 方法并将得到的字符串转换为数值

    3.5.6 关系操作符

    • 小于 ( < )、大于 ( > )、小于等于 ( <= ) 和大于等于 ( >= )
    • 这几个操作符都返回一个布尔值
    • 当关系操作符的操作数使用了非数值时,也要进行数据转换或完成某些奇怪的操作
      1. 如果两个操作数都是数值,则执行数值比较
      2. 如果两个操作数都是字符串,则比较两个字符串对应的字符编码值
      3. 如果一个操作数是数值,则将另一个操作数转换为一个数值,然后执行数值比较
      4. 如果一个操作数是对象,则调用对象的 valueOf ( ) 方法,用得到的结果按照前面的规则执行比较。如果对象没有 valueOf ( ) 方法,则调用其 toString( ) 方法,并用得到的结果按照前面的规则执行比较
      5. 如果一个操作数是布尔值,则先将其转化为数值,然后再执行比较
    • 任何操作数与 NaN 进行比较,结果都是 false

    3.5.7 相等操作符

    • 两组操作符
      • 相等不相等————先转换再比较
      • 全等不全等————仅比较而不转换

    相等和不相等

    • 相等操作符由两个等于号( == )表示,不相等由感叹号后跟等于号( != )表示
    • 这两个操作符都会先强制转型,再比较相等性
    • 再转换不同类型数据时,遵循下列基本规则:
      1. 如果有一个操作数是布尔值,则在比较相等性之前先将其转换为数值————false为0,true为1
      2. 如果一个操作数是字符串, 另一个操作数是数值,在比较相等性之前先将字符串转换为数值
      3. 如果一个操作数是对象,另一个操作数不是,则调用对象的 value0f( ) 方法,用得到的基本类型值按照前面的规则进行比较
    • 这两个操作符在进行比较时则要遵循下列规则
      1. null 和 undefined 是相等的
      2. 要比较相等性之前,不能将 null 和 undefined 转换成其他任何值
      3. 如果有一个操作数是 NaN ,则相等操作符返回 false ,而不相等操作符返回 true
        • 重要提示:即使两个操作数都是 NaN,相等操作符也返回 false,因为按照规则,NaN 不等于 NaN
      4. 如果两个操作数都是对象,则比较它们是不是同一 个对象。如果两个操作数都指向同一个对象,则相等操作符返回 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 函数

    猜你喜欢

    转载自www.cnblogs.com/Lee-cappuccino/p/10885293.html