JavaScript
简介
ECMA 和 JavaScript
- ECMA
- 欧洲计算机制造协会
- ECMA-262
- 欧洲计算机制造协会制定的 标准 ,定义语法和语义
- ECMAScript
- 通过 ECMA-262 标准 实现的脚本语言
- JavaScript
- 核心使用 ECMAScript 脚本语言,并扩展了其他API功能
JavsScript基础
严格模式
严格模式用法
- 脚本文件的顶部定义字符串 “use strict”,整个脚本以严格模式进行运行
- 函数中的顶部定义字符串 “use strict”,函数中以喊个模式进行运行
严格模式限制
- 不允许使用未定义的变量
- 不允许删除变量或对象
- 不允许删除函数
- 不允许变量重名
- 不允许使用八进制
- 不允许使用转义字符
- 不允许对只读属性赋值
- 不允许对一个使用getter方法读取的属性进行赋值
- 不允许删除一个不允许删除的属性
- 变量名标识符不能为 “eval”
- 变量名标识符不能为 “arguments”
- 不能使用 with 语句
- this 不能指向全局对象,函数中的 this 为 undefined
词法结构
字符集
- JavaScript 是用 Unicode 编写的,因此代码中可以使用任何字符
- 区分大小写,标识符定义和引用必须一致
- JavaScript 会忽略空格和换行符,因此可以随意缩进换行统一编码风格
- 无法输入的字符,使用 Unicode转义序列(\uFFFF)
直接量
程序中直接使用的数据
标识符
- 标识符就是一个名字,作为变量或函数的名称,或者循环语句跳转位置的标记
- 必须以 字母、数字、下划线(_)、美元符($) 进行命名
- 必须以 字母、下划线(_)、美元符($) 开始
保留字
JavaScript 预先声明的标识符,用作自己的关键字,程序中不能再重新定义这些标识符
分号
- 分号(;) 用于将 语句 分开
- 语句独占一行,可以省略分号(;)
- 缺少分号(;),语句作为下一条语句的开始
- 缺少了分号(;)的多行语句,上下行语句作为代码无法正常解析时,JavaScript 会自动在两条语句间添加分号(;)
- “(“, “[“, “/“, “+”, “-“ 开始的语句极有可能和前一条语句一起解析
- 常见解决:在他们之前添加 分号(;)
- return, break, continue 独占一行,一定会添加分号(;)
代码结构
书写位置
行内
- 事件
- 事件触发时,执行一段JavaScript代码
- 伪协议(javascript:)
- 触发默认动作时,执行一段JavaScript代码
1 | |
script 标签
1 | |
js 文件
引入 js 文件,script 标签中不能书写 javascript 代码
1 | |
表达式
计算出一个结果的 短语
基本表达式
- 关键字、变量、常量
- this关键字
- 字面量(null,布尔值字面量,数字字面量,字符串字面量)
- 初始化字面量(数组字面量[],对象字面量{},正则表达式字面量/ab+c/i)
- 函数表达式
- 类表达式
- 分组操作符()
- 模板字面量
`…${…}…`
左值表达式
- 属性访问符
- new
- 元属性:new.target
- super
- 函数调用
- 参数列表(arguments, …arguments)
- import
立即调用函数表达式(IIFE)
(function(){...})()
运算符
- 一元
delete, void, typeof, +, -, ~, !
- 算术
+, -, /, *, %, A++, A–, ++A, --A
- 比较
<, >, <=, >=, in, instanceof, ==, ===, !==, !===
- 条件
condition ? ifTrue : ifFalse
- 赋值
=, -=, +=, *=, /=, &=, |=, 解构赋值如[a, b] = [1, 2]、{a, b} = {a: 1, b: 2}等
- 逗号
,
- 位移,二进制,二元逻辑
<<, >>, >>>; &, ^, |; &&, ||等
语句
使某件事发生的 整句
声明语句
- 变量声明
var, let, const
- 函数声明
function, 生成器函数, async函数
- 类声明
class
流程语句
- 块语句
{...}
- 空语句
;
- 迭代语句
while/do...whilefor/for…of/for…in/for await…of
- 条件语句
ifswitch
- 跳转语句
breakcontinuethrowtry…catchreturn
其他语句
- debugger
- 设置断点
- export
- 导出
- import
- 导入
- label
- 别名
- with
- 扩展作用域链
表达式语句
任何表达式都可以成为语句,需要使用表达式的副作用(而不在意表达式返回的值),此处的表达式叫做 表达式语句。如:
- 赋值表达式:返回右边的值。
- 副作用:将值赋给了左边的变量
- 函数调用表达式:返回函数运行结果
- 副作用:函数的运行过程
运算符
| 归类 | 优先级 | 运算符 | 说明 | 结合性 |
|---|---|---|---|---|
| 符号 | 20 | ( ... ) | 圆括号 | n/a |
| 19 | ... . ... | 属性访问 | 从左到右 | |
| ... [ ... ] | 需计算的属性访问 | 从左到右 | ||
| new ... ( ... ) | new (带参数列表) | n/a | ||
| 18 | ... ( ... ) | 函数调用 | 从左到右 | |
| new ... | new (无参数列表) | 从右到左 | ||
| 一元运算符 | 17 | ... ++ | 后置递增 | n/a |
| ... -- | 后置递减 | n/a | ||
| 16 | ! ... | 逻辑非 | 从右到左 | |
| ~ ... | 按位非 | 从右到左 | ||
| + ... | 一元加法 | 从右到左 | ||
| - ... | 一元减法 | 从右到左 | ||
| ++ ... | 前置递增 | 从右到左 | ||
| -- ... | 前置递减 | 从右到左 | ||
| typeof ... | 类型查询 | 从右到左 | ||
| void ... | 表达式返回undefined | 从右到左 | ||
| delete ... | 删除对象属性 | 从右到左 | ||
| 算数运算符 | 15 | ... ** ... | 幂运算 | 从右到左 |
| 14 | ... * ... | 乘法 | 从左到右 | |
| ... / ... | 除法 | 从左到右 | ||
| ... % ... | 取模 | 从左到右 | ||
| 13 | ... + ... | 加法 | 从左到右 | |
| ... - ... | 减法 | 从左到右 | ||
| 位移运算符 | 12 | ... << ... | 安位左移 | 从左到右 |
| ... >> ... | 安位右移 | 从左到右 | ||
| ... >>> ... | 无符号右移 | 从左到右 | ||
| 比较运算符 | 11 | ... < ... | 小于 | 从左到右 |
| ... <= ... | 小于等于 | 从左到右 | ||
| ... > ... | 大于 | 从左到右 | ||
| ... >= ... | 大于等于 | 从左到右 | ||
| ... in ... | 原型链中查找属性 | 从左到右 | ||
| ... instanceof ... | 对象是否是函数实例 | 从左到右 | ||
| 10 | ... == ... | 等于 | 从左到右 | |
| ... != ... | 不等于 | 从左到右 | ||
| ... === ... | 全等 | 从左到右 | ||
| ... !== ... | 不全等 | 从左到右 | ||
| 位运算符 | 9 | ... & ... | 按位与 | 从左到右 |
| 8 | ... ^ ... | 按位异或 | 从左到右 | |
| 7 | ... | ... | 按位或 | 从左到右 | |
| 逻辑运算符 | 6 | ... && ... | 逻辑与 | 从左到右 |
| 5 | ... || ... | 逻辑或 | 从左到右 | |
| 4 | ... ? ... : ... | 三目运算符 | 从右到左 | |
| 赋值运算符 | 3 | ... = ... | 赋值 | 从右到左 |
| ... += ... | ||||
| ... -= ... | ||||
| ... *= ... | ||||
| ... /= ... | ||||
| ... %= ... | ||||
| ... <<= ... | ||||
| ... >>= ... | ||||
| ... >>>= ... | ||||
| ... &= ... | ||||
| ... ^= ... | ||||
| ... |= ... | ||||
| 生成器 | 2 | yield ... | 生成器 | 从右到左 |
| yield* ... | 生成器 | 从右到左 | ||
| 展开运算符 | 1 | ... xxx | 展开运算符 | n/a |
| 逗号 | 0 | ... , ... | 逗号 | 从左到右 |
术语
- 操作数:运算符需要的参数
- 一元运算符:只需要一个操作数的运算符
- 二元运算符:需要两个操作数的运算符
优先级和结合性
- 优先级:表达式有多个运算符,根据优先级决定运算符执行先后顺序
- 结合性:相同优先级的运算符在同一个表达式中,且没有括号的时候,运算符和操作数的结合(组合)方式
运算顺序
先计算操作数,再计算运算符:运算符的优先级和结合性决定了复杂表达式的运算顺序,但是没有规定各 操作数(子表达式) 运算的顺序
- 操作数(子表达式) 依据从左往右的顺序依次计算
- 其值(操作数的值)再依据运算符的优先级和结合性的运算顺序计算复杂表达式
1 | |
“+” 运算符
连接字符串 “+”
- “+” 被用于字符串,会将两个字符串合并连接
- 一个操作数是字符串,另一个也将转换为字符串并合并连接
- 只有二元运算符 “+” 具有连接字符串效果,其他算术运算符总是将数据转换为 number
转化数字 “+”
- 一元运算符 “+”,会将任意类型操作数转换为 nunber,并返回转换后的 number(原始值不变)
- 效果等同于 Number(…)
“比较” 运算符
- 比较的结果为 Boolean 类型
- 字符串比较:是按照字母顺序逐个比较,相同的话比较下一个字母
- 不同类型比较:操作数先转换为 number ,然后进行比较
- 相等运算符(==):自动类型转换
- 严格相等运算符(===):不会进行类型转换
- undefined、null
- undefined == null 值为 true(特例)
- undefined === null 值为 false
- undefined、null 配合 相等运算符(==),不会转换类型为 number,因此总为 false 【undefined == null 是个特例规定如此】。配合其他操作符则正常转换为 number
1
2
3
4
5null == 0 // false 不转换为 number
null >= 0 // true 转为 0
undefined == 0 //false 不转换为 number
undefined >= 0 //false 转为 NaN
“逻辑” 运算符
逻辑与 “&&”
操作数从左往右计算,遇到 false(假值)操作数,直接返回,且不计算右侧操作数
- 两个操作数都是布尔值:一个是 false 则返回 false,都是 true 时才返回 true
- 操作数是 “真值” 或 “假值”
- 操作数按从左往右,总返回第一个 “假值”
- 两个操作数都为 “真值”,则返回右边操作数的值
总结:总在寻找 “假值”,碰到 “假值” 就返回
逻辑或 “||”
操作数从左往右计算,遇到 true(真值)操作数,直接返回,且不计算右侧操作数
- 两个操作数都是布尔值:一个是 true 则返回 ture,都是 false 时才返回 false
- 操作数是 “真值” 或 “假值”
- 操作数按从左往右,总返回第一个 “真值”
- 两个操作数都为 “假值”,则返回右边操作数的值
总结:总在寻找 “真值”,碰到 “真值” 就返回
逻辑非 “!”
- 先将操作数转换为布尔值
- 然后取反
- 总返回 true/false
“in” 运算符
- 属性在指定对象原型链上,返回 true
- 不存在的属性,返回 false
- 属性值为 undefined 返回 true
"a" in obj
使用
- 左操作数:字符串(属性名)
- 右操作数:对象
- 返回:布尔值
“instanceof” 运算符
左侧对象是右侧类(或子类)的实例,返回 true
obj instanceof Fun
使用
- 左操作数:实例对象
- 右操作数:类
- 返回:布尔值
“eval” 运算符
- 既是运算符,也是全局函数
- 运行 JavaScript 代码组成的字符串。先编译,后执行
- 编译字符串
- 编译失败:抛出语法错误异常
- 编译成功:执行此代码
- 返回值
- 返回字符串最后一个表达式或语句的值
- 最后一个表达式或语句没有值,返回 undefined
- 编译字符串
- 字符串中变量的作用域,为调用 eval 函数时所在的作用域,可以调用所在作用域的变量或声明变量 【相当于在调用 eval 函数的作用域中,声明并执行了代码】
- 给 eval 函数定义别名,通过别名调用,其字符串中变量作用域为全局环境 【相当于在全局环境中,声明并执行了代码】
- 严格模式下,局部作用域中调用 eval 不能声明变量或函数
使用
eval("var a = 1;alert(a)")
参数:一个字符串,如果不是字符串,则返回此参数
“typeof” 运算符
返回表示操作数类型的字符串typeof xx
| 操作数 | 类型(字符串) |
|---|---|
| undefined | “undefined” |
| null | “object” |
| true/false | “boolean” |
| 数字/NaN | “number” |
| 字符串 | “string” |
| 函数 | “function” |
| 内置对象(非函数) | “object” |
| 宿主对象(运行环境生成的对象) | 编译器实现的不同字符串 |
| 自定义对象 | “object” |
“delete” 运算符
delete o.x
- 删除对象属性或数组元素
- 删除一个不允许删除的属性,返回 false(严格模式报错)。除此以外删除任何操作数(即使不存在)都将返回 true
“void” 运算符
void "abc"
操作数正常计算,忽略计算结果返回 undefined 【使表达式返回 undefined】
“,” 运算符
i = 0 , 1+3
先计算左侧操作数,再计算右侧操作数,返回右侧操作数值 【相当于表达式分隔符】
注释
注释内容不会在浏览器进行加载
单行注释
1 | |
多行注释
1 | |
变量/常量
变量
声明方式
- var
- var a
- var a = 1
- var a,b,c
- var a=1,b=2,c=3
- let
- let a
- let a = 1
- let a,b,c
- let a=1,b=2,c=3
var
- 声明变量时没赋值,值为 undefined
- 可以重复声明
- 重复声明未赋值没任何变化
- 重复声明且赋值相当于简单赋值语句
- 全局作用域创建的变量,此变量会默认成为全局对象的一个属性
- 给未声明变量赋值,此变量会默认成为全局对象的一个属性
- 变量提升:变量声明被提前至作用域顶部(只是声明提升到作用于顶部并未赋值,因此值为 undefined)
1
2
3
4
5
6var scope = "global"
function f(){
console.log(scope); //输出 undefined (变量声明提前,局部变量覆盖全局变量,值为 undefined)
var scope = "local"; //进行初始赋值
console.log(scope); //输出 local
}
let
- 全局作用域中创建变量,不会作为全局对象的属性
- 具有块级作用域
- 不能重复声明,包裹用 var/const 声明(let 前后声明),都会报错
- 不能变量提升,声明之前访问会报错(处于未初始化状态),而不是 undefined
- 全局作用域创建的变量,不作为全局对象属性
常量
声明方式
- const a = undefined
const
- const 声明的变量称为 “常量”
- 声明变量时必须赋初始值(初始化变量),否则报错
- 初始化的值不能被修改
- 具有块级作用域
- 不能重复声明,包裹用 var/let 声明(const 前后声明),都会报错
- 不能变量提升,声明之前访问会报错(处于未初始化状态),而不是 undefined
变量作用域 / 闭包
变量作用域
什么是变量作用域
程序 源代码中,定义这个变量的区域
变量作用域的作用
限制可用范围:变量在其所在作用域之外不可见(无法被访问),只在其作用域中可以被访问
变量作用域分类
- 块级作用域:{ … }
- 函数作用域:function(){ … }
- 全局作用域:…
只有 let 、const 声明的变量(常量),具有块级作用域,var 声明的变量没有块级作用域
作用域链
基础概念
- 词法环境(Lexical Environment)
- 特性:
- JavaScript 内部(隐藏)的 特殊对象
- 函数、代码块{…}、全局环境 都有对应的 词法环境
- 组成部分:
- 环境记录(Environment Record):存储对应环境中的变量作为其属性的对象
- 外部词法环境的引用:用于引用外部词法环境,从
[[Environment]]获取
- 特性:
- 全局环境没有外部词法环境
[[Environment]]:函数初始化时 自动创建的隐藏属性,保存着创建函数时所在词法环境的引用(外部词法环境的引用)
作用域原理
- 变量声明
- 所在 环境 开始运行时(函数运行时),对应 词法环境 就会填充对应 作用域 中将会声明的所有变量
- 这就是变量提升的原因
- var 声明的变量填充后直接进行 初始化
- let、const 声明的变量填充后处于 未初始化 状态
- 所在 环境 开始运行时(函数运行时),对应 词法环境 就会填充对应 作用域 中将会声明的所有变量
函数声明
- 所在 环境 开始运行时,对应 词法环境 就会填充对应 作用域 中将会声明的所有函数(使用语句声明)
- 填充后的函数直接 初始化

- 函数初始化时,会 创建隐藏属性
[[Environment]],指向创建函数时所在词法环境(外部词法环境)
函数调用
- 函数调用刚开始时,就会自动创建一个新的词法环境以存储这个调用函数的局部变量和参数
- 这个词法环境对外部词法环境的引用从
[[Environment]]隐藏属性中获取 - 当代码要访问一个变量时,首先会搜索内部词法环境,然后搜索外部词法环境,以此类推形成 作用域链
闭包
什么是闭包
闭包:是指一个函数可以记住其外部变量并可以访问这些变量
实现方式
- makeCounter() 函数初始化时,具有隐藏属性指向外部词法环境
- makeCounter() 被调用时,创建新词法环境,通过隐藏属性指向外部词法环境
- 执行到 return 之后,初始化一个匿名函数,此函数具有隐藏属性指向外部词法环境(makeCounter() 被调用时的词法环境)
- 调用匿名的函数,创建新的词法环境,并可以引用 makeCounter() 被调用时的词法环境

基本数据类型
数字
基础概念
- 不区分整数和浮点数,均用浮点数表示
- 整数范围:-2⁵³ ~ 2⁵³
直接量
- 代码书写的数字形式,底层都是以二进制进行计算,返回展示的结果还是10进制
- 整数:
- 十进制:0、3、100
- 八进制:014、057、077
- 十六进制:0xff、0X19AB
- 浮点数:
[digits][.digits][(E|e)[(+|-)]digits]- 3.14
- .25 // 0.25
- 6.02e23 // 6.02 * 10²³
- .25E-32 // 0.25 * 10ˉ³²
- 全局变量
- ±infinity
- 正负无穷大
- 数字超出 ±1.7976931348623157 * 10³⁰⁸
- NaN
- 非数字
- 与任何数的计算都为 NaN
- NaN 与任何数都不相等,包括 NaN 自身
- ±infinity
算数运算不报错
- “溢出”:返回 ±infinity (正负无穷大)(数字超出 ±1.7976931348623157 * 10³⁰⁸)
- “下溢”:返回 0 (数字小于 ±5 * 10ˉ³²⁴)
- “…/0”:返回 ±infinity
- “0/0”:返回 NaN
- 所有不适用于算数运算的操作数,计算结果都将返回 NaN
常用方法
| 方法 | 调用 | 参数 | 作用 |
|---|---|---|---|
| Math.abs( ) | Math 类 | 1:±数字 | 返回一个数的绝对值 |
| Math.ceil( ) | Math 类 | 1:±数字 | 返回大于等于参数,并且与它最接近的整数 |
| Math.floor( ) | Math 类 | 1:±数字 | 返回小于等于参数,并且与它最接近的整数 |
| Math.trunc( ) | Math 类 | 1:±数字 | 返回舍弃小数部分的整数 (与 floor() 区别在于,负数时 floor() 返回值远离 0,trunc() 直接舍弃小数部分) |
| Math.round( ) | Math 类 | 1:±数字 | 返回四舍五入的整数 |
| Math.min( ) | Math 类 | 1,2,3…±数字 | 返回指定一组数字中最小值 |
| Math.max( ) | Math 类 | 1,2,3…±数字 | 返回指定一组数字中最大值 |
| Math.sqrt( ) | Math 类 | 1:+数字 | 返回的是一个数的平方根 |
| Math.sqrt( ) | Math 类 | 1:+数字 | 返回的是一个数的平方根 |
| Math.pow( ) | Math 类 | 1:±数字 2:±数字 |
返回 参数1 的 参数2 次幂 |
| Math.random( ) | Math 类 | 无 | 返回 0(包含) ~ 1(不包含) 之间的一个随机数 |
字符串
基础概念
- 使用 UTF-16 编码的 unicode 字符集
- 字符串是固定不变的,对字符串的所有操作都是返回新字符串,原字符串不变
- 字符串位置从 0 开始
- JavaScript 中每个字符由16位内码表示
- JavaScript 中字符串是由16位值组成的序列
- 对字符串的操作也是基于16位内码进行,而非针对字符进行的操作
- 因此字符个数有时不等于字符串长度(length),一个字符可能由两个16位值组成
直接量
- 双引号、单引号、反引号 引起来的字符
- 字符串符号,可以包含不能穿插
- 换行显示:
\n - 换行定义单行显示:
- 每行结尾用 \
- 下一行从文本开头算起(包含空格)
1
2
3
4
5
6"aaaaaa\
bbb\
ccccc"
// 输出
aaaaaa bbb ccccc
转义字符
转义字符:代表新含义的字符组合
- \ 配合一个字符,不代表字符原本含义
- \u 配合4个十六进制数,可以指定的任意 Unicode 字符
- \x 配合2个十六进制数,可以指定 Latin-1 字符
| \ 转义字符 | 含义 | \u 转义字符 |
|---|---|---|
| \0 | 空字符(NUL) | \u0000 |
| \b | 退格符 | \u0008 |
| \t | 水平制表符 | \u0009 |
| \n | 换行符 | \u000C |
| \v | 垂直制表符 | \u000B |
| \f | 换页符 | \u000C |
| \r | 回车符 | \u000D |
| " | 双引号 | \u0022 |
| ' | 单引号 | \u0027 |
| \\ | 反斜杠 | \005C |
| \xXX | Latin-1 字符 | |
| \uXXXX | Unicode 字符 |
常用方法
| 方法 | 调用 | 参数 | 作用 |
|---|---|---|---|
| charAt( ) | 字符串 | 1:+数字 | 返回字符串指定位置字符 |
| indexOf( ) | 字符串 | 1:字符/串 2:+数字【可选】 |
字符串中从前往后找,返回指定字符(字符串)在字符串中首次出现位置,没有找到返回 -1 参数2:从指定位置开始找,没有的话从0开始 |
| lastIndexOf( ) | 字符串 | 1:字符/字符串 2:+数字【可选】 |
字符串中从后往前找,返回指定字符(字符串)在字符串中首次出现位置,没有找到返回 -1 参数2:从指定位置开始找,没有的话从0开始 |
| slice( ) | 字符串 | 1:±数字 2:±数字【可选】 |
返回字符串指定范围字符 【参数1开始 ~ 参数2之前】 负数从尾部开始数【-1 表示最后一个字符】 没有参数2:表示返回指定字符到最后一个字符 |
| substring( ) | 字符串 | 1:+数字 2:+数字【可选】 |
返回字符串指定范围字符 【参数1开始 ~ 参数2之前】 不能使用负数 没有参数2:表示返回指定字符到最后一个字符 |
| split( ) | 字符串 | 1:字符【可选】 2:+数字【可选】 |
依据指定字符拆分为数组 没有参数:数组[0] 为整个字符串 参数是空字符串””:数组元素为每个字符 参数2:设置拆分数组的长度,没有参数才分所有字符 |
| replace( ) | 字符串 | 1:字符/串/正则 2:字符/串 |
将字符串中 参数1 指定的字符/串/正则替换为 参数2 指定的字符/串 只替换首个匹配的字符/串/正则 要替换所有匹配使用正则 /…/g 区分大小写,不匹配大小写不同的字符 匹配时不区分大小写:使用正则 /…/i |
| replaceAll( ) | 字符串 | 1:字符/串/正则 2:字符/串 |
将字符串中 参数1 指定的字符/串/正则替换为 参数2 指定的字符/串 替换所有匹配的字符/串 区分大小写,不匹配大小写不同的字符 匹配时不区分大小写:使用正则 /…/i |
| includes( ) | 字符串 | 1:字符/串 2:+数字【可选】 |
判断字符/串是否包含在字符串中,返回true/false 区分大小写,不匹配大小写不同字符 参数2:从指定位置开始查找,没有参数从0开始 |
| match( ) | 字符串 | 1:正则 | 根据正则表达式匹配对应字符串,匹配到的字符串组织成数组返回 区分大小写 |
| search( ) | 字符串 | 1:字符/串/正则 | 从字符串中查找字符/串/正则,找到的话返回下标,没有找到返回 -1 只匹配第一个字符/串/正则,即使正则 /…/g 也只匹配返回第一个字符/串下标 区分大小写,正则 /…/i 可以不区分大小写 |
| toLowerCase( ) | 字符串 | 无 | 字符串转换为小写 |
| toUpperCase( ) | 字符串 | 无 | 字符串转换为大写 |
| trim( ) | 字符串 | 无 | 删除字符串的头尾空白符,空白符包括:空格、制表符 tab、换行符等其他空白符 |
布尔值
基础概念
- 值:true / false
- 任何值都可以转换为布尔值
“真值” 和 “假值”
可以转换成 false 的值,就称为 “假值”。其他所有值都会转换成 true,这些值都是 “真值”
“假值” 如下:
- undefined
- null
- ±0
- NaN
- “”
null
- JavaScript 中的关键词
- 用来描述 “空值”
- typeof 运算返回 “object”,null 是一个特殊的对象值
- 通常将 null 当作 JavaScript 自己所有类型唯一的一个成员,表示 数字 , 字符串 ,对象 是 “无值” 的
undefined
- 预定义的全局变量,不是关键词
- typeof 运算返回 “undefined”,undefined 是 undefined 类型的唯一值
- 表明变量没有初始化
- 查询属性或元素返回 undefined,说明属性元素不存在
- 函数没有返回值,返回 undefined
- 没有实参的函数形参也是 undefined
bigint
symbol
引用类型
全局对象
- 全局对象的属性是全局定义的,JavaScript 程序可以直接使用
- JavaScript 解释器启动时,或web浏览器加载新页面时,将会创建一个新的全局对象,并给一组定义的初始属性
- 全局属性:如 undefined、Infinity、NaN、全局变量
- 全局函数:如 isNaN( )、parseInt( )、eval( )
- 构造函数:如 Date( )、RegExp( )、String( )、Object( )、Array( )
- 全局对象:如 Math、JSON
全局对象引用
- 代码最外层(不在任何函数内),this 指向全局对象
- 浏览器中全局 Window 对象的属性 window,引用全局对象
包装对象
什么是包装对象
存取基本数据类型 “字符串”,“数字”,“布尔值” 的属性时,创建的对象。
包装对象的作用
- 使基本数据类型可以像对象一样,调用其属性和方法
- 用于区分 “字符串”—“字符串对象”、“数字”—“数值对象”、“布尔值”—“布尔对象”
原理
基本数据类型 “字符串”、“数字”、“布尔值”,使用 . 访问他们的属性,JavaScript 就会将基本类型数据通过调用 new 构造函数转换成对象,通过这个对象调用其属性和方法,属性引用结束,这个对象就会被销毁
特性
- 包装对象的属性都是只读的
1
2
3var s = "test"; // 声明变量并初始化
s.len = 4; // 创建临时字符串对象,并添加属性 len,并赋值为 4,调用结束销毁这个字符串对象
var t = s.len; // 创建一个新的字符串对象,没有 len 属性,因此返回 undefined - JavaScript 会在必要时将包装对象转换成原始值
- 显示 “==” 比较
- 隐式类型转换时
1
2
3
4
5
6var a = "abcde"
var aa = new String("abcde");
console.log(a==aa); // true
console.log(a===aa); // false
typeof a // "string"
typeof aa // "object"
类型转换
类型转换表
| 原始值 | 转换为 | ||||
|---|---|---|---|---|---|
| 字符串 | 数字 | 布尔值 | 对象 | ||
| 标识符/关键词 | undefined | "undefined" | NaN | false | throws TypeError |
| null | "null" | 0 | false | throws TypeError | |
| 布尔值 | true | "true" | 1 | 自身 | new Boolean(true) |
| false | "false" | 0 | 自身 | new Boolean(false) | |
| 字符串 | ""(空字符串) | 自身 | 0 | false | new String("") |
| "1.2"(非空,数字) | 自身 | 1.2 | true | new String("1.2") | |
| "one"、"a123"、"123b"(非空,非数字) | 自身 | NaN | true | new String("one") | |
| 数字 | 0 | "0" | 自身 | false | new Number("0") |
| -0 | "0" | 自身 | false | new Number("-0") | |
| NaN | "NaN" | 自身 | false | new Number(NaN) | |
| Infinity | "Infinity" | 自身 | true | new Number(Infinity) | |
| -Infinity | "-Infinity" | 自身 | true | new Number(-Infinity) | |
| 123 | "123" | 自身 | true | new Number(123) | |
| 引用类型 | { }(任意对象) | 3.8.3 | 3.8.3 | true | 自身 |
| [ ](任意数组) | " " | 0 | true | 自身 | |
| [9](一个数字元素) | "9" | 9 | true | 自身 | |
| ['a'](其他数组) | 使用 join() 方法 | NaN | true | 自身 | |
| function(){...}(任意函数) | 3.8.3 | NaN | true | 自身 | |
显示类型转换
基础类型转换
不通过 new 调用函数,函数作为类型转换函数
- Boolean()
- Number()
- String()
- Object():传入基本类型数据转换为对应包装对象
- 调用 toString() 方法
- null、undefined 没有属性或方法,调用 toString() 会报错
数字转字符串
数字转换为指定进制字符串
- 转二进制字符串:xx.toString(2)
- 转八进制字符串:xx.toString(8)
- 转十六进制字符串:xx.toString(16)
数字转换为指定有效数字符串:
- xx.toFixed()
- xx.toExponential()
- xx.toPrecision()
字符串转数字
使用 parseInt()、parseFloat() 全局函数将字符串转换为数字
- parseInt()
- 根据字符串前缀 “0x”、“0X” 将字符串当作十六进制转换为10进制数字
- 会忽略前导空格,尽可能解析数值字符,并忽略后面非数值字符
- 第一个非空字符是非数字,则返回 NaN
- 第二个参数,指定字符串以相应进制进行解析,返回10进制数字。(取值范围:2~36)
- parseFloat()
- 会忽略前导空格,尽可能解析数值字符(包括 . 符号),并忽略后面非数值字符
- 第一个非空字符是非数字(. 符号除外),则返回 NaN
隐式类型转换
JavaScript 期望使用一种类型数据时,实际可以使用任意类型数据,JavaScript 将根据需要自动转换类型
对象转原始值
- 所有对象都继承了 toString()、valueOf() 方法
- 本地对象通过 toString()、valueOf() 方法转换为字符串、数值
- 宿主对象(例如:web浏览器定义的对象)根据各自算法转换成特定字符串或数字(宿主对象有自己特有的字符串、数值)
- 本地对象:ECMAScript 实现中,并非由宿主环境,而是完全由本规范定义其语义的对象
对象转布尔值
都是 true
对象转字符串
宿主对象 toString() 返回值:
- 数组:元素转换为字符串,元素间添加逗号后合并起来的字符串
- 函数:函数定义的字符串形式
- 日期类:可读的日期和时间字符串
- RegExp:返回正则字面量字符串形式
本地对象转字符串过程:
- 尝试调用 toString() 方法
- 如果返回原始值,原始值转换为字符串并返回
- 没有 toStrinig() 方法,或者没有返回原始值,则调用 valueOf() 方法
- 如果返回原始值,原始值转换为字符串并返回
- 如果 toString()、valueOf() 都无法返回原始值,抛出类型错误
对象转数值
宿主对象 valueOf() 返回值:
- 日期类:返回1970年1月1日以来的毫秒数
- 包装对象:valueOf() 返回其对应的原始值
- 本地对象:valueOf() 默认返回对象本身
本地对象转数字过程:
- 尝试调用 valueOf() 方法
- 如果返回原始值,原始值转换为数字并返回(本地对象默认返回对象本身)
- 没有 valueOf() 方法,或者没有返回原始值,则调用 toString() 方法
- 如果返回原始值,原始值转换为数字并返回
- 如果 toString()、valueOf() 都无法返回原始值,抛出类型错误
ES6
DOM
BOM
弹窗
alert
警示、警告弹窗
1 | |
prompt
提示 弹窗
用户根据提示输入内容,获取用户输入内容
- 参数
- 提示内容
- 初始默认值
- 返回值
- 点击确定:返回用户输入值(都是字符串)(无内容为空字符串)
- 点击取消:返回null
1 | |
confirm
确认 弹窗
- 参数
- 提示内容
- 返回值
- 点解确定:返回 true
- 点击取消:返回 false
1 | |
