《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的值
Booleantruefalse
String任何非空字符串" "(空字符串)
Number任何非零数值(包括无穷大)0和null
Object任何对象null
Undefinedn/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 函数

  • 通过函数可以封装任意多条语句,可以在任何时候调用
  • 函数的基本语法:

    function functionName (arg0, arg1, ... , argN) {
        statements
    }
  • ECMAScript 中的函数定义时不必指定是否返回值,但任何函数在任何时候都可以通过 return 语句来实现返回值

    function sum(num1, num2) {
        return num1 + num2;
    }
    • return 语句也可以不带有任何返回值,此时将返回 undefined
  • 函数会在执行完 return 语句后立即退出,即 return 语句后的代码永远都不会被执行
  • 严格模式下对函数有一些限制:
    1. 不能把函数命名为 eval 或 arguments
    2. 不能把参数命名为 eval 或 arguments
    3. 不能出现两个命名参数同名的情况

3.7.1 理解参数

  • 即使定义的函数只接收两个参数,调用时也未必一定要传递两个参数(命名的参数只是提供便利,并不是必需的)
  • ECMAScript 中的参数在内部是用一个数组来表示的,函数接收到的始终是这个数组,而不关心数组中有多少元素
  • 在函数体内可以通过 argument 对象来访问这个参数数组,从而获取传递给函数的每一个参数
    • 其实,argument 对象只是与数组类似(它并不是 Array 的实例)
    • argument 的值永远与对应命名参数的值保持同步
  • 没有传递值的命名参数将自动被赋予 undefined 值
  • ECMAScript 中的所有参数传递的都是值,不可能通过引用传递参数

3.7.2 没有重载

  • 由于不存在函数签名的特性,ECMAScript 函数不能重载
发表于 2019-05-18 12:07  卡不加奇诺君 阅读( ...) 评论( ...) 编辑 收藏
 

转载于:https://www.cnblogs.com/Lee-cappuccino/p/10885293.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值