一、什么是JavaScript
完整的JavaScript包含:
- 核心(ECMAScript):由ECMA-262定义并提供核心功能。
- 文档对象模型(DOM):是一个应用编程接口,提供与网页内容交互的方法和接口。
- 浏览器对象模型(BOM):提供与浏览器交互的方法和接口。
1.ECMAScript
- 1998年,国际标准化组织和国际电工委员会也将ECMAScript纳入标准,自此后,各家浏览器通过ECMAScript作为实现JavaScript的依据。
- 浏览器对JavaScript的支持,指的是实现ECMAScript和DOM的程度。
2.DOM
DOM AP可以轻松地删除、添加、替换、修改节点
DOM等级 DOM Leve1:反映文档结构
DOM Leve2:DOM 视图、DOM事件、DOM样式、DOM遍历和范围
DOM Leve3:统一加载、保存和验证文档的方法
DOM4:替代Mutation Events的Mutation Observers
3.BOM
- BOM主要针对浏览器窗口和子窗口
- BOM的扩展
- 弹出新浏览器窗口的能力
- 移动、缩放和关闭浏览器窗口的能力
- navigator对象、提供关于浏览器的详尽信息
- location对象、提供浏览器加载页面的详尽信息
- screen对象、提供关于用户屏幕分辨率的详尽信息
- performance对象、提供浏览器内存占用、导航行为和事件统计的详尽信息
- 对cookie的支持
- 其他自定义对象
二、HTML中的JavaScript
1.script标签
1.1 script标签概念
- script标签:将JavaScript插入HTML的方法
- script元素的八个属性(全部可选):
- async:表示应该立即开始下载脚本,但不能阻止其他页面动作
- charset:使用src属性指定的代码字符集
- crossorigin:配置相关请求的CORS(跨资源共享)设置
- defer:表示在文档解析和显示完成后再执行脚本是没有问题的,只对外部脚本有效
- integrity:允许比对接收到的资源和指定到的加密签名以验证子资源完整性,可以用于确保内容分发网络不会提供恶意内容
- src:表示包含要执行的代码的外部文件
- type:替代language,表示代码块中脚本语言的内容类型(也称MIME类型)
1.2 script标签使用
引入JavaScript
<!DOCTYPE html>
<html lang="en,zh">
<head>
<meta charset="UTF-8">
<title></title>
<!-- 内部引入js -->
<script>
// 这里写JavaScript代码,先下载、解析、解释JavaScript代码后开始渲染页面,会增加页面渲染延迟
</script>
<!-- 外部引入js -->
<script src="../js/js.js"></script>
</head>
<body>
<!-- 内部引入js -->
<script>
// 这里写JavaScript代码,先渲染页面,再下载、解析、解释JavaScript代码
</script>
<!-- 外部引入js -->
<script src="../js/js.js"></script>
</body>
</html>
异步执行JavaScript
<!DOCTYPE html>
<html lang="en,zh">
<head>
<meta charset="UTF-8">
<title></title>
<!-- 两者都只对外部脚本有效 -->
<script defer src="../js/js.js">
// 可以把脚本推迟到文档渲染完毕后再执行,推迟的脚本总是按照它们被列出的次序执行
</script>
<script async src="../js/js.js">
// 表示脚本不需要等待其他脚本,同时也不阻塞文档渲染,即异步加载,异步脚本不能保证按照它们在页面中出现的次序执行
</script>
</head>
<body>
</body>
</html>
使用外部文件的好处
- 可维护性
- 缓存
- 适应未来
三、语言基础
1. 标识符
- 标识符:就是变量、函数、属性或函数参数的名称
- 标识符可以由一个或多个字符组成:
a.第一个字符必须是字母、下划线、美元符号
b.其他字符可以是字母、下划线、美元符号、数字- 标识符的字母可以是ASCII中的字母,也可以是Unicode的字母字符,可以使用驼峰大小写形式:即第一个单词的首字母小写,后面每个单词的首字母大写
- 关键字、保留字、true、false、null不能作为标识符
2. 注释
- // 单行注释
- /* 多行注释 */
3. 变量
优先使用const,其次使用let
3.1 var关键字
- var 变量名:不初始化的情况下,变量会保存一个特殊值undefined
- 使用var操作符定义的变量会成为包含它的函数的局部变量,使用var在一个函数内部定义一个变量,就意味着该变量将在函数退出时被销毁
- 在函数内定义变量时省略var操作符,可以创建一个全局变量
- 使用var时,这个关键字声明的变量会自动提升到函数作用域顶部
- var在全局作用域中声明的变量会成为window对象的属性
3.2 let声明
- let声明的范围是块作用域,块作用域是函数作用域的子集
- let声明的变量不会再作用域中被提升
- let声明之前的执行瞬间被成为“暂时性死区”,在此阶段引用任何后面才声明的变量都会抛出ReferenceError
- let在全局作用域中声明的变量不会成为window对象的属性
3.3 const声明
- 与let基本相同,区别是const声明变量时必须同时初始化变量,且尝试修改const声明的变量会导致运行时错误
- const不允许重复声明,也是块作用域
- const变量引用的是一个对象,那么修改这个对象内部的属性并不违反const的限制,不能用const来声明迭代变量
4. 数据类型
4.1 typeof 操作符
- 会返回下列字符串之一:
a. “undefined”:表示值未定义
b. “boolean”:表示值为布尔值
c. “string”:表示值为字符串
d. “number”:表示值为数值
e. “object”:表示值为对象或null
f. “function”:表示值为函数
f. “symbol”:表示值为符号
4.2 Nndefined 类型
- 只有一个值undefined,是一个假值
- 增加这个特殊值的目的是为了正式明确空对象指针null和未初始化变量的区别
4.3 Null 类型
- 只有一个null值,表示一个空对象指针,是一个假值
- 定义将来要保存对象值的变量时,建议使用Null来初始化,不要使用其他值
4.4 Boolean 类型
- 有两个字面值:true和false,区分大小写
布尔值之间转换规则
4.5 Number 类型
4.5.1 浮点数
- 要定义浮点数,数值中必须包含小数点,而且小数点后面必须至少有一个数字
- 数值本身是整数,小数点后面跟着0会被转换为整数
- 浮点值的精确度最高可达17位小数
4.5.2 值的范围
- 任何无法表示的负数以-Infinity(负无穷大)
- 任何无法表示的正数以Infinity(正无穷大)
- 确定一个值是不是有限大,使用isFinite()函数
4.5.3 NaN
- NaN不是数值
- 任何涉及NaN的操作始终返回NaN
- NaN不等于包括NaN在内的任何值
4.5.4 数值转换
- 可以将非数值转换为数值,number()是转型函数,可以用于任何数据类型
- Number()函数基于如下规则执行转换。
a. 布尔值,true转换为1,false转换为0。
b. 数值,直接返回。
c. null,返回0。
d. undefined,返回NaN。
e. 字符串,应用以下规则:
1> 如果字符串包含数值字符,包括数值字符前面带加、减号的情况,则转换为一个十进制数值。因此,Number(“1”)返回1,Number(“123”)返回123,Number(“011”)返回11(忽略前面的零)。
2> 如果字符串包含有效的浮点值格式如"1.1",则会转换为相应的浮点值(同样,忽略前面的零)。
3> 如果字符串包含有效的十六进制格式如"0xf",则会转换为与该十六进制值对应的十进制整数值。
4> 如果是空字符串(不包含字符),则返回0。 如果字符串包含除上述情况之外的其他字符,则返回NaN。
f. 对象,调用valueOf()方法,并按照上述规则转换返回的值。如果转换结果是NaN,则调用toString()方法,再按照转换字符串的规则转换。
- parseInt()函数,可以转换为整数 a. 如果第一个字符不是数值字符、加号或减号,parseInt()立即返回NaN b. parseInt()第二个参数,用于指定底数(进制数)
- parseFloat()函数,转换为浮点数 a. 解析到字符串末尾或者解析到一个无效的浮点数字符为止,意味着第一次出现的小数点是优先的,第二次出现的小数点无效 b.
始终忽略字符串开头的零 c. 只解析十进制值,不能指定底数
4.6 String 类型
- String数据类型表示零或多个16为Unicode字符序列,字符串可以使用双引号、单引号、反引号标示
字符字面量
- 字符串是不可变的,要修改某个变量中的字符串值,必须先销毁原始的字符串,然后将包含新值的另一个字符保存到该变量
- toString(),转换为字符串,返回当前值的字符串等价物
a. 可用于数值、布尔值、对象和字符串值,null和undefined值没有该方法啊
b. 默认情况下,返回数组的十进制字符串表示,二通过传入参数,可以得到数组的二进制、八进制、十六进制,或者其他任何有效基数的字符串值- String()函数遵循如下规则
a. 如果值有toString()方法,则调用该方法(不传参数)并返回结果
b. 如果值是null,返回"null"
c. 如果值是undefined,返回"undefined"
- 模板字面量会保持反引号内部的空格
- 字符串插值通过在${}中使用一个JavaScript表达式实现,所有插入的值都会使用toString()强制转型为字符串,而且任何JavaScript表达式都可以用于插值
- 模板字面量支持定义标签函数,通过标签函数可以自定义插值行为。标签函数会接收被插值记号分隔后的模板和对每个表达式求值的结果
- 使用模板字面量可以直接获取原始的模板字面量内容,而不是被转换后的字符表示,可以使用默认的String.raw标签函数
4.7 Symbol 类型
- Symbol值必须放在[]中,不能进行运算
- 符号是原始值,且符号实例是唯一、不可变的,符号的用途是确保对象属性使用唯一标识符,不会发生属性冲突的危险
- 符号就是用来创建唯一记号,进而用做非字符串形式的对象属性
- 符号需要使用symbol()函数初始化,typeof操作符对符号返回symbol
- 调用Symbol()函数时,也可以传入一个字符串参数作为对符号的描述(description),将来可以通过这个字符串来调试代码。但是,这个字符串参数与符号定义或标识完全无关
- 符号没有字面量语法
- Symbol()函数不能用作构造函数,与new关键字一起使用
- 实想使用符号包装对象,可以借用Object()函数
- Symbol.for()方法,注册全局符号
- Symbol.for()对每个字符串键都执行幂等操作
- 全局注册表中的符号必须使用字符串键来创建,因此作为参数传给Symbol.for()的任何值都会被转换为字符串
- 使用Symbol.keyFor()来查询全局注册表,这个方法接收符号,返回该全局符号对应的字符串键。如果查询的不是全局符号,则返回undefined
- Object.getOwnPropertyNames()返回对象实例的常规属性数组,Object.getOwnPropertySymbols()返回对象实例的符号属性数组。
这两个方法的返回值彼此互斥。
Object.getOwnPropertyDescriptors()会返回同时包含常规和符号属性描述符的对象。
Reflect.ownKeys()会返回两种类型的键
- 内置符号最重要的用途之一是重新定义它们,从而改变原生结构的行为
- 内置符号也没有什么特别之处,它们就是全局函数Symbol的普通字符串属性,指向一个符号的实例。所有内置符号属性都是不可写、不可枚举、不可配置的
- @@iterator指的就是Symbol.iterator
- Symbol.asyncIterator:该方法返回对象默认的AsyncIterator,这个符号表示实现异步迭代器API的函数
- Symbol.hasInstance:该方法决定一个构造器对象是否认可一个对象是它的实例,instanceof操作符可以用来确定一个对象实例的原型链上是否有原型
- Symbol.isConcatSpreadable:一个布尔值,如果是true,则意味着对象应该用Array.prototype.concat()打平其数组元素
a.数组对象默认情况下会被打平到已有的数组,false或假值会导致整个对象被追加到数组末尾 b.
类数组对象默认情况下会被追加到数组末尾,true或真值会导致这个类数组对象被打平到数组实例 c.
其他不是类数组对象的对象在Symbol.isConcatSpreadable被设置为true的情况下将被忽略- Symbol.iterator:该方法返回对象默认的迭代器,这个符号表示实现迭代器API的函数
- Symbol.match:一个正则表达式方法,该方法用正则表达式去匹配字符串。由String.prototype.match()方法使用
- Symbol.replace:一个正则表达式方法,该方法替换一个字符串中匹配的子串。由String.prototype.replace()方法使用
- Symbol.search:一个正则表达式方法,该方法返回字符串中匹配正则表达式的索引。由String.prototype.search()方法使用
- Symbol.species:一个函数值,该函数作为创建派生对象的构造函数。用Symbol.species定义静态的获取器(getter)方法,可以覆盖新创建实例的原型定义
- Symbol.split:一个正则表达式方法,该方法在匹配正则表达式的索引位置拆分字符串。由String.prototype.split()方法使用
- Symbol.toPrimitive:一个方法,该方法将对象转换为相应的原始值。由ToPrimitive抽象操作使用
- Symbol.toStringTag:一个字符串,该字符串用于创建对象的默认字符串描述。由内置方法Object.prototype.toString()使用。通过toString()方法获取对象标识时,会检索由Symbol.toStringTag指定的实例标识符,默认为"Object
- Symbol.unscopables:一个对象,该对象所有的以及继承的属性,都会从关联对象的with环境绑定中排除。设置这个符号并让其映射对应属性的键值为true,就可以阻止该属性出现在with环境绑定中
4.8 Object 类型
- 对象通过new操作符后跟对象类型的名称来创建。开发者可以通过创建Object类型的实例来创建自己的对象,然后再给对象添加属性和方法
- Object类型的所有属性和方法在派生的对象上同样存在,每个Object实例都有如下属性和方法
a. constructor:用于创建当前对象的函数。在前面的例子中,这个属性的值就是Object()函数
b. hasOwnProperty(propertyName):用于判断当前对象实例(不是原型)上是否存在给定的属性。要检查的属性名必须是字符串(如o.hasOwnProperty(“name”))或符号
c. isPrototypeOf(object):用于判断当前对象是否为另一个对象的原型
d. propertyIsEnumerable(propertyName):用于判断给定的属性是否可以使用
e. toLocaleString():返回对象的字符串表示,该字符串反映对象所在的本地化执行环境
f. toString():返回对象的字符串表示
e. valueOf():返回对象对应的字符串、数值或布尔值表示。通常与toString()的返回值相同
5. 操作符
- 操作符通常会调用valueOf()和/或toString()方法来取得可以计算的值
5.1 一元操作符
- 递增/递减操作符
- 只操作一个值的操作符叫一元操作符
- 递增/递减操作符: a. 前缀递增操作符会给数值+1,把两个加号(++)放到变量前头即可,前缀递减操作符会给数值-1,把两个减号(–)放到变量前头即可,前缀递增还是前缀递减操作符,变量的值都会在语句被求值之前改变
b.
后缀递增操作符会给数值+1,把两个加号(++)放到变量后头即可,后缀递减操作符会给数值-1,把两个减号(–)放到变量后头即可,后缀递增还是后缀递减操作符,变量的值都会在语句被求值之后改变- 对于字符串,如果是有效的数值形式,则转换为数值再应用改变。变量类型从字符串变成数值。
- 对于字符串,如果不是有效的数值形式,则将变量的值设置为NaN。变量类型从字符串变成数值。
- 对于布尔值,如果是false,则转换为0再应用改变。变量类型从布尔值变成数值。
- 对于布尔值,如果是true,则转换为1再应用改变。变量类型从布尔值变成数值。
- 对于浮点值,加1或减1。
- 对象,则调用其(第5章会详细介绍的)valueOf()方法取得可以操作的值。对得到的值应用上述规则。如果是NaN,则调用toString()并再次应用其他规则。变量类型从对象变成数值
- 一元加和减
- 一元加由一个加号(+)表示,放在变量前头,对数值没有任何影响
- 将一元加应用到非数值,则会执行与使用Number()转型函数一样的类型转换:布尔值false和true转换为0和1,字符串根据特殊规则进行解析,对象会调用它们的valueOf()和/或toString()方法以得到可以转换的值
- 一元减由一个减号(-)表示,放在变量前头,主要用于把数值变成负值,如把1转换为-1
- 在应用到非数值时,一元减会遵循与一元加同样的规则,先对它们进行转换,然后再取负值
5.2 位操作符
- 有符号整数使用32位的前31位表示整数值。第32位表示数值的符号,如0表示正,1表示负。这一位称为符号位(sign bit),它的值决定了数值其余部分的格式
- 负值以一种称为二补数(或补码)的二进制编码存储
- 按位非操作符用波浪符(~)表示,它的作用是返回数值的一补数
- 按位与操作符用和号(&)表示,有两个操作数
- 按位或操作符用管道符(|)表示,同样有两个操作数
- 按位异或用脱字符(^)表示,同样有两个操作数
- 左移操作符用两个小于号(<<)表示,会按照指定的位数将数值的所有位向左移动
- 有符号右移由两个大于号(>>)表示,会将数值的所有32位都向右移,同时保留符号(正或负)
- 无符号右移用3个大于号表示(>>>),会将数值的所有32位都向右移
5.3 布尔操作符
- 逻辑非操作符由一个叹号(!)表示,可应用给ECMAScript中的任何值,逻辑非操作符会遵循如下规则: a. 如果操作数是对象,则返回false。 b. 如果操作数是空字符串,则返回true。 c.
如果操作数是非空字符串,则返回false。 d. 如果操作数是数值0,则返回true。 e.
如果操作数是非0数值(包括Infinity),则返回false。 f. 如果操作数是null,则返回true。 g.
如果操作数是NaN,则返回true。 h. 如果操作数是undefined,则返回true
- 逻辑与操作符由两个和号(&&)表示,应用到两个值,遵循如下规则:
a. 如果第一个操作数是对象,则返回第二个操作数。
b. 如果第二个操作数是对象,则只有第一个操作数求值为true才会返回该对象。
c. 如果两个操作数都是对象,则返回第二个操作数。
d. 如果有一个操作数是null,则返回null。
e. 如果有一个操作数是NaN,则返回NaN。
f. 如果有一个操作数是undefined,则返回undefined
- 逻辑或操作符由两个管道符(||)表示,遵循如下规则:
a. 如果第一个操作数是对象,则返回第一个操作数。
b. 如果第一个操作数求值为false,则返回第二个操作数。
c. 如果两个操作数都是对象,则返回第一个操作数。
d. 如果两个操作数都是null,则返回null。
e. 如果两个操作数都是NaN,则返回NaN。
f. 如果两个操作数都是undefined,则返回undefined
5.4 乘性操作符
- 乘法操作符由一个星号(*)表示,可以用于计算两个数值的乘积
a. 如果操作数都是数值,则执行常规的乘法运算,即两个正值相乘是正值,两个负值相乘也是正值,正负符号不同的值相乘得到负值。
b.如果ECMAScript不能表示乘积,则返回Infinity或-Infinity。
c. 如果有任一操作数是NaN,则返回NaN。
d. 如果是Infinity乘以0,则返回NaN。
e. 如果是Infinity乘以非0的有限数值,则根据第二个操作数的符号返回Infinity或-Infinity。
f. 如果是Infinity乘以Infinity,则返回Infinity。
g. 如果有不是数值的操作数,则先在后台用Number()将其转换为数值,然后再应用上述规则
- 除法操作符由一个斜杠(/)表示,用于计算第一个操作数除以第二个操作数的商
a. 如果操作数都是数值,则执行常规的除法运算,即两个正值相除是正值,两个负值相除也是正值,符号不同的值相除得到负值。
b. 如果ECMAScript不能表示商,则返回Infinity或-Infinity。
c. 如果有任一操作数是NaN,则返回NaN。
d. 如果是Infinity除以Infinity,则返回NaN。
e. 如果是0除以0,则返回NaN。
f. 如果是非0的有限值除以0,则根据第一个操作数的符号返回Infinity或-Infinity。
g. 如果是Infinity除以任何数值,则根据第二个操作数的符号返回Infinity或-Infinity。
h. 如果有不是数值的操作数,则先在后台用Number()函数将其转换为数值,然后再应用上述规则
- 取模(余数)操作符由一个百分比符号(%)表示
a. 如果操作数是数值,则执行常规除法运算,返回余数。
b. 如果被除数是无限值,除数是有限值,则返回NaN。
c. 如果被除数是有限值,除数是0,则返回NaN。
d. 如果是Infinity除以Infinity,则返回NaN。
e. 如果被除数是有限值,除数是无限值,则返回被除数。
f. 如果被除数是0,除数不是0,则返回0。
g. 如果有不是数值的操作数,则先在后台用Number()函数将其转换为数值,然后再应用上述规则
5.5 指数操作符
ECMAScript 7新增了指数操作符,Math.pow()现在有了自己的操作符**,指数赋值操作符**=
5.6 加性操作符
- 加法操作符(+)用于求两个数的和,并根据如下规则返回结果:
a. 如果有任一操作数是NaN,则返回NaN
b. 如果是Infinity加Infinity,则返回Infinity
c. 如果是-Infinity加-Infinity,则返回-Infinity
d. 如果是Infinity加-Infinity,则返回NaN
e. 如果是+0加+0,则返回+0
f. 如果是-0加+0,则返回+0
g. 如果是-0加-0,则返回-0- 如果有一个操作数是字符串,则要应用如下规则:
a. 如果两个操作数都是字符串,则将第二个字符串拼接到第一个字符串后面
b. 如果只有一个操作数是字符串,则将另一个操作数转换为字符串,再将两个字符串拼接在一起- 如果有任一操作数是对象、数值或布尔值,则调用它们的toString()方法以获取字符串,然后再应用前面的关于字符串的规则。对于undefined和null,则调用String()函数,分别获取"undefined"和"null"
- 减法操作符(-)也是使用很频繁的一种操作符,并根据如下规则返回结果:
a. 如果两个操作数都是数值,则执行数学减法运算并返回结果。
b. 如果有任一操作数是NaN,则返回NaN。
c. 如果是Infinity减Infinity,则返回NaN。如果是-Infinity减-Infinity,则返回NaN。 如果是Infinity减-Infinity,则返回Infinity。如果是-Infinity减Infinity,则返回-Infinity。
d. 如果是+0减+0,则返回+0。如果是+0减-0,则返回-0。如果是-0减-0,则返回+0。
e. 如果有任一操作数是字符串、布尔值、null或undefined,则先在后台使用Number()将其转换为数值,然后再根据前面的规则执行数学运算。
f. 如果转换结果是NaN,则减法计算的结果是NaN。
g. 如果有任一操作数是对象,则调用其valueOf()方法取得表示它的数值。
h. 如果该值是NaN,则减法计算的结果是NaN。如果对象没有valueOf()方法,则调用其toString()方法,然后再将得到的字符串转换为数值
5.7 关系操作符
- 关系操作符执行比较两个值的操作,包括小于(<)、大于(>)、小于等于(<=)和大于等于(>=),都返回布尔值
a. 如果操作数都是数值,则执行数值比较。
b. 如果操作数都是字符串,则逐个比较字符串中对应字符的编码。
c. 如果有任一操作数是数值,则将另一个操作数转换为数值,执行数值比较。
d. 如果有任一操作数是对象,则调用其valueOf()方法,取得结果后再根据前面的规则执行比较。
e. 如果没有valueOf()操作符,则调用toString()方法,取得结果后再根据前面的规则执行比较。
f. 如果有任一操作数是布尔值,则将其转换为数值再执行比较
5.8 相等操作符
- 等于和不等于:
- 等于操作符用两个等于号(==)表示,如果操作数相等,则会返回true。不等于操作符用叹号和等于号(!=)表示,如果两个操作数不相等,则会返回true。这两个操作符都会先进行类型转换(通常称为强制类型转换)再确定操作数是否相等
a. 如果任一操作数是布尔值,则将其转换为数值再比较是否相等。false转换为0,true转换为1。
b. 如果一个操作数是字符串,另一个操作数是数值,则尝试将字符串转换为数值,再比较是否相等。
c. 如果一个操作数是对象,另一个操作数不是,则调用对象的valueOf()方法取得其原始值,再根据前面的规则进行比较。
d. null和undefined相等。 null和undefined不能转换为其他类型的值再进行比较。
e. 如果有任一操作数是NaN,则相等操作符返回false,不相等操作符返回true。记住:即使两个操作数都是NaN,相等操作符也返回false,因为按照规则,NaN不等于NaN。
f. 如果两个操作数都是对象,则比较它们是不是同一个对象。如果两个操作数都指向同一个对象,则相等操作符返回true。否则,两者不相等
- 全等和不全等:
- 全等操作符由3个等于号(===)表示,只有两个操作数在不转换的前提下相等才返回true。
- 不全等操作符用一个叹号和两个等于号(!==)表示,只有两个操作数在不转换的前提下不相等才返回true
5.9 条件操作符
5.10 赋值操作符
- 简单赋值用等于号(=)表示,将右手边的值赋给左手边的变量
a. 乘后赋值(*=)
b. 除后赋值(/=)
c. 取模后赋值(%=)
d. 加后赋值(+=)
e. 减后赋值(-=)
f. 左移后赋值(<<=)
g. 右移后赋值(>>=)
h. 无符号右移后赋值(>>>=)
5.11 逗号操作符
- 逗号操作符可以用来在一条语句中执行多个操作
- 可以使用逗号操作符来辅助赋值,在赋值时使用逗号操作符分隔值,最终会返回表达式中最后一个值
6. 语句
6.1 if 语句
这里的条件(condition)可以是任何表达式,并且求值结果不一定是布尔值
6.2 do-while 语句
- do-while语句是一种后测试循环语句,即循环体中的代码执行后才会对退出条件进行求值
- 循环体内的代码至少执行一次
6.3 while 语句
- while语句是一种先测试循环语句,即先检测退出条件,再执行循环体内的代码
- while循环体内的代码有可能不会执行
6.4 for 语句
- for语句也是先测试语句,只不过增加了进入循环之前的初始化代码,以及循环执行后要执行的表达式
6.5 for-in 语句
- for-in语句是一种严格的迭代语句,用于枚举对象中的非符号键属性
for (property in expression) statement- ECMAScript中对象的属性是无序的,因此for-in语句不能保证返回对象属性的顺序
- for-in循环要迭代的变量是null或undefined,则不执行循环体
6.6 for-of 语句
- for-of语句是一种严格的迭代语句,用于遍历可迭代对象的元素
- for-of循环会按照可迭代对象的next()方法产生值的顺序迭代元素
- 尝试迭代的变量不支持迭代,则for-of语句会抛出错误
6.7 标签语句
- 标签语句用于给语句加标签:label: statement
- start是一个标签,可以在后面通过break或continue语句引用
6.8 break和continue语句
- break和continue语句为执行循环代码提供了更严格的控制手段
- break语句用于立即退出循环,强制执行循环后的下一条语句
- continue语句也用于立即退出循环,但会再次从循环顶部开始执行
6.9 with语句
- with语句的用途是将代码作用域设置为特定的对象:with (expression) statement;
- 使用with语句的主要场景是针对一个对象反复操作,这时候将代码作用域设置为该对象能提供便利
- 严格模式不允许使用with语句,否则会抛出错误
6.10 switch语句
- switch语句是与if语句紧密相关的一种流控制语句
- 这里的每个case(条件/分支)相当于:“如果表达式等于后面的值,则执行下面的语句。”break关键字会导致代码执行跳出switch语句。如果没有break,则代码会继续匹配下一个条件。default关键字用于在任何条件都没有满足时指定默认执行的语句(相当于else语句)
- switch语句可以用于所有数据类型,因此可以使用字符串甚至对象。其次,条件的值不需要是常量,也可以是变量或表达式
- switch语句在比较每个条件的值时会使用全等操作符,因此不会强制转换数据类型(比如,字符串"10"不等于数值10)
7. 函数
- 可以封装语句,然后在任何地方、任何时间执行。ECMAScript中的函数使用function关键字声明,后跟一组参数,然后是函数体
- 任何函数在任何时间都可以使用return语句来返回函数的值,用法是后跟要返回的值
- 只要碰到return语句,函数就会立即停止执行并退出。因此,return语句后面的代码不会被执行
- return语句也可以不带返回值,函数会立即停止执行并返回undefined
8. 严格模式
- 严格模式对函数也有一些限制:
a. 函数不能以eval或arguments作为名称;
b. 函数的参数不能叫eval或arguments;
c. 两个命名参数不能叫同一个名称。