沈琪云的ECMAScript2015学习笔记
2021-04-26 21:28:54 4 举报
AI智能生成
es6学习笔记
作者其他创作
大纲/内容
es6
1、块级作用域绑定
块级声明
let声明
禁止重声明
const声明
一旦设定不可更改
临时死区
循环中的块作用域绑定
ES6 声明变量的六种方法
var
var 声明及变量提升机制
无论在哪里声明,都会被当作当前作用域顶部声明的变量
function
const
class
let
import
函数
es6的默认参数值
可以为其提供初始值
默认参数值对arguments对象的影响
在非严格模式下,命名参数的变化会同步更新到arguments的对象中
在严格模式下。,命名参数的变化,不会导致arguments改变
展开运算符
明确函数的多种用途
js函数有两个不同的内部方法:[[call]]和[[construct]].
通过nwe关键字调用函数的是[[construct]]
创建一个被称为实例的新对象
执行函数体
将this绑定到实例上
不通过new关键字调用函数是[[call]]
在es5中判断函数被调用的方法
用instanceof
元属性 new.target
为了解决判断函数是否通过new关键字调用的问题
解决了在es5中,call方法也能不通过new创建而通过es5中的判断
必须通过new关键字调用
块级函数
块级作用域内部的函数在块级之前的外面也可以访问到,在块级结束后,会将该函数移除
es6将其标准化
箭头函数
差异
与传统函数的不同
没有this、super、argument、new.target绑定
这些值由外围最近一层非箭头函数决定
不能通过new关键字调用
没有原型
不可以改变this的绑定
不支持arguments对象
没有自己的arguments对象,但可以访问外围的函数的arguments对象
不支持重复的命名参数
差异产生的原因
this绑定丢失
减少错误以及理清模糊不清的地方。
箭头函数也有一个name属性值
语法
创建立即执行函数表达式
你可以定义一个匿名函数并立即调用,自始自终不保存对函数的引用。当想创建一个与其他程序隔离的作用域时,这种模式非常方便
箭头函数与正常函数创建的立即执行函数表达式的不同
小括号只包裹箭头函数定义,没有包含(‘Nicholas’)
正常函数定义的立即执行函数表达式既可以用小括号包裹函数体,也可以额外包裹函数调用部分
箭头函数内没有this绑定
箭头函数与数组
箭头函数没有arguments绑定
没有自己的arguments对象,但可以访问外围的函数的arguments对象
尾调用优化
尾调用指的是函数作为另一个函数的最后一条语句被调用
es6中对尾调用的优化
作用:
缩减了严格模式下尾调用栈的大小
条件
满足以下条件,尾调用不再创建新的栈顶,而且清除并重用当前的栈帧
尾调用不访问当前栈帧的变量
在函数内部,尾调用是最后一条语句
尾调用的结果作为函数值返回
扩展对象的功能性
对象类别
普通(ordinary)对象
具有js对象所有的默认内部行为
特异(Exotic)对象
具有某些与默认行为不符的内部行为
标准(standard)对象
ECMAScript 6规范中定义的对象
标准对象既可以是普通对象,也可以是特意对象
内建对象
脚本开始执行时存在于JavaScript执行环境中的对象
所有标准对象都是内建对象
对象字面量语法扩展
属性初始值的简写
当一个对象的属性与本地变量同名时,不必再写冒号和值,简单的只写属性名即可
对象方法的简写语法
消除了冒号和function关键字
区别:简写方法可以使用super关键字
可计算的属性名
用方括号包含变量名,会算出变量名的值,来当属性名
新增方法
Object.is()
弥补全等运算符的不准确运算
与全等运算符(===)唯一的区别,时能识别+0,-0;NaN与NaN
Object.assign()
混合(Mixin)时js实现对象组合最流行的一种模式
在一个mixin方法中,一个对象接收l来自了另一个对象的属性和方法
Object.assign()方法可以接受任意数量的源对象,并按指定的顺序将属性复制到接受对象中。
如果多个源对象具有同名属性,则排位靠后的源对象会覆盖排位靠前的。
不能将提供者的访问器属性复制到接收对象中,但会将其转变为接收对象的一个属性
自由属性枚举规则
规则
所有数字键按升序排序
所有字符串键按照他们被加入对象的顺序排序
所有symbol键按照他们加入对象的顺序排序
涉及到的方法
Object.getOwnPropertyNames()方法
Reflect.ownKeys
Object.getOwnPropertyNames
不会被影响到的方法
Object.keys()方法
JSON.stringify()方法
for ...in..
增强对象原型
改变对象的原型
Object.setPrototypeOf( )
参数
被改变原型的对象
替代第一个参数原型的对象
扩展
正常情况下无论是通过构造函数还是Object.create()方法创建对象,其原型是在对象创建时指定的
es5中添加了Object.getPrototypesOf( )方法来返回任意指定对象的原型
简化原型访问的Super引用
限制
必须在简写方法的对象中使用Super引用
super引用不是动态变化的,它总是指向正确的对象,
Super的苏勇引用都是通过[[HomeObject]]属性来确定后续的运行过程。
第一步,是在[[HomeObject]]属性上调用Object。getPrototypeOf()方法来检索原型的引用;
通过原型找到同名函数
设置this绑定并且调用相应的方法
正式的方法定义
[[HomeObject]]属性
用途
用来容纳这个方法从属的对象
5、解构:使数据访问更加便捷
基本用法
这种写法属于“模式匹配”,只要等号两边的模式相同,左边的变量就会被赋予对应的值。下面是一些使用嵌套数组进行解构的例子。
只要某种数据结构具有 Iterator 接口,都可以采用数组形式的解构赋值
如Set,Map,Generator(生成器)
不完全解构
报错
如果解构不成功,变量的值就等于undefined。
如果等号的右边不是数组(或者严格地说,不是可遍历的结构,参见《Iterator》一章),那么将会报错
对象的解构赋值
对象的解构与数组有一个重要的不同
数组的元素是按次序排列的
对象变量必须与属性同名,才能取到正确的值
如果变量名与属性名不一致,必须写成这样。
对象的解构也可以指定默认值
嵌套赋值
数组本质是特殊的对象,因此可以对数组进行对象属性的解构。
失败
如果解构失败,变量的值等于undefined
如果解构模式是嵌套的对象,而且子对象所在的父属性不存在,那么将会报错。
如果要将一个已经声明的变量用于解构赋值,必须非常小心。
解构赋值允许等号左边的模式之中,不放置任何变量名。
对象的解构赋值,可以很方便地将现有对象的方法,赋值到某个变量。
字符串的解构赋值
原因
字符串也可以解构赋值。这是因为此时,字符串被转换成了一个类似数组的对象。
类似数组的对象都有一个length属性,因此还可以对这个属性解构赋值。
数值和布尔值的解构赋值
解析赋值的规则
只要等号右边的值不是对象或数组,就先将其转为对象。由于undefined和null无法转为对象,所以对它们进行解构赋值,都会报错。
圆括号问题
函数参数的解构赋值
建议只要有可能,就不要在模式中放置圆括号。
不能使用圆括号的情况
1)变量声明语句
2)函数参数
3)赋值语句的模式
用途
交换变量的值
从函数返回多个值
函数参数的定义
提取 JSON 数据
函数参数的默认值
指定参数的默认值,就避免了在函数体内部再写var foo = config.foo || 'default foo';这样的语句。
遍历 Map 结构
如果只想获取键名,或者只想获取键值
输入模块的指定方法
6、Symbol和Symbol属性
概述
ECMAScript5及早期版本中,语言包含5种原始类型
字符串型
数字型
布尔型、
null
undefined
ECMAScript6中引入了第6种原始类型:Symbol
创建Symbol
注意:
由于Symbol 是原始值,因此调用new Symbol会导致程序抛出错误
参数
可选
让你添加一段文本描述即将创建的Symbol
这段描述不可用于属性访问,但是建议你在每次创建Symbol时都添加这一段描述
会被存储在内部的[[Description]]属性中,只有当调用Symbol的toString()方法时,才可读取这个属性。
在执行console.log种会隐式的调用toString()方法
他的描述会被打印到日志中,但不能直接在代码中访问
Symbol的辨识方法
typeof
Symbol的使用方法
使用地点
所有使用可计算属性名
可计算对象字面量属性名
Object.defineProperty()
Object.defineProperties()方法
Symbol共享体系
创建一个可共享的Symbol
Symbol.for()方法
参数一
用途:即将创建的Symbol的字符串标识符
用途二:也作为Symbol的描述
过程
首先在全局Symbo表中搜索键为“uid”的Symbol是否存在
存在:直接返回已有的Symbol
不存在:
创建一个新的Symbol
并使用这个键在Symbol全局注册表中注册
返回新创建的Symbol
共享相关的特性
Symbol.keyFor()方法
使用该方法在Symbol全局注册表中检索与Symbol有关的键
注意:使用let uid3 = Symbol("description"),并不会在全局注册表中注册该Symbol
Symbol与类型强制转换
不能将Symbol强制转换为字符串和数字类型
子主题
Symbol属性检索
扩展
检索对象中所有的属性名
Object.key()
返回所有可枚举䣌属性名
Object.getOwnPropertyNames()
不考虑属性的可枚举性一律返回
两种方法均不支持Symbol属性
Object.getOwnPropertySymbols()
ES6新增方法
用来检索对象中的Symbol属性
返回值是一个包含所有Symbol自有属性的数组
well-known Symbol
包括
Symbol.hasInstance
用于检测对象的继承信息
一个在执行instanceof时调用的内部方法
Symbol.isConcatSpreadable
一个布尔值
用来表示当传递一个集合作为Array.prototype.concat()方法的参数时,是否应该将集合内的元素规整到同一层级
Symbol.iterator
一个返回迭代器的方法
Symbol.match
一个在调用String.prototype.match()方法时调用的方法,用来比较字符串
Symbol.replace
一个在调用String.prototype.replace()方法时调用的方法,用于替换字符串中替换子串
Symbol.search
一个在调用String.prototype.search()方法时调用的方法
用于在字符串中定位子串
Symbol.species
用于创建派生对象的构造函数
Symbol.split
一个在调用String.prototype.split()方法时调用的方法
用于分割字符串
Symbol.toPrimitive
一个返回对象原始值的方法
Symbol.toStringTag
一个在调用Object.prototye.toString方法时使用的字符串
用于创建对象描述
Symbol.unscopables
一个定义了一些不可被with语句引用的对象属性名称的对象集合
7、Set集合与Map集合
ECMAScript5中的Set与Map集合
在es5中开发者用对象属性来模拟这两种集合
该解决方案的一些问题
待完善
ECMAScript6中的Set集合
定义
是一种有序列表
含有一些相互独立的非重复值
能更有效地追踪各种离散值
是一个强引用的Set集合
创建Set集合并添加元素
方法
调用new Set()创建Set集合
调用add()方法向集合中添加元素
访问集合的size属性可以获取集合中目前的元素数量
has()
可以检测Set集合种是否存在某个值
补充:不会对所存值进行强制的类型转换
如数字5和字符串”5“可以作为两个独立元素存在
唯一的例外时+0,和-0被认为是相等的
set构造函数会过滤掉重复的值,从而保证集合中的元素各自唯一
移除元素
方法
delete()
可以移除Set集合种的某一个元素
clear()
会移除集合中的所有元素
Set集合中的forEach()方法
参数
Set集合中下一次索引的位置
参数一
与第一个参数一样的值
参数二
被遍历的Set集合本身
参数三
与数组中的forEach()的异同
Set中回调函数前两个参数的值是一样的
Map集合的forEach()方法和数组的接收的参数都是三个参数u,前两个时值和键名
值
键名
被遍历的集合
注意:你不能通过索引访问集合中的元素。如果有需要,最好先将Set集合转换成一个数组
将Set集合转换为数组
运用展开运算符(...)
它可以将数组中的元素分解为各自独立的函数参数
Weak Set集合(弱引用Set集合)
特点
Weak Set集合只存储对象的弱引用,并且不可以存储原始值;
集合中的弱引用如果是对象唯一的引用,则会被回收并释放内存
创建Weak Set集合
方法
new WeakSet()
可以创建WeakSet集合
add()
has()
delete()
参数
只能为对象或着是对象的集合
不接受任何原始值
如果包含其他非对象值,程序会抛出错误
两种Set类型的主要区别
WeakSet 保存的对象值是弱引用
最大区别
在WeakSet的实例中,如果向add()方法传入非对象参数会导致程序抛错,而向has()和delete()方法传入非对象参数则会返回false
WeakSet集合不可迭代,所以不能被用于for-of循环
WeakSet集合不暴露任何迭代器(例如keys(),values()方法),所以无法通过程序本身来检测其中的内容
WeakSet集合不支持forEach方法
WeakSet集合不支持size属性
总之:如果你只需要跟踪对象引用,你更应该使用WeakSet集合而不是普通的Set集合
Set类型可以用来处理列表中的值,但是不适用于处理键值对这样的信息结构
ECMAScript6中的Map集合
概述
es6中的Map
许多键值对
有序列表
Object.is()
等价性判断是通过该方法来实现的
所以字符串”5“和数字5会被判定为两种类型,可以分别作为两个独立的键出现在程序中
这一点与对象不太一样,对象中的属性名总会被强制转换成字符串类型
键
可以用对象作为对象属性的键名
对象不可以
方法
set(key,value)
含义
向Map集合中添加新的元素
参数
键名
参数一
value值
参数二
get(key)
含义
从集合中获取信息
参数
键名
如不存在返回‘undefined’
has(key)
检测指定的键名在Mao集合中是否已经存在
delete(key)
从Map集合中移除指定键名及其对应的值
clear(key)
移除Map集合中所有键值对
属性
size
代表当前集合种哦那个包含的键值对数量
Map集合的forEach(value,key,map)
WeakMap
是弱引用的Mao集合
键名必须是一个非null类型的对象
如果不是对象则会报错
如果在弱引用外不存在其他的强引用,引擎的垃圾回收机制会自动回收这个对象,同时移除WeakMap中的键值对
创建一个私有数据
主要问题
是否只用对象作为集合的键名
是:weakMap
相对Map集合而言,Weak Map集合对用户的可见度更低,其不支持通过
forEach()
size属性
clear()方法
8、迭代器(Iterator)和生成器(Generator)
出现该方法之前的Javascript历史问题
循环语句的问题
当多个循环嵌套则需要追踪多个变量代码复杂度会大大增加
容易错误使用了其他for循环的跟踪变量
迭代器
定义
是一种特殊对象
方法
next()方法
每次调用会返回一个结果对象
结果对象
属性
value:表示下一个将要返回的值
done:是一个bool类型,当没有更多可返回数据时返回true
迭代器会保存一个内部指针,用来指向当前集合中值的位置
每调用一次next()方法都会返回下一个可用的值
优点
可以极大地简化数据操作
es5实现方法
生成器
定义
是一个返回迭代器的函数
通过function 关键字后的星号(*)来表示
可以紧挨function关键字 也可以在中间添一个空格
yield
每当执行完一条yield语句后函数就会自动停止执行
使用限制
只可在生成器内部使用,在生成器内部的函数里使用也会报错
生成器函数表达式
注意不能使用箭头函数来创建生成器
生成器对象的方法
生成器默认会为Symbol.Iterator属性赋值,因此所有通过生成器创建的迭代器都是可迭代对象
可迭代对象和for-of循环
可迭代对象
相关定义
具有Symbol.iterator属性
Symbol.Iterator通过制定的函数返回一个作用于附属对象的迭代器
是一种与迭代器密切相关的对象
由于具有Symbol.Iterator属性的对象都有默认的迭代器因此可以用它检测对象是否为可迭代器
在ES6中所有的集合对象(数组,Set集合及Map集合)和字符串都是可迭代对象,这些对象中都有默认的迭代器
ES6中新加入的特性for-of循环需要用到可迭代对象的这些功能
创建可迭代对象
默认情况下,开发者定义的对象都是不可迭代对象
但如果给Symbol.iterator属性添加一个生成器
则可以将其变为可迭代对象
for-of循环
每执行一次
限制
用于不可迭代对象、null、或undefined 将会导致程序抛出错误
内建迭代器
集合对象迭代器
集合对象
数组
Map集合、
Set集合
迭代器
entries()
定义
返回一个迭代器
其值为多个键值对
return(返回值)
返回一个数组,数组中两个元素分别表示集合中每个元素的键与值
被遍历的对象是
数组
索引
值
Set集合
两个是相同的值
Map集合
键值(key)
值(value)
values()
定义
返回一个迭代器
其值为集合的值
keys()
定义
返回一个迭代器
其值为集合中所有键名
对于数组对象,无论是否为数组添加命名属性,打印出来的都是数字类型的索引‘
而for -in 循环迭代的是数组属性,而不是数字类型的索引
9、JavaScript中的类
ES5中的近类结构
类的声明
基本的类声明语法
建议在构造函数中创建所有自有属性
与函数不同的是,类属性不可被赋予新值,在之前的示例中PersonClass.prototype就是这样一个只可读的类属性
为何使用类语法
函数声明可以被提升,而类声明与let声明类似,不能被提升:真正执行声明语句之前,他们会一直存在于临时死区
类声明中的所有代码将自动运行在严格模式下,且无法强行让代码脱离严格模式执行
在自定义类型中,需要通过Object.defineProperty()方法手工指定某个方法为不可枚举;而在类中,所有方法都是不可枚举的
每个类都有一个名为[[construct]]的内部方法,通过关键字new调用那些不含[[construct]]的方法会导致程序抛出错误
使用除关键字new以外的方式调用类的构造函数会导致程序抛出错误
在类中修改类名会导致程序报错
额外:常量类名
类的名称只在类中为常量,
在类的方法中不能修改类名
内部是通过const命名
但可以在外部修改
外部是通过let命名
类表达式
存在形式
声明形式
由function和class定义
表达式形式
基本的类表达式语法
命名类表达式
声明时在关键字后class后添加一个标识符
作为一等公民的类
一等公民
可以传入函数,可以从函数返回,并且可以赋值给变量的值
可以将类作为参数传入函数中、
可计算成员名称
用方括号包裹一个表达式即可使用可计算名称
属性名可以设置为用[]包着的变量
生成器方法
静态成员
继承与派生类
es6之前的继承
es6的等价版本
super()
通过调用super()方法即可访问基类的构造函数。
如果在派生类欸中指定了构造函数,则必须要调用super(),如果不这样做程序就会报错。
如果选择不使用构造函数,则当创建新的类实例时会自动调用super()并传入所有参数
使用super()的小贴士
只可在派生类的构造函数中使用super()如果尝试在非派生类(不是用extends声明的类)或函数中使用则会导致程序抛出错误
在构造函数中访问this之前一定要调用super(),它负责初始化this,如果在调用super()之前尝试访问this会导致程序出错
如果不想调用super(),则唯一的方法时让类的构造函数返回一个对象
类方法遮蔽
派生类中的方法总会覆盖基类中的同名方法
静态成员继承
如果基类有静态成员,那么这些静态成员在派生类中也可以用
派生自表达式的类
只要表达式可以被解析为一个函数并且具有[[construct]]属性和原型,那么就可以用extends进行派生
动态地确定类的继承目标
创建mixin
注意:
extends后可以使用任意表达式,但不是所有表达式最终都能生成合法的类。如果使用null或生成器函数会导致错误,类在这些情况下没有[[construct]]属性
内建对象地继承(未读 p203)
Symbol.species属性
在类的构造函数中使用new.target(未读 p208)
10、改进地数组功能
创建数组
es6以前
创建数组:均需列举数组中地元素
调用Array构造函数
数组字面量
Array.of()
添加原因
帮助开发者们规避通过Array构造函数创建数组时的怪异行为
工作机制
总会创建一个包含所有参数的数组,不因参数的不同而改变
注意·:
Array.of方法不通过Symbol.species属性确定返回值的类型,他使用当前构造函数(也就是of()方法中的this值)来确定正确的返回类型
Array.from()方法
概述
es5中类数组对象转化为数组
参数一
可迭代对象或类数组对象
必选
通过this来确定返回数组类型的
映射转换
参数二
映射函数
该函数,会将类数组对象中的每一个值转换成其他形式,最后将结果储存在结果数组的相应索引中
参数三
表示映射函数的this值
可选
Array.from()转换可迭代对象
能将所有含有Symbol.iterator属性的对象转换为数组
为所有数组添加的新办法
find()方法和findIndex()方法
协助开发者在数组中查找任意值
参数
参数一
回调函数
回调函数的参数
该元素
该元素在数组中的索引值
数组本身
参数二
指定回调函数的this的值
可选
返回值
返回true时,find()方法和findIndex()方法都会立即停止
区别
find返回查找到的值
findIndex返回查找到值的索引
优点
按某个条件查找时,用find和findIndex()方法更适合
反之,按某个值匹配的元素时用indexOf和lastIndexOf()更适合
es5中
indexOf()
lastIndexOf()
缺点
只能查找一个值
fill方法
功能
用指定的值填充一至多个数组元素
传入一个值时,fill()方法会用这个值重写数组中的所有值
参数
参数一:
指定的值
参数二:
开始索引
可选
参数三
不包含结束索引
不包含结束索引当前值
可选
注意:
当索引值为负数时,这些值会与length值相加来作最终位置
copyWithin()方法
功能
从数组中复制元素的值
参数
1、
设置该位置的值,为得到的值
被粘贴的位置
paste
2、
得到该位置的值
被复制得位置
copy
3、
指定停止复制值的位置
不包含当前索引所指向的值
[set,get,get停止的位置(不包含当前位置的值)]
定型数组
概述
是一种用于处理数值类型数据的专用数组
就是将任何数字转换为一个包含数字比特的数组
引入定型数组是为了提供高性能的算术运算
数值数据类型
有符号的8位整数int8
无符号的8位整数uint8
int 16
uint16
int32
uint32
float32
float64
数组缓冲区
新建数组缓冲区
new操作符
slice()将已有的数组缓冲区来创建一个新的
通过视图操作数组缓冲区
视图:用来操作内存的接口
可以操作与数组缓冲区或缓冲区字节的子集
数据缓冲区:是内存中的一段地址
DataView类型
是一种通用的数组缓冲区视图
其支持所有8种数值型数据类型
获取视图信息
buffer
视图绑定的数组缓冲区
byteOffset
DataView构造函数的第二个参数,默认是0,只有传入参数时才有值
byteLength
DataView构造函数的第三个参数,默认是缓冲区的长度byteLength
读取和写入数据
getInt8(byteOffset,littleEndian)
setInt8(byteOffset,value,littleEndian)
getUnit8(byteOffset,littleEndian)
setUint8(byteOffset,value,littleEndian)
11、Promise与异步编程
异步编程的背景知识
事件模型
回调模式
Promise的基础知识
Promise的生命周期
状态
pending
进行中
Fulfilled
Promise异步操作成功完成
Rejected
Promise异步操作未能成功完成
方法
then()
参数
参数一:当promise状态变为fulfilled时要调用的函数
与异步操作相关附加数据都会传递给这个完成函数
参数二:当状态变为rejected状态时调用的函数
创建未完成的Promise
使用Promise的构造函数
创建已处理的Promise
使用Promise.resolve()
已完成态
使用Promise.reject()
已拒绝态
非Promise的Thenable对象
构成:
then()方法
参数1:resolve
参数2:reject
调用Promise.resolve()方法将Thenable对象转换成一个已完成的Promise
执行器错误
全局的Promise拒绝处理
Node.js环境的拒绝处理
浏览器环境的拒绝处理
unhandledrejection
当Promise被拒绝,并且没有提供拒绝处理程序时,触发该事件
rejectionhandled
当Promise被拒绝时,若拒绝处理程序被调用,触发该事件
接受一个有以下属性的事件对象作为参数
type
事件名称
unhandlerejecttion
rejectionhandled
promise
被拒绝的Promise对象
reason
来自Promise的拒绝值
跟踪未处理拒绝的代码
串联Promise
概念
每次调用then()或catch()方法时实际上创建并返回了另一个Promise。
只有当第一个Promise完成或被拒绝后,第二个才会被拒绝
捕获错误
链式Promise调用可以感知到链中其他Promise的错误
务必在Promise链的末尾留有一个拒绝处理程序以确保能够正确处理所有可能发生的错误
Promise链的返回值
在Promise链中返回Promise
响应多个Promise
Promise.all()方法
概念
只接受一个参数并返回一个Promise
参数:一个含有多个受监视Promise的可迭代对象(例如一个数组)
必须所有Promise都被完成后返回的Promise才会被完成
只要有一个被拒绝,那么返回的Promise没等所有Promise都完成,都立即被拒绝
Promise.race()方法
参数:一个含有多个受监视Promise的可迭代对象(例如一个数组)
只要有一个Promise被解决返回的Promise就被解决
自Promise继承
基于Promise的异步任务执(未读,待完善)
12、代理(Proxy)和反射(Reflection)API(未读,待完善)
13、用模块封装代码
什么是模块
模块是自动运行在严格模式下并且没有办法退出运行的JavaScript代码。
特性:
this的值是undefined;
模块不支持HTML风格的代码注释
脚本,也就是任何不是模块的JavaScript代码
导出的基本语法
export关键字
将一部分已发布的代码暴露给其他模块
可以将expor放在任何变量、函数或类声明的前面
导入的基本语法
import
基本形式
大括号:表示从给定模块导入的绑定(binding)
关键字from:表示从哪个模块导入给定的绑定,该模块由表示模块路径的字符串指定(被成为模块说明符)
导入一个绑定时,他就好像使用const定义的一样,无法定义一个同名变量
导入单个绑定
导入多个绑定
导入整个模块
注意:
不管在import语句中把一个模块写了多少次,该模块将只执行一次
导入绑定的一个微妙怪异之处:
标识符只有在被导出的模块中可以修改,即便是导入绑定的模块也无法更改绑定的值
模块语法的限制
export和import的一个重要的限制是,他们必须在其他语句和函数之外使用
不能动态地导入或导出绑定
导出和导入时重命名
as关键字
模块的默认值
导出默认值
default关键字
导入默认值
用逗号将默认的本地名称与大括号包裹的非默认值分隔开。
在import语句中,默认值必须排在非默认值之前
重新导出一个绑定
无绑定导入
内建对象(如Array和Object)的共享定义可在模块中访问,对这些对象所做的更改将反映在其他模块中
加载模块
在web浏览器中使用模块
在<script>中使用模块
当type属性的值位‘module’时支持加载模块。
将type设置位“module”可以让浏览器所有内联代码/包含在src指定的文件中的代码按照模块而非脚本的方式加载
web浏览器中的模块加载顺序
模块按照他们出现在HTML文件中的顺序执行
不管他是内联还是src属性
按需加载
下载并解析module.js
递归下载并解析module.js中导入的资源
解析内联模块
递归下载并解析内联模块中导入的资源
下载并解析module2.js
递归下载并解析module2.js中导入的资源
加载完成,被完全解析后的执行顺序
递归执行module.js中导入的资源
执行module.js
递归执行内联模块中导入的资源
执行内联模块
递归执行module2.js中导入的资源
执行module2.js
注意:内联模块与另两个模块不同的是:它不必先下载模块代码
web浏览器中异步模块加载
async属性
应用于脚本时
脚本文件将在文件完全下载并解析后执行
不必等待包含的文档完成解析
应用在模块时
脚本文件将在文件完全下载并解析后执行
不必等待包含的文档完成解析
区别:模块在执行前,模块中所有的导入资源都必须下载
将模块作为Worker加载
浏览器模块说明符解析
模块说明符
以/开头的解析为根目录开始
以./开头的解析为当前目录开始
以../开头的解析为父目录开始
URL格式
总结
es6中的模块是一种打包和封装功能的方式
模块的行为与脚本不同,模块不会将它的顶级变量,函数和类修改为全局作用域,而且this值为undefined.
必须导出所有要让模块使用者使用的功能,变量、函数和类都可以导出,每个模块还可以有一个默认的导出值。
导入后的名称表现得像const定义的一样,无法重新声明它
模块只操作全局作用域,则不需导出任何值
通过<script type = "module"加载的模块文件默认具有defer属性。在文档完全被解析之后,模块也按照他们在包含文档中出现顺序依次执行
es6
1、块级作用域绑定
块级声明
let声明
禁止重声明
const声明
一旦设定不可更改
临时死区
循环中的块作用域绑定
ES6 声明变量的六种方法
var
var 声明及变量提升机制
无论在哪里声明,都会被当作当前作用域顶部声明的变量
function
const
class
let
import
函数
es6的默认参数值
可以为其提供初始值
默认参数值对arguments对象的影响
在非严格模式下,命名参数的变化会同步更新到arguments的对象中
在严格模式下。,命名参数的变化,不会导致arguments改变
展开运算符
明确函数的多种用途
js函数有两个不同的内部方法:[[call]]和[[construct]].
通过nwe关键字调用函数的是[[construct]]
创建一个被称为实例的新对象
执行函数体
将this绑定到实例上
不通过new关键字调用函数是[[call]]
在es5中判断函数被调用的方法
用instanceof
元属性 new.target
为了解决判断函数是否通过new关键字调用的问题
解决了在es5中,call方法也能不通过new创建而通过es5中的判断
必须通过new关键字调用
块级函数
块级作用域内部的函数在块级之前的外面也可以访问到,在块级结束后,会将该函数移除
es6将其标准化
箭头函数
差异
与传统函数的不同
没有this、super、argument、new.target绑定
这些值由外围最近一层非箭头函数决定
不能通过new关键字调用
没有原型
不可以改变this的绑定
不支持arguments对象
没有自己的arguments对象,但可以访问外围的函数的arguments对象
不支持重复的命名参数
差异产生的原因
this绑定丢失
减少错误以及理清模糊不清的地方。
箭头函数也有一个name属性值
语法
创建立即执行函数表达式
你可以定义一个匿名函数并立即调用,自始自终不保存对函数的引用。当想创建一个与其他程序隔离的作用域时,这种模式非常方便
箭头函数与正常函数创建的立即执行函数表达式的不同
小括号只包裹箭头函数定义,没有包含(‘Nicholas’)
正常函数定义的立即执行函数表达式既可以用小括号包裹函数体,也可以额外包裹函数调用部分
箭头函数内没有this绑定
箭头函数与数组
箭头函数没有arguments绑定
没有自己的arguments对象,但可以访问外围的函数的arguments对象
尾调用优化
尾调用指的是函数作为另一个函数的最后一条语句被调用
es6中对尾调用的优化
作用:
缩减了严格模式下尾调用栈的大小
条件
满足以下条件,尾调用不再创建新的栈顶,而且清除并重用当前的栈帧
尾调用不访问当前栈帧的变量
在函数内部,尾调用是最后一条语句
尾调用的结果作为函数值返回
扩展对象的功能性
对象类别
普通(ordinary)对象
具有js对象所有的默认内部行为
特异(Exotic)对象
具有某些与默认行为不符的内部行为
标准(standard)对象
ECMAScript 6规范中定义的对象
标准对象既可以是普通对象,也可以是特意对象
内建对象
脚本开始执行时存在于JavaScript执行环境中的对象
所有标准对象都是内建对象
对象字面量语法扩展
属性初始值的简写
当一个对象的属性与本地变量同名时,不必再写冒号和值,简单的只写属性名即可
对象方法的简写语法
消除了冒号和function关键字
区别:简写方法可以使用super关键字
可计算的属性名
用方括号包含变量名,会算出变量名的值,来当属性名
新增方法
Object.is()
弥补全等运算符的不准确运算
与全等运算符(===)唯一的区别,时能识别+0,-0;NaN与NaN
Object.assign()
混合(Mixin)时js实现对象组合最流行的一种模式
在一个mixin方法中,一个对象接收l来自了另一个对象的属性和方法
Object.assign()方法可以接受任意数量的源对象,并按指定的顺序将属性复制到接受对象中。
如果多个源对象具有同名属性,则排位靠后的源对象会覆盖排位靠前的。
不能将提供者的访问器属性复制到接收对象中,但会将其转变为接收对象的一个属性
自由属性枚举规则
规则
所有数字键按升序排序
所有字符串键按照他们被加入对象的顺序排序
所有symbol键按照他们加入对象的顺序排序
涉及到的方法
Object.getOwnPropertyNames()方法
Reflect.ownKeys
Object.getOwnPropertyNames
不会被影响到的方法
Object.keys()方法
JSON.stringify()方法
for ...in..
增强对象原型
改变对象的原型
Object.setPrototypeOf( )
参数
被改变原型的对象
替代第一个参数原型的对象
扩展
正常情况下无论是通过构造函数还是Object.create()方法创建对象,其原型是在对象创建时指定的
es5中添加了Object.getPrototypesOf( )方法来返回任意指定对象的原型
简化原型访问的Super引用
限制
必须在简写方法的对象中使用Super引用
super引用不是动态变化的,它总是指向正确的对象,
Super的苏勇引用都是通过[[HomeObject]]属性来确定后续的运行过程。
第一步,是在[[HomeObject]]属性上调用Object。getPrototypeOf()方法来检索原型的引用;
通过原型找到同名函数
设置this绑定并且调用相应的方法
正式的方法定义
[[HomeObject]]属性
用途
用来容纳这个方法从属的对象
5、解构:使数据访问更加便捷
基本用法
这种写法属于“模式匹配”,只要等号两边的模式相同,左边的变量就会被赋予对应的值。下面是一些使用嵌套数组进行解构的例子。
只要某种数据结构具有 Iterator 接口,都可以采用数组形式的解构赋值
如Set,Map,Generator(生成器)
不完全解构
报错
如果解构不成功,变量的值就等于undefined。
如果等号的右边不是数组(或者严格地说,不是可遍历的结构,参见《Iterator》一章),那么将会报错
对象的解构赋值
对象的解构与数组有一个重要的不同
数组的元素是按次序排列的
对象变量必须与属性同名,才能取到正确的值
如果变量名与属性名不一致,必须写成这样。
对象的解构也可以指定默认值
嵌套赋值
数组本质是特殊的对象,因此可以对数组进行对象属性的解构。
失败
如果解构失败,变量的值等于undefined
如果解构模式是嵌套的对象,而且子对象所在的父属性不存在,那么将会报错。
如果要将一个已经声明的变量用于解构赋值,必须非常小心。
解构赋值允许等号左边的模式之中,不放置任何变量名。
对象的解构赋值,可以很方便地将现有对象的方法,赋值到某个变量。
字符串的解构赋值
原因
字符串也可以解构赋值。这是因为此时,字符串被转换成了一个类似数组的对象。
类似数组的对象都有一个length属性,因此还可以对这个属性解构赋值。
数值和布尔值的解构赋值
解析赋值的规则
只要等号右边的值不是对象或数组,就先将其转为对象。由于undefined和null无法转为对象,所以对它们进行解构赋值,都会报错。
圆括号问题
函数参数的解构赋值
建议只要有可能,就不要在模式中放置圆括号。
不能使用圆括号的情况
1)变量声明语句
2)函数参数
3)赋值语句的模式
用途
交换变量的值
从函数返回多个值
函数参数的定义
提取 JSON 数据
函数参数的默认值
指定参数的默认值,就避免了在函数体内部再写var foo = config.foo || 'default foo';这样的语句。
遍历 Map 结构
如果只想获取键名,或者只想获取键值
输入模块的指定方法
6、Symbol和Symbol属性
概述
ECMAScript5及早期版本中,语言包含5种原始类型
字符串型
数字型
布尔型、
null
undefined
ECMAScript6中引入了第6种原始类型:Symbol
创建Symbol
注意:
由于Symbol 是原始值,因此调用new Symbol会导致程序抛出错误
参数
可选
让你添加一段文本描述即将创建的Symbol
这段描述不可用于属性访问,但是建议你在每次创建Symbol时都添加这一段描述
会被存储在内部的[[Description]]属性中,只有当调用Symbol的toString()方法时,才可读取这个属性。
在执行console.log种会隐式的调用toString()方法
他的描述会被打印到日志中,但不能直接在代码中访问
Symbol的辨识方法
typeof
Symbol的使用方法
使用地点
所有使用可计算属性名
可计算对象字面量属性名
Object.defineProperty()
Object.defineProperties()方法
Symbol共享体系
创建一个可共享的Symbol
Symbol.for()方法
参数一
用途:即将创建的Symbol的字符串标识符
用途二:也作为Symbol的描述
过程
首先在全局Symbo表中搜索键为“uid”的Symbol是否存在
存在:直接返回已有的Symbol
不存在:
创建一个新的Symbol
并使用这个键在Symbol全局注册表中注册
返回新创建的Symbol
共享相关的特性
Symbol.keyFor()方法
使用该方法在Symbol全局注册表中检索与Symbol有关的键
注意:使用let uid3 = Symbol("description"),并不会在全局注册表中注册该Symbol
Symbol与类型强制转换
不能将Symbol强制转换为字符串和数字类型
子主题
Symbol属性检索
扩展
检索对象中所有的属性名
Object.key()
返回所有可枚举䣌属性名
Object.getOwnPropertyNames()
不考虑属性的可枚举性一律返回
两种方法均不支持Symbol属性
Object.getOwnPropertySymbols()
ES6新增方法
用来检索对象中的Symbol属性
返回值是一个包含所有Symbol自有属性的数组
well-known Symbol
包括
Symbol.hasInstance
用于检测对象的继承信息
一个在执行instanceof时调用的内部方法
Symbol.isConcatSpreadable
一个布尔值
用来表示当传递一个集合作为Array.prototype.concat()方法的参数时,是否应该将集合内的元素规整到同一层级
Symbol.iterator
一个返回迭代器的方法
Symbol.match
一个在调用String.prototype.match()方法时调用的方法,用来比较字符串
Symbol.replace
一个在调用String.prototype.replace()方法时调用的方法,用于替换字符串中替换子串
Symbol.search
一个在调用String.prototype.search()方法时调用的方法
用于在字符串中定位子串
Symbol.species
用于创建派生对象的构造函数
Symbol.split
一个在调用String.prototype.split()方法时调用的方法
用于分割字符串
Symbol.toPrimitive
一个返回对象原始值的方法
Symbol.toStringTag
一个在调用Object.prototye.toString方法时使用的字符串
用于创建对象描述
Symbol.unscopables
一个定义了一些不可被with语句引用的对象属性名称的对象集合
7、Set集合与Map集合
ECMAScript5中的Set与Map集合
在es5中开发者用对象属性来模拟这两种集合
该解决方案的一些问题
待完善
ECMAScript6中的Set集合
定义
是一种有序列表
含有一些相互独立的非重复值
能更有效地追踪各种离散值
是一个强引用的Set集合
创建Set集合并添加元素
方法
调用new Set()创建Set集合
调用add()方法向集合中添加元素
访问集合的size属性可以获取集合中目前的元素数量
has()
可以检测Set集合种是否存在某个值
补充:不会对所存值进行强制的类型转换
如数字5和字符串”5“可以作为两个独立元素存在
唯一的例外时+0,和-0被认为是相等的
set构造函数会过滤掉重复的值,从而保证集合中的元素各自唯一
移除元素
方法
delete()
可以移除Set集合种的某一个元素
clear()
会移除集合中的所有元素
Set集合中的forEach()方法
参数
Set集合中下一次索引的位置
参数一
与第一个参数一样的值
参数二
被遍历的Set集合本身
参数三
与数组中的forEach()的异同
Set中回调函数前两个参数的值是一样的
Map集合的forEach()方法和数组的接收的参数都是三个参数u,前两个时值和键名
值
键名
被遍历的集合
注意:你不能通过索引访问集合中的元素。如果有需要,最好先将Set集合转换成一个数组
将Set集合转换为数组
运用展开运算符(...)
它可以将数组中的元素分解为各自独立的函数参数
Weak Set集合(弱引用Set集合)
特点
Weak Set集合只存储对象的弱引用,并且不可以存储原始值;
集合中的弱引用如果是对象唯一的引用,则会被回收并释放内存
创建Weak Set集合
方法
new WeakSet()
可以创建WeakSet集合
add()
has()
delete()
参数
只能为对象或着是对象的集合
不接受任何原始值
如果包含其他非对象值,程序会抛出错误
两种Set类型的主要区别
WeakSet 保存的对象值是弱引用
最大区别
在WeakSet的实例中,如果向add()方法传入非对象参数会导致程序抛错,而向has()和delete()方法传入非对象参数则会返回false
WeakSet集合不可迭代,所以不能被用于for-of循环
WeakSet集合不暴露任何迭代器(例如keys(),values()方法),所以无法通过程序本身来检测其中的内容
WeakSet集合不支持forEach方法
WeakSet集合不支持size属性
总之:如果你只需要跟踪对象引用,你更应该使用WeakSet集合而不是普通的Set集合
Set类型可以用来处理列表中的值,但是不适用于处理键值对这样的信息结构
ECMAScript6中的Map集合
概述
es6中的Map
许多键值对
有序列表
Object.is()
等价性判断是通过该方法来实现的
所以字符串”5“和数字5会被判定为两种类型,可以分别作为两个独立的键出现在程序中
这一点与对象不太一样,对象中的属性名总会被强制转换成字符串类型
键
可以用对象作为对象属性的键名
对象不可以
方法
set(key,value)
含义
向Map集合中添加新的元素
参数
键名
参数一
value值
参数二
get(key)
含义
从集合中获取信息
参数
键名
如不存在返回‘undefined’
has(key)
检测指定的键名在Mao集合中是否已经存在
delete(key)
从Map集合中移除指定键名及其对应的值
clear(key)
移除Map集合中所有键值对
属性
size
代表当前集合种哦那个包含的键值对数量
Map集合的forEach(value,key,map)
WeakMap
是弱引用的Mao集合
键名必须是一个非null类型的对象
如果不是对象则会报错
如果在弱引用外不存在其他的强引用,引擎的垃圾回收机制会自动回收这个对象,同时移除WeakMap中的键值对
创建一个私有数据
主要问题
是否只用对象作为集合的键名
是:weakMap
相对Map集合而言,Weak Map集合对用户的可见度更低,其不支持通过
forEach()
size属性
clear()方法
8、迭代器(Iterator)和生成器(Generator)
出现该方法之前的Javascript历史问题
循环语句的问题
当多个循环嵌套则需要追踪多个变量代码复杂度会大大增加
容易错误使用了其他for循环的跟踪变量
迭代器
定义
是一种特殊对象
方法
next()方法
每次调用会返回一个结果对象
结果对象
属性
value:表示下一个将要返回的值
done:是一个bool类型,当没有更多可返回数据时返回true
迭代器会保存一个内部指针,用来指向当前集合中值的位置
每调用一次next()方法都会返回下一个可用的值
优点
可以极大地简化数据操作
es5实现方法
生成器
定义
是一个返回迭代器的函数
通过function 关键字后的星号(*)来表示
可以紧挨function关键字 也可以在中间添一个空格
yield
每当执行完一条yield语句后函数就会自动停止执行
使用限制
只可在生成器内部使用,在生成器内部的函数里使用也会报错
生成器函数表达式
注意不能使用箭头函数来创建生成器
生成器对象的方法
生成器默认会为Symbol.Iterator属性赋值,因此所有通过生成器创建的迭代器都是可迭代对象
可迭代对象和for-of循环
可迭代对象
相关定义
具有Symbol.iterator属性
Symbol.Iterator通过制定的函数返回一个作用于附属对象的迭代器
是一种与迭代器密切相关的对象
由于具有Symbol.Iterator属性的对象都有默认的迭代器因此可以用它检测对象是否为可迭代器
在ES6中所有的集合对象(数组,Set集合及Map集合)和字符串都是可迭代对象,这些对象中都有默认的迭代器
ES6中新加入的特性for-of循环需要用到可迭代对象的这些功能
创建可迭代对象
默认情况下,开发者定义的对象都是不可迭代对象
但如果给Symbol.iterator属性添加一个生成器
则可以将其变为可迭代对象
for-of循环
每执行一次
限制
用于不可迭代对象、null、或undefined 将会导致程序抛出错误
内建迭代器
集合对象迭代器
集合对象
数组
Map集合、
Set集合
迭代器
entries()
定义
返回一个迭代器
其值为多个键值对
return(返回值)
返回一个数组,数组中两个元素分别表示集合中每个元素的键与值
被遍历的对象是
数组
索引
值
Set集合
两个是相同的值
Map集合
键值(key)
值(value)
values()
定义
返回一个迭代器
其值为集合的值
keys()
定义
返回一个迭代器
其值为集合中所有键名
对于数组对象,无论是否为数组添加命名属性,打印出来的都是数字类型的索引‘
而for -in 循环迭代的是数组属性,而不是数字类型的索引
9、JavaScript中的类
ES5中的近类结构
类的声明
基本的类声明语法
建议在构造函数中创建所有自有属性
与函数不同的是,类属性不可被赋予新值,在之前的示例中PersonClass.prototype就是这样一个只可读的类属性
为何使用类语法
函数声明可以被提升,而类声明与let声明类似,不能被提升:真正执行声明语句之前,他们会一直存在于临时死区
类声明中的所有代码将自动运行在严格模式下,且无法强行让代码脱离严格模式执行
在自定义类型中,需要通过Object.defineProperty()方法手工指定某个方法为不可枚举;而在类中,所有方法都是不可枚举的
每个类都有一个名为[[construct]]的内部方法,通过关键字new调用那些不含[[construct]]的方法会导致程序抛出错误
使用除关键字new以外的方式调用类的构造函数会导致程序抛出错误
在类中修改类名会导致程序报错
额外:常量类名
类的名称只在类中为常量,
在类的方法中不能修改类名
内部是通过const命名
但可以在外部修改
外部是通过let命名
类表达式
存在形式
声明形式
由function和class定义
表达式形式
基本的类表达式语法
命名类表达式
声明时在关键字后class后添加一个标识符
作为一等公民的类
一等公民
可以传入函数,可以从函数返回,并且可以赋值给变量的值
可以将类作为参数传入函数中、
可计算成员名称
用方括号包裹一个表达式即可使用可计算名称
属性名可以设置为用[]包着的变量
生成器方法
静态成员
继承与派生类
es6之前的继承
es6的等价版本
super()
通过调用super()方法即可访问基类的构造函数。
如果在派生类欸中指定了构造函数,则必须要调用super(),如果不这样做程序就会报错。
如果选择不使用构造函数,则当创建新的类实例时会自动调用super()并传入所有参数
使用super()的小贴士
只可在派生类的构造函数中使用super()如果尝试在非派生类(不是用extends声明的类)或函数中使用则会导致程序抛出错误
在构造函数中访问this之前一定要调用super(),它负责初始化this,如果在调用super()之前尝试访问this会导致程序出错
如果不想调用super(),则唯一的方法时让类的构造函数返回一个对象
类方法遮蔽
派生类中的方法总会覆盖基类中的同名方法
静态成员继承
如果基类有静态成员,那么这些静态成员在派生类中也可以用
派生自表达式的类
只要表达式可以被解析为一个函数并且具有[[construct]]属性和原型,那么就可以用extends进行派生
动态地确定类的继承目标
创建mixin
注意:
extends后可以使用任意表达式,但不是所有表达式最终都能生成合法的类。如果使用null或生成器函数会导致错误,类在这些情况下没有[[construct]]属性
内建对象地继承(未读 p203)
Symbol.species属性
在类的构造函数中使用new.target(未读 p208)
参数:
正则表达式/RegExp对象
10、改进地数组功能
es6
创建数组
es6以前
创建数组:均需列举数组中地元素
调用Array构造函数new
数组字面量
Array.of()
添加原因
帮助开发者们规避通过Array构造函数创建数组时的怪异行为
工作机制
总会创建一个包含所有参数的数组,不因参数的不同而改变
注意·:
Array.of方法不通过Symbol.species属性确定返回值的类型,他使用当前构造函数(也就是of()方法中的this值)来确定正确的返回类型
Array.from()方法
概述
es5中类数组对象转化为数组
参数一
可迭代对象或类数组对象
必选
通过this来确定返回数组类型的
映射转换
参数二
映射函数
该函数,会将类数组对象中的每一个值转换成其他形式,最后将结果储存在结果数组的相应索引中
参数三
表示映射函数的this值
可选
Array.from()转换可迭代对象
能将所有含有Symbol.iterator属性的对象转换为数组
为所有数组添加的新办法
find()方法和findIndex()方法
协助开发者在数组中查找任意值
参数
参数一
回调函数
回调函数的参数
该元素
该元素在数组中的索引值
数组本身
参数二
指定回调函数的this的值
可选
返回值
返回true时,find()方法和findIndex()方法都会立即停止
区别
find返回查找到的值
findIndex返回查找到值的索引
优点
按某个条件查找时,用find和findIndex()方法更适合
反之,按某个值匹配的元素时用indexOf和lastIndexOf()更适合
es5中
indexOf()
lastIndexOf()
缺点
只能查找一个值
fill方法
功能
用指定的值填充一至多个数组元素
传入一个值时,fill()方法会用这个值重写数组中的所有值
参数
参数一:
指定的值
参数二:
开始索引
可选
参数三
不包含结束索引
不包含结束索引当前值
可选
注意:
当索引值为负数时,这些值会与length值相加来作最终位置
copyWithin()方法
功能
从数组中复制元素的值
参数
1、
设置该位置的值,为得到的值
被粘贴的位置
paste
2、
得到该位置的值
被复制得位置
copy
3、
指定停止复制值的位置
不包含当前索引所指向的值
[set,get,get停止的位置(不包含当前位置的值)]
遍历数组方法
entries()方法
键值对的遍历
keys()方法
键的遍历
values()方法
值的遍历
定型数组
概述
是一种用于处理数值类型数据的专用数组
就是将任何数字转换为一个包含数字比特的数组
引入定型数组是为了提供高性能的算术运算
数值数据类型
有符号的8位整数int8
无符号的8位整数uint8
int 16
uint16
int32
uint32
float32
float64
数组缓冲区
新建数组缓冲区
new操作符
slice()将已有的数组缓冲区来创建一个新的
通过视图操作数组缓冲区
视图:用来操作内存的接口
可以操作与数组缓冲区或缓冲区字节的子集
数据缓冲区:是内存中的一段地址
DataView类型
是一种通用的数组缓冲区视图
其支持所有8种数值型数据类型
获取视图信息
buffer
视图绑定的数组缓冲区
byteOffset
DataView构造函数的第二个参数,默认是0,只有传入参数时才有值
byteLength
DataView构造函数的第三个参数,默认是缓冲区的长度byteLength
读取和写入数据
getInt8(byteOffset,littleEndian)
setInt8(byteOffset,value,littleEndian)
getUnit8(byteOffset,littleEndian)
setUint8(byteOffset,value,littleEndian)
es6之前
检测数组
instanceof
弊端:
假定只有一个全局执行环境。如果有多个框架或全局执行环境时会有不同的构造函数
Array.isArray(value)
目的是最终确定某个值到底是不是数组,而不管他是在哪个全局执行环境中创建的。
转换方法
toString()方法
会返回由数组中每个值得字符串形式拼接而成得一个以逗号分隔的字符串。
valueOf()方法
返回的还是数组本身
toLocaleString()方法
会返回由数组中每个值得字符串形式拼接而成得一个以逗号分隔的字符串。
不同之处
为了取得每一项的值,调用的是每一项的toLocaleString()方法
join()方法
可以使用不同的分隔符来构建字符串
参数:
用作分隔符的字符串,如不传值或传undefined则默认为“,”逗号
栈方法
push()方法
接受任意数量的参数,把他们逐个添加到数组末尾,并返回修改后的数组的长度
返回新数组的长度
pop()方法
删除从末尾移除最后一项,减少数组的length值
返回被移除项的值
队列方法
shift()方法
移除数组中第一个项,并返回该项
返回被移除项的值
unshift()方法
在数组前端添加任意个项,并返回新数组的长度。
返回新数组的长度
重排序方法
reverse()方法
反转数组项的顺序
sort()方法
默认为升序排序数组项
参数:
比较函数
比较函数接收两个参数
第一参数位于第二个参数前的则返回一个负数
相等,为0
第一个位于第二个参数后,则为正数
操作方法
concat()
基于当前数组中的所有项创建一个新数组
slice()方法
基于当前数组中的一个或多个项创建一个新数组。
参数
1、起始位置
2、结束位置
不包含该位置的项
只有一个参数时,从起始位置到数组末尾的所有项
splice()方法
用途
删除
删除第一项的位置
删除的项数
插入
起始位置
0(要删除的项数)
要插入的项
替换
起始位置
要删除的项数
要插入的任意数量的项
位置方法
indexOf()方法
参数:
要查找的项
表示查找起点位置的项(可选)
从数组开头向后查找
没找到返回-1
lastIndexOf()方法
参数:
要查找的项
表示查找起点位置的项(可选)
也是从后面向前数的位置项
从数组的末尾开始向前查找
没找到返回-1
迭代方法
every()
参数
运行的函数(可选)
函数的参数:
item
index
array
运行该函数的作用域对象-影响this值
条件
每一项都返回true
返回值
true
filter()方法
参数
运行的函数(可选)
函数的参数:
item
index
array
运行该函数的作用域对象-影响this值
条件
返回值
返回该函数会返回true的项组成的数组
forEach()
参数
运行的函数(可选)
函数的参数:
item
index
array
运行该函数的作用域对象-影响this值
条件
返回值
无返回值
map()
参数
运行的函数(可选)
函数的参数:
item
index
array
运行该函数的作用域对象-影响this值
条件
返回值
返回每次函数调用的结果组成的数组
some()
参数
运行的函数(可选)
函数的参数:
item
index
array
运行该函数的作用域对象-影响this值
条件
任一项返回ture
返回值
true
归并方法
reduce()
参数
运行的函数(可选)
函数的参数:
prev
前一个值
cur
当前值
index
项的索引、
array
数组对象
作为归并基础的初始值
从数组的第一项开始,逐个遍历到最后
reduceRight()
参数
运行的函数(可选)
函数的参数:
prev
前一个值
cur
当前值
index
项的索引、
array
数组对象
作为归并基础的初始值
从数组的最后一项开始,逐个遍历到第一项
11、Promise与异步编程
异步编程的背景知识
事件模型
回调模式
Promise的基础知识
Promise的生命周期
状态
pending
进行中
Fulfilled
Promise异步操作成功完成
Rejected
Promise异步操作未能成功完成
方法
then()
参数
参数一:当promise状态变为fulfilled时要调用的函数
与异步操作相关附加数据都会传递给这个完成函数
参数二:当状态变为rejected状态时调用的函数
创建未完成的Promise
使用Promise的构造函数
创建已处理的Promise
使用Promise.resolve()
已完成态
使用Promise.reject()
已拒绝态
非Promise的Thenable对象
构成:
then()方法
参数1:resolve
参数2:reject
调用Promise.resolve()方法将Thenable对象转换成一个已完成的Promise
执行器错误
全局的Promise拒绝处理
Node.js环境的拒绝处理
浏览器环境的拒绝处理
unhandledrejection
当Promise被拒绝,并且没有提供拒绝处理程序时,触发该事件
rejectionhandled
当Promise被拒绝时,若拒绝处理程序被调用,触发该事件
接受一个有以下属性的事件对象作为参数
type
事件名称
unhandlerejecttion
rejectionhandled
promise
被拒绝的Promise对象
reason
来自Promise的拒绝值
跟踪未处理拒绝的代码
串联Promise
概念
每次调用then()或catch()方法时实际上创建并返回了另一个Promise。
只有当第一个Promise完成或被拒绝后,第二个才会被拒绝
捕获错误
链式Promise调用可以感知到链中其他Promise的错误
务必在Promise链的末尾留有一个拒绝处理程序以确保能够正确处理所有可能发生的错误
Promise链的返回值
在Promise链中返回Promise
响应多个Promise
Promise.all()方法
概念
只接受一个参数并返回一个Promise
参数:一个含有多个受监视Promise的可迭代对象(例如一个数组)
必须所有Promise都被完成后返回的Promise才会被完成
只要有一个被拒绝,那么返回的Promise没等所有Promise都完成,都立即被拒绝
Promise.race()方法
参数:一个含有多个受监视Promise的可迭代对象(例如一个数组)
只要有一个Promise被解决返回的Promise就被解决
自Promise继承
基于Promise的异步任务执(未读,待完善)
12、代理(Proxy)和反射(Reflection)API(未读,待完善)
13、用模块封装代码
什么是模块
模块是自动运行在严格模式下并且没有办法退出运行的JavaScript代码。
特性:
this的值是undefined;
模块不支持HTML风格的代码注释
脚本,也就是任何不是模块的JavaScript代码
导出的基本语法
export关键字
将一部分已发布的代码暴露给其他模块
可以将expor放在任何变量、函数或类声明的前面
导入的基本语法
import
基本形式
大括号:表示从给定模块导入的绑定(binding)
关键字from:表示从哪个模块导入给定的绑定,该模块由表示模块路径的字符串指定(被成为模块说明符)
导入一个绑定时,他就好像使用const定义的一样,无法定义一个同名变量
导入单个绑定
导入多个绑定
导入整个模块
注意:
不管在import语句中把一个模块写了多少次,该模块将只执行一次
导入绑定的一个微妙怪异之处:
标识符只有在被导出的模块中可以修改,即便是导入绑定的模块也无法更改绑定的值
模块语法的限制
export和import的一个重要的限制是,他们必须在其他语句和函数之外使用
不能动态地导入或导出绑定
导出和导入时重命名
as关键字
模块的默认值
导出默认值
default关键字
导入默认值
用逗号将默认的本地名称与大括号包裹的非默认值分隔开。
在import语句中,默认值必须排在非默认值之前
重新导出一个绑定
无绑定导入
内建对象(如Array和Object)的共享定义可在模块中访问,对这些对象所做的更改将反映在其他模块中
加载模块
在web浏览器中使用模块
在<script>中使用模块
当type属性的值位‘module’时支持加载模块。
将type设置位“module”可以让浏览器所有内联代码/包含在src指定的文件中的代码按照模块而非脚本的方式加载
web浏览器中的模块加载顺序
模块按照他们出现在HTML文件中的顺序执行
不管他是内联还是src属性
按需加载
下载并解析module.js
递归下载并解析module.js中导入的资源
解析内联模块
递归下载并解析内联模块中导入的资源
下载并解析module2.js
递归下载并解析module2.js中导入的资源
加载完成,被完全解析后的执行顺序
递归执行module.js中导入的资源
执行module.js
递归执行内联模块中导入的资源
执行内联模块
递归执行module2.js中导入的资源
执行module2.js
注意:内联模块与另两个模块不同的是:它不必先下载模块代码
web浏览器中异步模块加载
async属性
应用于脚本时
脚本文件将在文件完全下载并解析后执行
不必等待包含的文档完成解析
应用在模块时
脚本文件将在文件完全下载并解析后执行
不必等待包含的文档完成解析
区别:模块在执行前,模块中所有的导入资源都必须下载
将模块作为Worker加载
浏览器模块说明符解析
模块说明符
以/开头的解析为根目录开始
以./开头的解析为当前目录开始
以../开头的解析为父目录开始
URL格式
总结
es6中的模块是一种打包和封装功能的方式
模块的行为与脚本不同,模块不会将它的顶级变量,函数和类修改为全局作用域,而且this值为undefined.
必须导出所有要让模块使用者使用的功能,变量、函数和类都可以导出,每个模块还可以有一个默认的导出值。
导入后的名称表现得像const定义的一样,无法重新声明它
模块只操作全局作用域,则不需导出任何值
通过<script type = "module"加载的模块文件默认具有defer属性。在文档完全被解析之后,模块也按照他们在包含文档中出现顺序依次执行
14、字符串的扩展
方法
字符的Unicode表示法
定位字符位置
之前
charAt
对于utf-16这种4个字节的字符,JavaScript 不能正确处理,字符串长度会误判为2,而且charAt方法无法读取整个字符
charCodeAt
只能分别返回前两个字节和后两个字节的值。
es6
codePointAt
够正确处理 4 个字节储存的字符,返回一个字符的码点。
codePointAt方法会正确返回 32 位的 UTF-16 字符的码点。对于那些两个字节储存的常规字符,它的返回结果与charCodeAt方法相同。
ES6之前的字符串
方法
字符方法
charAt(location:number)
参数是
基于0的字符位置
返回给定位置的哪个字符
charCodeAt()
参数是
基于0的字符位置
返回给定位置字符的字符编码。不是那个字符
方括号加数字索引来访问字符串中的特定字符
String.fromCharCode()方法
接收一个或多个字符编码,然后将他们转换成一个字符串
本质上来看这个方法与实例方法charCodeAt()方法执行的是相反的操作
字符串操作方法
concat()
将一或多个字符串拼接起来
原字符串不变,返回一个新的字符串
slice()
参数
1、子字符串开始的位置
2、子字符串结束的位置,但不包含该位置上的字符
参数是负值时:负值与字符串的长度相加
原字符串不变,返回一个新的字符串
substr()
参数
1、子字符串开始的位置
2、返回字符的个数,默认值为:字符串的末尾作为结束位置
不同点,与另外两个不同的地方
参数是负值时:负值与字符串的长度相加。第二个转化为0。
原字符串不变,返回一个新的字符串
substring()
参数
1、子字符串开始的位置
2、子字符串结束的位置,但不包含该位置上的字符
参数为负值时:所有参数均转换为0。
原字符串不变,返回一个新的字符串
trim()方法
删除前缀,后缀的所有空格
原字符串不变,返回一个新的字符串
localeCompare()方法
比较两个字符串,并返回下列值中的一个:
如果字符串在字母表中应该排在字符串参数前,则返回一个负数-1
如果字符串等于字符串参数,则返回0
如果字符串在字母表中应该排在字符串参数之后,则返回一个正数1
字符串位置方法
indexOf()
参数:
1、子字符串
2、开始查找的位置(包含该位置)
从该位置往后查找
返回:该参数在字符上的位置
规则从前往后查找
lastIndexOf()
参数:
1、子字符串
2、开始查找的位置(包含该位置)
从该位置往前查找
返回:该参数在字符上的位置
规则:从后往前查找
字符串大小转换方法
toLowerCase()
toUpperCase()
toLocaleUpperCase()
toLocalLowerCase()
字符串的模式匹配方法
match()方法
参数:
正则表达式/RegExp对象
search()方法
参数:
字符串/正则表达式/RegExp对象
返回:第一个匹配项的索引,如没有找到返回-1
replace()方法
参数
1、一个RegExg对象/字符串、
字符串的时候,只能匹配第一个,如想匹配其他的,则必须用正则表达式
2、字符串/函数
参数为函数的时候:
会向这个函数传递3个参数
模式的匹配项
模式匹配项在字符串中的位置
原始字符串
用第二个参数替换第一个参数
split()方法
基于指定的分隔符将一个字符串分割成多个子字符串,并将结果放在一个数组中。
参数:
1、字符串/RegExg对象
2、(可选)指定返回数组的大小
替换文本
$$
$
$&
匹配整个模式的子字符串。与RegExg.lastMatch的值相同
$'
匹配的子字符串之前的子字符串。
与RegExg.leftContext的值相同
$`
匹配的子字符串之后的子字符串。
与RegExg.rightContext的值相同
$n
匹配第n各捕获组的子字符串,其中n等于0~9.
$nn
匹配第nn个捕获组的子字符串,其中nn等于01~99.
es6扩展的方法
codePointAt()方法
能正确返回需要4个字节存储的字符编码。js默认以2个字节存储字符
String.fromCodePoint()方法
优化了es5中的fromCharCode()方法
字符串的遍历器接口
for...of
遍历字符串
最大优点:是可以识别大于0xFFFF的码点
for循环会认为它包含2个字符
at()
优化了charAt()方法,识别大于0xFFFF的字符
normalize()
将字符的不同表达方法,统一为同样的形式
参数:
1、NFC,默认参数,标准等价合成
语义,视觉均等价
2、NFD,标准等价分解
3、NFKC,兼容等价合成
语义等价,视觉不等价
4、NFKD,兼容等价分解
确定一个字符串是否包含在另一个字符串中
includes()
返回bool值,表示是否找到了参数字符串
参数
字符串
n,表示开始搜索的位置,从第n个到字符串结束的位置
startsWith()
返回bool值,表示参数字符串是否在源字符串的头部
参数
字符串
n,表示开始搜索的位置,从第n个到字符串结束的位置
endsWith()
返回bool值,表示参数字符串是否在源字符串的尾部
参数
字符串
n,表示前n个字符中
repeat()方法
返回一个新字符串,表示将原字符串重复n次
padStart()、padEnd()
字
字符串补全长度的功能。
padStart()
用于头部补全
参数
指定字符串最小的长度
用来补全的字符串
padEnd()
用于尾部补全 v
参数
指定字符串最小的长度
用来补全的字符串
es6
1、块级作用域绑定
块级声明
let声明
禁止重声明
const声明
一旦设定不可更改
临时死区
循环中的块作用域绑定
ES6 声明变量的六种方法
var
var 声明及变量提升机制
无论在哪里声明,都会被当作当前作用域顶部声明的变量
function
const
class
let
不存在变量提升
暂时性死区
不允许重复声明
增加了块级作用域
块级作用域使IIFE立即执行表达式不再必要
import
函数
es6的默认参数值
可以为其提供初始值
默认参数值对arguments对象的影响
在非严格模式下,命名参数的变化会同步更新到arguments的对象中
在严格模式下。,命名参数的变化,不会导致arguments改变
展开运算符
明确函数的多种用途
js函数有两个不同的内部方法:[[call]]和[[construct]].
通过nwe关键字调用函数的是[[construct]]
创建一个被称为实例的新对象
执行函数体
将this绑定到实例上
不通过new关键字调用函数是[[call]]
在es5中判断函数被调用的方法
用instanceof
元属性 new.target
为了解决判断函数是否通过new关键字调用的问题
解决了在es5中,call方法也能不通过new创建而通过es5中的判断
必须通过new关键字调用
块级函数
块级作用域内部的函数在块级之前的外面也可以访问到,在块级结束后,会将该函数移除
es6将其标准化
箭头函数
差异
与传统函数的不同
没有this、super、argument、new.target绑定
这些值由外围最近一层非箭头函数决定
不能通过new关键字调用
没有原型
不可以改变this的绑定
不支持arguments对象
没有自己的arguments对象,但可以访问外围的函数的arguments对象
不支持重复的命名参数
差异产生的原因
this绑定丢失
减少错误以及理清模糊不清的地方。
箭头函数也有一个name属性值
语法
创建立即执行函数表达式
你可以定义一个匿名函数并立即调用,自始自终不保存对函数的引用。当想创建一个与其他程序隔离的作用域时,这种模式非常方便
箭头函数与正常函数创建的立即执行函数表达式的不同
小括号只包裹箭头函数定义,没有包含(‘Nicholas’)
正常函数定义的立即执行函数表达式既可以用小括号包裹函数体,也可以额外包裹函数调用部分
箭头函数内没有this绑定
箭头函数与数组
箭头函数没有arguments绑定
没有自己的arguments对象,但可以访问外围的函数的arguments对象
尾调用优化
尾调用指的是函数作为另一个函数的最后一条语句被调用
es6中对尾调用的优化
作用:
缩减了严格模式下尾调用栈的大小
条件
满足以下条件,尾调用不再创建新的栈顶,而且清除并重用当前的栈帧
尾调用不访问当前栈帧的变量
在函数内部,尾调用是最后一条语句
尾调用的结果作为函数值返回
扩展对象的功能性
对象类别
普通(ordinary)对象
具有js对象所有的默认内部行为
特异(Exotic)对象
具有某些与默认行为不符的内部行为
标准(standard)对象
ECMAScript 6规范中定义的对象
标准对象既可以是普通对象,也可以是特意对象
内建对象
脚本开始执行时存在于JavaScript执行环境中的对象
所有标准对象都是内建对象
对象字面量语法扩展
属性初始值的简写
当一个对象的属性与本地变量同名时,不必再写冒号和值,简单的只写属性名即可
对象方法的简写语法
消除了冒号和function关键字
区别:简写方法可以使用super关键字
可计算的属性名
用方括号包含变量名,会算出变量名的值,来当属性名
新增方法
Object.is()
弥补全等运算符的不准确运算
与全等运算符(===)唯一的区别,时能识别+0,-0;NaN与NaN
Object.assign()
混合(Mixin)时js实现对象组合最流行的一种模式
在一个mixin方法中,一个对象接收l来自了另一个对象的属性和方法
Object.assign()方法可以接受任意数量的源对象,并按指定的顺序将属性复制到接受对象中。
如果多个源对象具有同名属性,则排位靠后的源对象会覆盖排位靠前的。
不能将提供者的访问器属性复制到接收对象中,但会将其转变为接收对象的一个属性
自由属性枚举规则
规则
所有数字键按升序排序
所有字符串键按照他们被加入对象的顺序排序
所有symbol键按照他们加入对象的顺序排序
涉及到的方法
Object.getOwnPropertyNames()方法
Reflect.ownKeys
Object.getOwnPropertyNames
不会被影响到的方法
Object.keys()方法
JSON.stringify()方法
for ...in..
增强对象原型
改变对象的原型
Object.setPrototypeOf( )
参数
被改变原型的对象
替代第一个参数原型的对象
扩展
正常情况下无论是通过构造函数还是Object.create()方法创建对象,其原型是在对象创建时指定的
es5中添加了Object.getPrototypesOf( )方法来返回任意指定对象的原型
简化原型访问的Super引用
限制
必须在简写方法的对象中使用Super引用
super引用不是动态变化的,它总是指向正确的对象,
Super的苏勇引用都是通过[[HomeObject]]属性来确定后续的运行过程。
第一步,是在[[HomeObject]]属性上调用Object。getPrototypeOf()方法来检索原型的引用;
通过原型找到同名函数
设置this绑定并且调用相应的方法
正式的方法定义
[[HomeObject]]属性
用途
用来容纳这个方法从属的对象
5、解构:使数据访问更加便捷
基本用法
这种写法属于“模式匹配”,只要等号两边的模式相同,左边的变量就会被赋予对应的值。下面是一些使用嵌套数组进行解构的例子。
只要某种数据结构具有 Iterator 接口,都可以采用数组形式的解构赋值
如Set,Map,Generator(生成器)
不完全解构
报错
如果解构不成功,变量的值就等于undefined。
如果等号的右边不是数组(或者严格地说,不是可遍历的结构,参见《Iterator》一章),那么将会报错
对象的解构赋值
对象的解构与数组有一个重要的不同
数组的元素是按次序排列的
对象变量必须与属性同名,才能取到正确的值
如果变量名与属性名不一致,必须写成这样。
对象的解构也可以指定默认值
嵌套赋值
数组本质是特殊的对象,因此可以对数组进行对象属性的解构。
失败
如果解构失败,变量的值等于undefined
如果解构模式是嵌套的对象,而且子对象所在的父属性不存在,那么将会报错。
如果要将一个已经声明的变量用于解构赋值,必须非常小心。
解构赋值允许等号左边的模式之中,不放置任何变量名。
对象的解构赋值,可以很方便地将现有对象的方法,赋值到某个变量。
字符串的解构赋值
原因
字符串也可以解构赋值。这是因为此时,字符串被转换成了一个类似数组的对象。
类似数组的对象都有一个length属性,因此还可以对这个属性解构赋值。
数值和布尔值的解构赋值
解析赋值的规则
只要等号右边的值不是对象或数组,就先将其转为对象。由于undefined和null无法转为对象,所以对它们进行解构赋值,都会报错。
圆括号问题
函数参数的解构赋值
建议只要有可能,就不要在模式中放置圆括号。
不能使用圆括号的情况
1)变量声明语句
2)函数参数
3)赋值语句的模式
用途
交换变量的值
从函数返回多个值
函数参数的定义
提取 JSON 数据
函数参数的默认值
指定参数的默认值,就避免了在函数体内部再写var foo = config.foo || 'default foo';这样的语句。
遍历 Map 结构
如果只想获取键名,或者只想获取键值
输入模块的指定方法
6、Symbol和Symbol属性
概述
ECMAScript5及早期版本中,语言包含5种原始类型
字符串型
数字型
布尔型、
null
undefined
ECMAScript6中引入了第6种原始类型:Symbol
创建Symbol
注意:
由于Symbol 是原始值,因此调用new Symbol会导致程序抛出错误
参数
可选
让你添加一段文本描述即将创建的Symbol
这段描述不可用于属性访问,但是建议你在每次创建Symbol时都添加这一段描述
会被存储在内部的[[Description]]属性中,只有当调用Symbol的toString()方法时,才可读取这个属性。
在执行console.log种会隐式的调用toString()方法
他的描述会被打印到日志中,但不能直接在代码中访问
Symbol的辨识方法
typeof
Symbol的使用方法
使用地点
所有使用可计算属性名
可计算对象字面量属性名
Object.defineProperty()
Object.defineProperties()方法
Symbol共享体系
创建一个可共享的Symbol
Symbol.for()方法
参数一
用途:即将创建的Symbol的字符串标识符
用途二:也作为Symbol的描述
过程
首先在全局Symbo表中搜索键为“uid”的Symbol是否存在
存在:直接返回已有的Symbol
不存在:
创建一个新的Symbol
并使用这个键在Symbol全局注册表中注册
返回新创建的Symbol
共享相关的特性
Symbol.keyFor()方法
使用该方法在Symbol全局注册表中检索与Symbol有关的键
注意:使用let uid3 = Symbol("description"),并不会在全局注册表中注册该Symbol
Symbol与类型强制转换
不能将Symbol强制转换为字符串和数字类型
子主题
Symbol属性检索
扩展
检索对象中所有的属性名
Object.key()
返回所有可枚举䣌属性名
Object.getOwnPropertyNames()
不考虑属性的可枚举性一律返回
两种方法均不支持Symbol属性
Object.getOwnPropertySymbols()
ES6新增方法
用来检索对象中的Symbol属性
返回值是一个包含所有Symbol自有属性的数组
well-known Symbol
包括
Symbol.hasInstance
用于检测对象的继承信息
一个在执行instanceof时调用的内部方法
Symbol.isConcatSpreadable
一个布尔值
用来表示当传递一个集合作为Array.prototype.concat()方法的参数时,是否应该将集合内的元素规整到同一层级
Symbol.iterator
一个返回迭代器的方法
Symbol.match
一个在调用String.prototype.match()方法时调用的方法,用来比较字符串
Symbol.replace
一个在调用String.prototype.replace()方法时调用的方法,用于替换字符串中替换子串
Symbol.search
一个在调用String.prototype.search()方法时调用的方法
用于在字符串中定位子串
Symbol.species
用于创建派生对象的构造函数
Symbol.split
一个在调用String.prototype.split()方法时调用的方法
用于分割字符串
Symbol.toPrimitive
一个返回对象原始值的方法
Symbol.toStringTag
一个在调用Object.prototye.toString方法时使用的字符串
用于创建对象描述
Symbol.unscopables
一个定义了一些不可被with语句引用的对象属性名称的对象集合
7、Set集合与Map集合
ECMAScript5中的Set与Map集合
在es5中开发者用对象属性来模拟这两种集合
该解决方案的一些问题
待完善
ECMAScript6中的Set集合
定义
是一种有序列表
含有一些相互独立的非重复值
能更有效地追踪各种离散值
是一个强引用的Set集合
创建Set集合并添加元素
方法
调用new Set()创建Set集合
调用add()方法向集合中添加元素
访问集合的size属性可以获取集合中目前的元素数量
has()
可以检测Set集合种是否存在某个值
补充:不会对所存值进行强制的类型转换
如数字5和字符串”5“可以作为两个独立元素存在
唯一的例外时+0,和-0被认为是相等的
set构造函数会过滤掉重复的值,从而保证集合中的元素各自唯一
移除元素
方法
delete()
可以移除Set集合种的某一个元素
clear()
会移除集合中的所有元素
Set集合中的forEach()方法
参数
Set集合中下一次索引的位置
参数一
与第一个参数一样的值
参数二
被遍历的Set集合本身
参数三
与数组中的forEach()的异同
Set中回调函数前两个参数的值是一样的
Map集合的forEach()方法和数组的接收的参数都是三个参数u,前两个时值和键名
值
键名
被遍历的集合
注意:你不能通过索引访问集合中的元素。如果有需要,最好先将Set集合转换成一个数组
将Set集合转换为数组
运用展开运算符(...)
它可以将数组中的元素分解为各自独立的函数参数
Weak Set集合(弱引用Set集合)
特点
Weak Set集合只存储对象的弱引用,并且不可以存储原始值;
集合中的弱引用如果是对象唯一的引用,则会被回收并释放内存
创建Weak Set集合
方法
new WeakSet()
可以创建WeakSet集合
add()
has()
delete()
参数
只能为对象或着是对象的集合
不接受任何原始值
如果包含其他非对象值,程序会抛出错误
两种Set类型的主要区别
WeakSet 保存的对象值是弱引用
最大区别
在WeakSet的实例中,如果向add()方法传入非对象参数会导致程序抛错,而向has()和delete()方法传入非对象参数则会返回false
WeakSet集合不可迭代,所以不能被用于for-of循环
WeakSet集合不暴露任何迭代器(例如keys(),values()方法),所以无法通过程序本身来检测其中的内容
WeakSet集合不支持forEach方法
WeakSet集合不支持size属性
总之:如果你只需要跟踪对象引用,你更应该使用WeakSet集合而不是普通的Set集合
Set类型可以用来处理列表中的值,但是不适用于处理键值对这样的信息结构
ECMAScript6中的Map集合
概述
es6中的Map
许多键值对
有序列表
Object.is()
等价性判断是通过该方法来实现的
所以字符串”5“和数字5会被判定为两种类型,可以分别作为两个独立的键出现在程序中
这一点与对象不太一样,对象中的属性名总会被强制转换成字符串类型
键
可以用对象作为对象属性的键名
对象不可以
方法
set(key,value)
含义
向Map集合中添加新的元素
参数
键名
参数一
value值
参数二
get(key)
含义
从集合中获取信息
参数
键名
如不存在返回‘undefined’
has(key)
检测指定的键名在Mao集合中是否已经存在
delete(key)
从Map集合中移除指定键名及其对应的值
clear(key)
移除Map集合中所有键值对
属性
size
代表当前集合种哦那个包含的键值对数量
Map集合的forEach(value,key,map)
WeakMap
是弱引用的Mao集合
键名必须是一个非null类型的对象
如果不是对象则会报错
如果在弱引用外不存在其他的强引用,引擎的垃圾回收机制会自动回收这个对象,同时移除WeakMap中的键值对
创建一个私有数据
主要问题
是否只用对象作为集合的键名
是:weakMap
相对Map集合而言,Weak Map集合对用户的可见度更低,其不支持通过
forEach()
size属性
clear()方法
8、迭代器(Iterator)和生成器(Generator)
出现该方法之前的Javascript历史问题
循环语句的问题
当多个循环嵌套则需要追踪多个变量代码复杂度会大大增加
容易错误使用了其他for循环的跟踪变量
迭代器
定义
是一种特殊对象
方法
next()方法
每次调用会返回一个结果对象
结果对象
属性
value:表示下一个将要返回的值
done:是一个bool类型,当没有更多可返回数据时返回true
迭代器会保存一个内部指针,用来指向当前集合中值的位置
每调用一次next()方法都会返回下一个可用的值
优点
可以极大地简化数据操作
es5实现方法
生成器
定义
是一个返回迭代器的函数
通过function 关键字后的星号(*)来表示
可以紧挨function关键字 也可以在中间添一个空格
yield
每当执行完一条yield语句后函数就会自动停止执行
使用限制
只可在生成器内部使用,在生成器内部的函数里使用也会报错
生成器函数表达式
注意不能使用箭头函数来创建生成器
生成器对象的方法
生成器默认会为Symbol.Iterator属性赋值,因此所有通过生成器创建的迭代器都是可迭代对象
可迭代对象和for-of循环
可迭代对象
相关定义
具有Symbol.iterator属性
Symbol.Iterator通过制定的函数返回一个作用于附属对象的迭代器
是一种与迭代器密切相关的对象
由于具有Symbol.Iterator属性的对象都有默认的迭代器因此可以用它检测对象是否为可迭代器
在ES6中所有的集合对象(数组,Set集合及Map集合)和字符串都是可迭代对象,这些对象中都有默认的迭代器
ES6中新加入的特性for-of循环需要用到可迭代对象的这些功能
创建可迭代对象
默认情况下,开发者定义的对象都是不可迭代对象
但如果给Symbol.iterator属性添加一个生成器
则可以将其变为可迭代对象
for-of循环
每执行一次
限制
用于不可迭代对象、null、或undefined 将会导致程序抛出错误
内建迭代器
集合对象迭代器
集合对象
数组
Map集合、
Set集合
迭代器
entries()
定义
返回一个迭代器
其值为多个键值对
return(返回值)
返回一个数组,数组中两个元素分别表示集合中每个元素的键与值
被遍历的对象是
数组
索引
值
Set集合
两个是相同的值
Map集合
键值(key)
值(value)
values()
定义
返回一个迭代器
其值为集合的值
keys()
定义
返回一个迭代器
其值为集合中所有键名
对于数组对象,无论是否为数组添加命名属性,打印出来的都是数字类型的索引‘
而for -in 循环迭代的是数组属性,而不是数字类型的索引
9、JavaScript中的类
ES5中的近类结构
类的声明
基本的类声明语法
建议在构造函数中创建所有自有属性
与函数不同的是,类属性不可被赋予新值,在之前的示例中PersonClass.prototype就是这样一个只可读的类属性
为何使用类语法
函数声明可以被提升,而类声明与let声明类似,不能被提升:真正执行声明语句之前,他们会一直存在于临时死区
类声明中的所有代码将自动运行在严格模式下,且无法强行让代码脱离严格模式执行
在自定义类型中,需要通过Object.defineProperty()方法手工指定某个方法为不可枚举;而在类中,所有方法都是不可枚举的
每个类都有一个名为[[construct]]的内部方法,通过关键字new调用那些不含[[construct]]的方法会导致程序抛出错误
使用除关键字new以外的方式调用类的构造函数会导致程序抛出错误
在类中修改类名会导致程序报错
额外:常量类名
类的名称只在类中为常量,
在类的方法中不能修改类名
内部是通过const命名
但可以在外部修改
外部是通过let命名
类表达式
存在形式
声明形式
由function和class定义
表达式形式
基本的类表达式语法
命名类表达式
声明时在关键字后class后添加一个标识符
作为一等公民的类
一等公民
可以传入函数,可以从函数返回,并且可以赋值给变量的值
可以将类作为参数传入函数中、
可计算成员名称
用方括号包裹一个表达式即可使用可计算名称
属性名可以设置为用[]包着的变量
生成器方法
静态成员
继承与派生类
es6之前的继承
es6的等价版本
super()
通过调用super()方法即可访问基类的构造函数。
如果在派生类欸中指定了构造函数,则必须要调用super(),如果不这样做程序就会报错。
如果选择不使用构造函数,则当创建新的类实例时会自动调用super()并传入所有参数
使用super()的小贴士
只可在派生类的构造函数中使用super()如果尝试在非派生类(不是用extends声明的类)或函数中使用则会导致程序抛出错误
在构造函数中访问this之前一定要调用super(),它负责初始化this,如果在调用super()之前尝试访问this会导致程序出错
如果不想调用super(),则唯一的方法时让类的构造函数返回一个对象
类方法遮蔽
派生类中的方法总会覆盖基类中的同名方法
静态成员继承
如果基类有静态成员,那么这些静态成员在派生类中也可以用
派生自表达式的类
只要表达式可以被解析为一个函数并且具有[[construct]]属性和原型,那么就可以用extends进行派生
动态地确定类的继承目标
创建mixin
注意:
extends后可以使用任意表达式,但不是所有表达式最终都能生成合法的类。如果使用null或生成器函数会导致错误,类在这些情况下没有[[construct]]属性
内建对象地继承(未读 p203)
Symbol.species属性
在类的构造函数中使用new.target(未读 p208)
参数:
正则表达式/RegExp对象
es6
创建数组
es6以前
创建数组:均需列举数组中地元素
调用Array构造函数new
数组字面量
Array.of()
添加原因
帮助开发者们规避通过Array构造函数创建数组时的怪异行为
工作机制
总会创建一个包含所有参数的数组,不因参数的不同而改变
注意·:
Array.of方法不通过Symbol.species属性确定返回值的类型,他使用当前构造函数(也就是of()方法中的this值)来确定正确的返回类型
Array.from()方法
概述
es5中类数组对象转化为数组
参数一
可迭代对象或类数组对象
必选
通过this来确定返回数组类型的
映射转换
参数二
映射函数
该函数,会将类数组对象中的每一个值转换成其他形式,最后将结果储存在结果数组的相应索引中
参数三
表示映射函数的this值
可选
Array.from()转换可迭代对象
能将所有含有Symbol.iterator属性的对象转换为数组
为所有数组添加的新办法
find()方法和findIndex()方法
协助开发者在数组中查找任意值
参数
参数一
回调函数
回调函数的参数
该元素
该元素在数组中的索引值
数组本身
参数二
指定回调函数的this的值
可选
返回值
返回true时,find()方法和findIndex()方法都会立即停止
区别
find返回查找到的值
findIndex返回查找到值的索引
优点
按某个条件查找时,用find和findIndex()方法更适合
反之,按某个值匹配的元素时用indexOf和lastIndexOf()更适合
es5中
indexOf()
lastIndexOf()
缺点
只能查找一个值
fill方法
功能
用指定的值填充一至多个数组元素
传入一个值时,fill()方法会用这个值重写数组中的所有值
参数
参数一:
指定的值
参数二:
开始索引
可选
参数三
不包含结束索引
不包含结束索引当前值
可选
注意:
当索引值为负数时,这些值会与length值相加来作最终位置
copyWithin()方法
功能
从数组中复制元素的值
参数
1、
设置该位置的值,为得到的值
被粘贴的位置
paste
2、
得到该位置的值
被复制得位置
copy
3、
指定停止复制值的位置
不包含当前索引所指向的值
[set,get,get停止的位置(不包含当前位置的值)]
遍历数组方法
entries()方法
键值对的遍历
keys()方法
键的遍历
values()方法
值的遍历
定型数组
概述
是一种用于处理数值类型数据的专用数组
就是将任何数字转换为一个包含数字比特的数组
引入定型数组是为了提供高性能的算术运算
数值数据类型
有符号的8位整数int8
无符号的8位整数uint8
int 16
uint16
int32
uint32
float32
float64
数组缓冲区
新建数组缓冲区
new操作符
slice()将已有的数组缓冲区来创建一个新的
通过视图操作数组缓冲区
视图:用来操作内存的接口
可以操作与数组缓冲区或缓冲区字节的子集
数据缓冲区:是内存中的一段地址
DataView类型
是一种通用的数组缓冲区视图
其支持所有8种数值型数据类型
获取视图信息
buffer
视图绑定的数组缓冲区
byteOffset
DataView构造函数的第二个参数,默认是0,只有传入参数时才有值
byteLength
DataView构造函数的第三个参数,默认是缓冲区的长度byteLength
读取和写入数据
getInt8(byteOffset,littleEndian)
setInt8(byteOffset,value,littleEndian)
getUnit8(byteOffset,littleEndian)
setUint8(byteOffset,value,littleEndian)
es6之前
检测数组
instanceof
弊端:
假定只有一个全局执行环境。如果有多个框架或全局执行环境时会有不同的构造函数
Array.isArray(value)
目的是最终确定某个值到底是不是数组,而不管他是在哪个全局执行环境中创建的。
转换方法
toString()方法
会返回由数组中每个值得字符串形式拼接而成得一个以逗号分隔的字符串。
valueOf()方法
返回的还是数组本身
toLocaleString()方法
会返回由数组中每个值得字符串形式拼接而成得一个以逗号分隔的字符串。
不同之处
为了取得每一项的值,调用的是每一项的toLocaleString()方法
join()方法
可以使用不同的分隔符来构建字符串
参数:
用作分隔符的字符串,如不传值或传undefined则默认为“,”逗号
栈方法
push()方法
接受任意数量的参数,把他们逐个添加到数组末尾,并返回修改后的数组的长度
返回新数组的长度
pop()方法
删除从末尾移除最后一项,减少数组的length值
返回被移除项的值
队列方法
shift()方法
移除数组中第一个项,并返回该项
返回被移除项的值
unshift()方法
在数组前端添加任意个项,并返回新数组的长度。
返回新数组的长度
重排序方法
reverse()方法
反转数组项的顺序
sort()方法
默认为升序排序数组项
参数:
比较函数
比较函数接收两个参数
第一参数位于第二个参数前的则返回一个负数
相等,为0
第一个位于第二个参数后,则为正数
操作方法
concat()
基于当前数组中的所有项创建一个新数组
slice()方法
基于当前数组中的一个或多个项创建一个新数组。
参数
1、起始位置
2、结束位置
不包含该位置的项
只有一个参数时,从起始位置到数组末尾的所有项
splice()方法
用途
删除
删除第一项的位置
删除的项数
插入
起始位置
0(要删除的项数)
要插入的项
替换
起始位置
要删除的项数
要插入的任意数量的项
位置方法
indexOf()方法
参数:
要查找的项
表示查找起点位置的项(可选)
从数组开头向后查找
没找到返回-1
lastIndexOf()方法
参数:
要查找的项
表示查找起点位置的项(可选)
也是从后面向前数的位置项
从数组的末尾开始向前查找
没找到返回-1
迭代方法
every()
参数
运行的函数(可选)
函数的参数:
item
index
array
运行该函数的作用域对象-影响this值
条件
每一项都返回true
返回值
true
filter()方法
参数
运行的函数(可选)
函数的参数:
item
index
array
运行该函数的作用域对象-影响this值
条件
返回值
返回该函数会返回true的项组成的数组
forEach()
参数
运行的函数(可选)
函数的参数:
item
index
array
运行该函数的作用域对象-影响this值
条件
返回值
无返回值
map()
参数
运行的函数(可选)
函数的参数:
item
index
array
运行该函数的作用域对象-影响this值
条件
返回值
返回每次函数调用的结果组成的数组
some()
参数
运行的函数(可选)
函数的参数:
item
index
array
运行该函数的作用域对象-影响this值
条件
任一项返回ture
返回值
true
归并方法
reduce()
参数
运行的函数(可选)
函数的参数:
prev
前一个值
cur
当前值
index
项的索引、
array
数组对象
作为归并基础的初始值
从数组的第一项开始,逐个遍历到最后
reduceRight()
参数
运行的函数(可选)
函数的参数:
prev
前一个值
cur
当前值
index
项的索引、
array
数组对象
作为归并基础的初始值
从数组的最后一项开始,逐个遍历到第一项
11、Promise与异步编程
异步编程的背景知识
事件模型
回调模式
Promise的基础知识
Promise的生命周期
状态
pending
进行中
Fulfilled
Promise异步操作成功完成
Rejected
Promise异步操作未能成功完成
方法
then()
参数
参数一:当promise状态变为fulfilled时要调用的函数
与异步操作相关附加数据都会传递给这个完成函数
参数二:当状态变为rejected状态时调用的函数
创建未完成的Promise
使用Promise的构造函数
创建已处理的Promise
使用Promise.resolve()
已完成态
使用Promise.reject()
已拒绝态
非Promise的Thenable对象
构成:
then()方法
参数1:resolve
参数2:reject
调用Promise.resolve()方法将Thenable对象转换成一个已完成的Promise
执行器错误
全局的Promise拒绝处理
Node.js环境的拒绝处理
浏览器环境的拒绝处理
unhandledrejection
当Promise被拒绝,并且没有提供拒绝处理程序时,触发该事件
rejectionhandled
当Promise被拒绝时,若拒绝处理程序被调用,触发该事件
接受一个有以下属性的事件对象作为参数
type
事件名称
unhandlerejecttion
rejectionhandled
promise
被拒绝的Promise对象
reason
来自Promise的拒绝值
跟踪未处理拒绝的代码
串联Promise
概念
每次调用then()或catch()方法时实际上创建并返回了另一个Promise。
只有当第一个Promise完成或被拒绝后,第二个才会被拒绝
捕获错误
链式Promise调用可以感知到链中其他Promise的错误
务必在Promise链的末尾留有一个拒绝处理程序以确保能够正确处理所有可能发生的错误
Promise链的返回值
在Promise链中返回Promise
响应多个Promise
Promise.all()方法
概念
只接受一个参数并返回一个Promise
参数:一个含有多个受监视Promise的可迭代对象(例如一个数组)
必须所有Promise都被完成后返回的Promise才会被完成
只要有一个被拒绝,那么返回的Promise没等所有Promise都完成,都立即被拒绝
Promise.race()方法
参数:一个含有多个受监视Promise的可迭代对象(例如一个数组)
只要有一个Promise被解决返回的Promise就被解决
自Promise继承
基于Promise的异步任务执(未读,待完善)
12、代理(Proxy)和反射(Reflection)API(未读,待完善)
13、用模块封装代码
什么是模块
模块是自动运行在严格模式下并且没有办法退出运行的JavaScript代码。
特性:
this的值是undefined;
模块不支持HTML风格的代码注释
脚本,也就是任何不是模块的JavaScript代码
导出的基本语法
export关键字
将一部分已发布的代码暴露给其他模块
可以将expor放在任何变量、函数或类声明的前面
导入的基本语法
import
基本形式
大括号:表示从给定模块导入的绑定(binding)
关键字from:表示从哪个模块导入给定的绑定,该模块由表示模块路径的字符串指定(被成为模块说明符)
导入一个绑定时,他就好像使用const定义的一样,无法定义一个同名变量
导入单个绑定
导入多个绑定
导入整个模块
注意:
不管在import语句中把一个模块写了多少次,该模块将只执行一次
导入绑定的一个微妙怪异之处:
标识符只有在被导出的模块中可以修改,即便是导入绑定的模块也无法更改绑定的值
模块语法的限制
export和import的一个重要的限制是,他们必须在其他语句和函数之外使用
不能动态地导入或导出绑定
导出和导入时重命名
as关键字
模块的默认值
导出默认值
default关键字
导入默认值
用逗号将默认的本地名称与大括号包裹的非默认值分隔开。
在import语句中,默认值必须排在非默认值之前
重新导出一个绑定
无绑定导入
内建对象(如Array和Object)的共享定义可在模块中访问,对这些对象所做的更改将反映在其他模块中
加载模块
在web浏览器中使用模块
在<script>中使用模块
当type属性的值位‘module’时支持加载模块。
将type设置位“module”可以让浏览器所有内联代码/包含在src指定的文件中的代码按照模块而非脚本的方式加载
web浏览器中的模块加载顺序
模块按照他们出现在HTML文件中的顺序执行
不管他是内联还是src属性
按需加载
下载并解析module.js
递归下载并解析module.js中导入的资源
解析内联模块
递归下载并解析内联模块中导入的资源
下载并解析module2.js
递归下载并解析module2.js中导入的资源
加载完成,被完全解析后的执行顺序
递归执行module.js中导入的资源
执行module.js
递归执行内联模块中导入的资源
执行内联模块
递归执行module2.js中导入的资源
执行module2.js
注意:内联模块与另两个模块不同的是:它不必先下载模块代码
web浏览器中异步模块加载
async属性
应用于脚本时
脚本文件将在文件完全下载并解析后执行
不必等待包含的文档完成解析
应用在模块时
脚本文件将在文件完全下载并解析后执行
不必等待包含的文档完成解析
区别:模块在执行前,模块中所有的导入资源都必须下载
将模块作为Worker加载
浏览器模块说明符解析
模块说明符
以/开头的解析为根目录开始
以./开头的解析为当前目录开始
以../开头的解析为父目录开始
URL格式
总结
es6中的模块是一种打包和封装功能的方式
模块的行为与脚本不同,模块不会将它的顶级变量,函数和类修改为全局作用域,而且this值为undefined.
必须导出所有要让模块使用者使用的功能,变量、函数和类都可以导出,每个模块还可以有一个默认的导出值。
导入后的名称表现得像const定义的一样,无法重新声明它
模块只操作全局作用域,则不需导出任何值
通过<script type = "module"加载的模块文件默认具有defer属性。在文档完全被解析之后,模块也按照他们在包含文档中出现顺序依次执行
14、字符串的扩展
方法
字符的Unicode表示法
定位字符位置
之前
charAt
对于utf-16这种4个字节的字符,JavaScript 不能正确处理,字符串长度会误判为2,而且charAt方法无法读取整个字符
charCodeAt
只能分别返回前两个字节和后两个字节的值。
es6
codePointAt
够正确处理 4 个字节储存的字符,返回一个字符的码点。
codePointAt方法会正确返回 32 位的 UTF-16 字符的码点。对于那些两个字节储存的常规字符,它的返回结果与charCodeAt方法相同。
ES6之前的字符串
方法
字符方法
charAt(location:number)
参数是
基于0的字符位置
返回给定位置的哪个字符
charCodeAt()
参数是
基于0的字符位置
返回给定位置字符的字符编码。不是那个字符
方括号加数字索引来访问字符串中的特定字符
String.fromCharCode()方法
接收一个或多个字符编码,然后将他们转换成一个字符串
本质上来看这个方法与实例方法charCodeAt()方法执行的是相反的操作
字符串操作方法
concat()
将一或多个字符串拼接起来
原字符串不变,返回一个新的字符串
slice()
参数
1、子字符串开始的位置
2、子字符串结束的位置,但不包含该位置上的字符
参数是负值时:负值与字符串的长度相加
原字符串不变,返回一个新的字符串
substr()
参数
1、子字符串开始的位置
2、返回字符的个数,默认值为:字符串的末尾作为结束位置
不同点,与另外两个不同的地方
参数是负值时:负值与字符串的长度相加。第二个转化为0。
原字符串不变,返回一个新的字符串
substring()
参数
1、子字符串开始的位置
2、子字符串结束的位置,但不包含该位置上的字符
参数为负值时:所有参数均转换为0。
原字符串不变,返回一个新的字符串
trim()方法
删除前缀,后缀的所有空格
原字符串不变,返回一个新的字符串
localeCompare()方法
比较两个字符串,并返回下列值中的一个:
如果字符串在字母表中应该排在字符串参数前,则返回一个负数-1
如果字符串等于字符串参数,则返回0
如果字符串在字母表中应该排在字符串参数之后,则返回一个正数1
字符串位置方法
indexOf()
参数:
1、子字符串
2、开始查找的位置(包含该位置)
从该位置往后查找
返回:该参数在字符上的位置
规则从前往后查找
lastIndexOf()
参数:
1、子字符串
2、开始查找的位置(包含该位置)
从该位置往前查找
返回:该参数在字符上的位置
规则:从后往前查找
字符串大小转换方法
toLowerCase()
toUpperCase()
toLocaleUpperCase()
toLocalLowerCase()
字符串的模式匹配方法
match()方法
参数:
正则表达式/RegExp对象
search()方法
参数:
字符串/正则表达式/RegExp对象
返回:第一个匹配项的索引,如没有找到返回-1
replace()方法
参数
1、一个RegExg对象/字符串、
字符串的时候,只能匹配第一个,如想匹配其他的,则必须用正则表达式
2、字符串/函数
参数为函数的时候:
会向这个函数传递3个参数
模式的匹配项
模式匹配项在字符串中的位置
原始字符串
用第二个参数替换第一个参数
split()方法
基于指定的分隔符将一个字符串分割成多个子字符串,并将结果放在一个数组中。
参数:
1、字符串/RegExg对象
2、(可选)指定返回数组的大小
替换文本
$$
$
$&
匹配整个模式的子字符串。与RegExg.lastMatch的值相同
$'
匹配的子字符串之前的子字符串。
与RegExg.leftContext的值相同
$`
匹配的子字符串之后的子字符串。
与RegExg.rightContext的值相同
$n
匹配第n各捕获组的子字符串,其中n等于0~9.
$nn
匹配第nn个捕获组的子字符串,其中nn等于01~99.
es6扩展的方法
codePointAt()方法
能正确返回需要4个字节存储的字符编码。js默认以2个字节存储字符
String.fromCodePoint()方法
优化了es5中的fromCharCode()方法
字符串的遍历器接口
for...of
遍历字符串
最大优点:是可以识别大于0xFFFF的码点
for循环会认为它包含2个字符
at()
优化了charAt()方法,识别大于0xFFFF的字符
normalize()
将字符的不同表达方法,统一为同样的形式
参数:
1、NFC,默认参数,标准等价合成
语义,视觉均等价
2、NFD,标准等价分解
3、NFKC,兼容等价合成
语义等价,视觉不等价
4、NFKD,兼容等价分解
确定一个字符串是否包含在另一个字符串中
includes()
返回bool值,表示是否找到了参数字符串
参数
字符串
n,表示开始搜索的位置,从第n个到字符串结束的位置
startsWith()
返回bool值,表示参数字符串是否在源字符串的头部
参数
字符串
n,表示开始搜索的位置,从第n个到字符串结束的位置
endsWith()
返回bool值,表示参数字符串是否在源字符串的尾部
参数
字符串
n,表示前n个字符中
repeat()方法
返回一个新字符串,表示将原字符串重复n次
padStart()、padEnd()
字
字符串补全长度的功能。
padStart()
用于头部补全
参数
指定字符串最小的长度
用来补全的字符串
padEnd()
用于尾部补全 v
参数
指定字符串最小的长度
用来补全的字符串
es6and js
es6
1、块级作用域绑定
块级声明
let声明
禁止重声明
const声明
一旦设定不可更改
临时死区
循环中的块作用域绑定
ES6 声明变量的六种方法
var
var 声明及变量提升机制
无论在哪里声明,都会被当作当前作用域顶部声明的变量
function
const
不可变
其余跟let类似
本质
对于变量
实际上保证的是变量指向的那个内存地址所保存的数据不得改动
对于引用类型(复合类型)的数据
变量指向的内存地址,保存的只是一个指向实际数据的指针
const只能保证这个指针是固定的
至于它指向的数据结构是不是可变的,就完全不能控制了。因此,将一个对象声明为常量必须非常小心。
真的想将对象冻结.可使用Object.freeze({})方法
class
let
不存在变量提升
暂时性死区
使用let命令声明变量之前,该变量都不可用
不允许重复声明
增加了块级作用域
块级作用域使IIFE立即执行表达式不再必要
es6中明确允许在块级作用域中声明函数.
ES6规定块级作用中,函数声明语句的行为类似于let,在块级作用域之外不可引用
import
子主题
kmn
函数
es6的默认参数值
可以为其提供初始值
默认参数值对arguments对象的影响
在非严格模式下,命名参数的变化会同步更新到arguments的对象中
在严格模式下。,命名参数的变化,不会导致arguments改变
展开运算符
明确函数的多种用途
js函数有两个不同的内部方法:[[call]]和[[construct]].
通过nwe关键字调用函数的是[[construct]]
创建一个被称为实例的新对象
执行函数体
将this绑定到实例上
不通过new关键字调用函数是[[call]]
在es5中判断函数被调用的方法
用instanceof
元属性 new.target
为了解决判断函数是否通过new关键字调用的问题
解决了在es5中,call方法也能不通过new创建而通过es5中的判断
必须通过new关键字调用
块级函数
块级作用域内部的函数在块级之前的外面也可以访问到,在块级结束后,会将该函数移除
es6将其标准化
箭头函数
差异
与传统函数的不同
没有this、super、argument、new.target绑定
这些值由外围最近一层非箭头函数决定
不能通过new关键字调用
没有原型
不可以改变this的绑定
不支持arguments对象
没有自己的arguments对象,但可以访问外围的函数的arguments对象
不支持重复的命名参数
差异产生的原因
this绑定丢失
减少错误以及理清模糊不清的地方。
箭头函数也有一个name属性值
语法
创建立即执行函数表达式
你可以定义一个匿名函数并立即调用,自始自终不保存对函数的引用。当想创建一个与其他程序隔离的作用域时,这种模式非常方便
箭头函数与正常函数创建的立即执行函数表达式的不同
小括号只包裹箭头函数定义,没有包含(‘Nicholas’)
正常函数定义的立即执行函数表达式既可以用小括号包裹函数体,也可以额外包裹函数调用部分
箭头函数内没有this绑定
箭头函数与数组
箭头函数没有arguments绑定
没有自己的arguments对象,但可以访问外围的函数的arguments对象
尾调用优化
尾调用指的是函数作为另一个函数的最后一条语句被调用
es6中对尾调用的优化
作用:
缩减了严格模式下尾调用栈的大小
条件
满足以下条件,尾调用不再创建新的栈顶,而且清除并重用当前的栈帧
尾调用的结果作为函数值返回
尾调用不访问当前栈帧的变量
在函数内部,尾调用是最后一条语句
对象
对象
什么是面向对象
Javascript对象的特征
对象具有唯一标识性:即使完全相同的两个对象,也并非同一个对象.
对象有状态:对象具有状态,同一对象可能处于不同状态之下
对象具有行为:即对象的状态,可能因为它的行为产生变迁
扩展对象的功能性
对象类别
普通(ordinary)对象
具有js对象所有的默认内部行为
特异(Exotic)对象
具有某些与默认行为不符的内部行为
标准(standard)对象
ECMAScript 6规范中定义的对象
标准对象既可以是普通对象,也可以是特意对象
内建对象
脚本开始执行时存在于JavaScript执行环境中的对象
所有标准对象都是内建对象
对象字面量语法扩展
属性初始值的简写
当一个对象的属性与本地变量同名时,不必再写冒号和值,简单的只写属性名即可
对象方法的简写语法
消除了冒号和function关键字
区别:简写方法可以使用super关键字
可计算的属性名
用方括号包含变量名,会算出变量名的值,来当属性名
新增方法
Object.is()
弥补全等运算符的不准确运算
与全等运算符(===)唯一的区别,时能识别+0,-0;NaN与NaN
Object.assign()
混合(Mixin)时js实现对象组合最流行的一种模式
在一个mixin方法中,一个对象接收l来自了另一个对象的属性和方法
Object.assign()方法可以接受任意数量的源对象,并按指定的顺序将属性复制到接受对象中。
如果多个源对象具有同名属性,则排位靠后的源对象会覆盖排位靠前的。
不能将提供者的访问器属性复制到接收对象中,但会将其转变为接收对象的一个属性
自由属性枚举规则
规则
所有数字键按升序排序
所有字符串键按照他们被加入对象的顺序排序
所有symbol键按照他们加入对象的顺序排序
涉及到的方法
Object.getOwnPropertyNames()方法
Reflect.ownKeys
Object.getOwnPropertyNames
不会被影响到的方法
Object.keys()方法
JSON.stringify()方法
for ...in..
增强对象原型
改变对象的原型
Object.setPrototypeOf( )
参数
被改变原型的对象
替代第一个参数原型的对象
扩展
正常情况下无论是通过构造函数还是Object.create()方法创建对象,其原型是在对象创建时指定的
es5中添加了Object.getPrototypesOf( )方法来返回任意指定对象的原型
简化原型访问的Super引用
限制
必须在简写方法的对象中使用Super引用
super引用不是动态变化的,它总是指向正确的对象,
Super的苏勇引用都是通过[[HomeObject]]属性来确定后续的运行过程。
第一步,是在[[HomeObject]]属性上调用Object。getPrototypeOf()方法来检索原型的引用;
通过原型找到同名函数
设置this绑定并且调用相应的方法
正式的方法定义
[[HomeObject]]属性
用途
用来容纳这个方法从属的对象
5、解构:使数据访问更加便捷
基本用法
这种写法属于“模式匹配”,只要等号两边的模式相同,左边的变量就会被赋予对应的值。下面是一些使用嵌套数组进行解构的例子。
只要某种数据结构具有 Iterator 接口,都可以采用数组形式的解构赋值
如Set,Map,Generator(生成器)
不完全解构
报错
如果解构不成功,变量的值就等于undefined。
如果等号的右边不是数组(或者严格地说,不是可遍历的结构,参见《Iterator》一章),那么将会报错
对象的解构赋值
对象的解构与数组有一个重要的不同
数组的元素是按次序排列的
对象变量必须与属性同名,才能取到正确的值
如果变量名与属性名不一致,必须写成这样。
对象的解构赋值的内部机制是先找到同名属性,然后再赋值给对应的变量
真正被赋值的是后者,而不是前者
对象的解构也可以指定默认值
嵌套赋值
失败
如果解构失败,变量的值等于undefined
如果解构模式是嵌套的对象,而且子对象所在的父属性不存在,那么将会报错。
如果要将一个已经声明的变量用于解构赋值,必须非常小心。
解构赋值允许等号左边的模式之中,不放置任何变量名。
对象的解构赋值,可以很方便地将现有对象的方法,赋值到某个变量。
数组本质是特殊的对象,因此可以对数组进行对象属性的解构。
字符串的解构赋值
原因
字符串也可以解构赋值。这是因为此时,字符串被转换成了一个类似数组的对象。
类似数组的对象都有一个length属性,因此还可以对这个属性解构赋值。
数值和布尔值的解构赋值
解析赋值的规则
只要等号右边的值不是对象或数组,就先将其转为对象。由于undefined和null无法转为对象,所以对它们进行解构赋值,都会报错。
圆括号问题
建议只要有可能,就不要在模式中放置圆括号。
不能使用圆括号的情况
1)变量声明语句
2)函数参数
3)赋值语句的模式
可以使用圆括号的情况
赋值语句的非模式部分,可以使用圆括号。
函数参数的解构赋值
undefined会触发函数参数的默认值
默认值生效的条件是,对象的属性值严格等于undefined
函数参数的解构使用默认值
用途
交换变量的值
从函数返回多个值
函数参数的定义
方便地将一组参数与变量名对应起来
提取 JSON 数据
函数参数的默认值
指定参数的默认值,就避免了在函数体内部再写var foo = config.foo || 'default foo';这样的语句。
遍历 Map 结构
如果只想获取键名,或者只想获取键值
输入模块的指定方法
6、Symbol和Symbol属性
概述
ECMAScript5及早期版本中,语言包含5种原始类型
字符串型
数字型
布尔型、
null
undefined
ECMAScript6中引入了第6种原始类型:Symbol
2021年新增BigInt类型
创建Symbol
注意:
由于Symbol 是原始值,因此调用new Symbol会导致程序抛出错误
参数
可选
让你添加一段文本描述即将创建的Symbol
这段描述不可用于属性访问,但是建议你在每次创建Symbol时都添加这一段描述
会被存储在内部的[[Description]]属性中,只有当调用Symbol的toString()方法时,才可读取这个属性。
在执行console.log种会隐式的调用toString()方法
他的描述会被打印到日志中,但不能直接在代码中访问
Symbol的辨识方法
typeof
Symbol的使用方法
使用地点
所有使用可计算属性名
可计算对象字面量属性名
Object.defineProperty()
Object.defineProperties()方法
Symbol共享体系
创建一个可共享的Symbol
Symbol.for()方法
参数一
用途:即将创建的Symbol的字符串标识符
用途二:也作为Symbol的描述
过程
首先在全局Symbo表中搜索键为“uid”的Symbol是否存在
存在:直接返回已有的Symbol
不存在:
创建一个新的Symbol
并使用这个键在Symbol全局注册表中注册
返回新创建的Symbol
共享相关的特性
Symbol.keyFor()方法
使用该方法在Symbol全局注册表中检索与Symbol有关的键
注意:使用let uid3 = Symbol("description"),并不会在全局注册表中注册该Symbol
Symbol与类型强制转换
不能将Symbol强制转换为字符串和数字类型
子主题
Symbol属性检索
扩展
检索对象中所有的属性名
Object.key()
返回所有可枚举䣌属性名
Object.getOwnPropertyNames()
不考虑属性的可枚举性一律返回
两种方法均不支持Symbol属性
Object.getOwnPropertySymbols()
ES6新增方法
用来检索对象中的Symbol属性
返回值是一个包含所有Symbol自有属性的数组
well-known Symbol
包括
Symbol.hasInstance
用于检测对象的继承信息
一个在执行instanceof时调用的内部方法
Symbol.isConcatSpreadable
一个布尔值
用来表示当传递一个集合作为Array.prototype.concat()方法的参数时,是否应该将集合内的元素规整到同一层级
Symbol.iterator
一个返回迭代器的方法
Symbol.match
一个在调用String.prototype.match()方法时调用的方法,用来比较字符串
Symbol.replace
一个在调用String.prototype.replace()方法时调用的方法,用于替换字符串中替换子串
Symbol.search
一个在调用String.prototype.search()方法时调用的方法
用于在字符串中定位子串
Symbol.species
用于创建派生对象的构造函数
Symbol.split
一个在调用String.prototype.split()方法时调用的方法
用于分割字符串
Symbol.toPrimitive
一个返回对象原始值的方法
Symbol.toStringTag
一个在调用Object.prototye.toString方法时使用的字符串
用于创建对象描述
Symbol.unscopables
一个定义了一些不可被with语句引用的对象属性名称的对象集合
7、Set集合与Map集合
ECMAScript5中的Set与Map集合
在es5中开发者用对象属性来模拟这两种集合
该解决方案的一些问题
待完善
ECMAScript6中的Set集合
定义
是一种有序列表
含有一些相互独立的非重复值
能更有效地追踪各种离散值
是一个强引用的Set集合
创建Set集合并添加元素
方法
调用new Set()创建Set集合
调用add()方法向集合中添加元素
访问集合的size属性可以获取集合中目前的元素数量
has()
可以检测Set集合种是否存在某个值
补充:不会对所存值进行强制的类型转换
如数字5和字符串”5“可以作为两个独立元素存在
唯一的例外时+0,和-0被认为是相等的
set构造函数会过滤掉重复的值,从而保证集合中的元素各自唯一
移除元素
方法
delete()
可以移除Set集合种的某一个元素
clear()
会移除集合中的所有元素
Set集合中的forEach()方法
参数
Set集合中下一次索引的位置
参数一
与第一个参数一样的值
参数二
被遍历的Set集合本身
参数三
与数组中的forEach()的异同
Set中回调函数前两个参数的值是一样的
Map集合的forEach()方法和数组的接收的参数都是三个参数u,前两个时值和键名
值
键名
被遍历的集合
注意:你不能通过索引访问集合中的元素。如果有需要,最好先将Set集合转换成一个数组
将Set集合转换为数组
运用展开运算符(...)
它可以将数组中的元素分解为各自独立的函数参数
Weak Set集合(弱引用Set集合)
特点
Weak Set集合只存储对象的弱引用,并且不可以存储原始值;
集合中的弱引用如果是对象唯一的引用,则会被回收并释放内存
创建Weak Set集合
方法
new WeakSet()
可以创建WeakSet集合
add()
has()
delete()
参数
只能为对象或着是对象的集合
不接受任何原始值
如果包含其他非对象值,程序会抛出错误
两种Set类型的主要区别
WeakSet 保存的对象值是弱引用
最大区别
在WeakSet的实例中,如果向add()方法传入非对象参数会导致程序抛错,而向has()和delete()方法传入非对象参数则会返回false
WeakSet集合不可迭代,所以不能被用于for-of循环
WeakSet集合不暴露任何迭代器(例如keys(),values()方法),所以无法通过程序本身来检测其中的内容
WeakSet集合不支持forEach方法
WeakSet集合不支持size属性
总之:如果你只需要跟踪对象引用,你更应该使用WeakSet集合而不是普通的Set集合
Set类型可以用来处理列表中的值,但是不适用于处理键值对这样的信息结构
ECMAScript6中的Map集合
概述
es6中的Map
许多键值对
有序列表
Object.is()
等价性判断是通过该方法来实现的
所以字符串”5“和数字5会被判定为两种类型,可以分别作为两个独立的键出现在程序中
这一点与对象不太一样,对象中的属性名总会被强制转换成字符串类型
键
可以用对象作为对象属性的键名
对象不可以
方法
set(key,value)
含义
向Map集合中添加新的元素
参数
键名
参数一
value值
参数二
get(key)
含义
从集合中获取信息
参数
键名
如不存在返回‘undefined’
has(key)
检测指定的键名在Mao集合中是否已经存在
delete(key)
从Map集合中移除指定键名及其对应的值
clear(key)
移除Map集合中所有键值对
属性
size
代表当前集合种哦那个包含的键值对数量
Map集合的forEach(value,key,map)
WeakMap
是弱引用的Mao集合
键名必须是一个非null类型的对象
如果不是对象则会报错
如果在弱引用外不存在其他的强引用,引擎的垃圾回收机制会自动回收这个对象,同时移除WeakMap中的键值对
创建一个私有数据
主要问题
是否只用对象作为集合的键名
是:weakMap
相对Map集合而言,Weak Map集合对用户的可见度更低,其不支持通过
forEach()
size属性
clear()方法
8、迭代器(Iterator)和生成器(Generator)
出现该方法之前的Javascript历史问题
循环语句的问题
当多个循环嵌套则需要追踪多个变量代码复杂度会大大增加
容易错误使用了其他for循环的跟踪变量
迭代器
定义
是一种特殊对象
方法
next()方法
每次调用会返回一个结果对象
结果对象
属性
value:表示下一个将要返回的值
done:是一个bool类型,当没有更多可返回数据时返回true
迭代器会保存一个内部指针,用来指向当前集合中值的位置
每调用一次next()方法都会返回下一个可用的值
优点
可以极大地简化数据操作
es5实现方法
生成器
定义
是一个返回迭代器的函数
通过function 关键字后的星号(*)来表示
可以紧挨function关键字 也可以在中间添一个空格
yield
每当执行完一条yield语句后函数就会自动停止执行
使用限制
只可在生成器内部使用,在生成器内部的函数里使用也会报错
生成器函数表达式
注意不能使用箭头函数来创建生成器
生成器对象的方法
生成器默认会为Symbol.Iterator属性赋值,因此所有通过生成器创建的迭代器都是可迭代对象
可迭代对象和for-of循环
可迭代对象
相关定义
具有Symbol.iterator属性
Symbol.Iterator通过制定的函数返回一个作用于附属对象的迭代器
是一种与迭代器密切相关的对象
由于具有Symbol.Iterator属性的对象都有默认的迭代器因此可以用它检测对象是否为可迭代器
在ES6中所有的集合对象(数组,Set集合及Map集合)和字符串都是可迭代对象,这些对象中都有默认的迭代器
ES6中新加入的特性for-of循环需要用到可迭代对象的这些功能
创建可迭代对象
默认情况下,开发者定义的对象都是不可迭代对象
但如果给Symbol.iterator属性添加一个生成器
则可以将其变为可迭代对象
for-of循环
每执行一次
限制
用于不可迭代对象、null、或undefined 将会导致程序抛出错误
内建迭代器
集合对象迭代器
集合对象
数组
Map集合、
Set集合
迭代器
entries()
定义
返回一个迭代器
其值为多个键值对
return(返回值)
返回一个数组,数组中两个元素分别表示集合中每个元素的键与值
被遍历的对象是
数组
索引
值
Set集合
两个是相同的值
Map集合
键值(key)
值(value)
values()
定义
返回一个迭代器
其值为集合的值
keys()
定义
返回一个迭代器
其值为集合中所有键名
对于数组对象,无论是否为数组添加命名属性,打印出来的都是数字类型的索引‘
而for -in 循环迭代的是数组属性,而不是数字类型的索引
9、JavaScript中的类
ES5中的近类结构
类的声明
基本的类声明语法
建议在构造函数中创建所有自有属性
与函数不同的是,类属性不可被赋予新值,在之前的示例中PersonClass.prototype就是这样一个只可读的类属性
为何使用类语法
函数声明可以被提升,而类声明与let声明类似,不能被提升:真正执行声明语句之前,他们会一直存在于临时死区
类声明中的所有代码将自动运行在严格模式下,且无法强行让代码脱离严格模式执行
在自定义类型中,需要通过Object.defineProperty()方法手工指定某个方法为不可枚举;而在类中,所有方法都是不可枚举的
每个类都有一个名为[[construct]]的内部方法,通过关键字new调用那些不含[[construct]]的方法会导致程序抛出错误
使用除关键字new以外的方式调用类的构造函数会导致程序抛出错误
在类中修改类名会导致程序报错
额外:常量类名
类的名称只在类中为常量,
在类的方法中不能修改类名
内部是通过const命名
但可以在外部修改
外部是通过let命名
类表达式
存在形式
声明形式
由function和class定义
表达式形式
基本的类表达式语法
命名类表达式
声明时在关键字后class后添加一个标识符
作为一等公民的类
一等公民
可以传入函数,可以从函数返回,并且可以赋值给变量的值
可以将类作为参数传入函数中、
可计算成员名称
用方括号包裹一个表达式即可使用可计算名称
属性名可以设置为用[]包着的变量
生成器方法
静态成员
继承与派生类
es6之前的继承
es6的等价版本
super()
通过调用super()方法即可访问基类的构造函数。
如果在派生类欸中指定了构造函数,则必须要调用super(),如果不这样做程序就会报错。
如果选择不使用构造函数,则当创建新的类实例时会自动调用super()并传入所有参数
使用super()的小贴士
只可在派生类的构造函数中使用super()如果尝试在非派生类(不是用extends声明的类)或函数中使用则会导致程序抛出错误
在构造函数中访问this之前一定要调用super(),它负责初始化this,如果在调用super()之前尝试访问this会导致程序出错
如果不想调用super(),则唯一的方法时让类的构造函数返回一个对象
类方法遮蔽
派生类中的方法总会覆盖基类中的同名方法
静态成员继承
如果基类有静态成员,那么这些静态成员在派生类中也可以用
派生自表达式的类
只要表达式可以被解析为一个函数并且具有[[construct]]属性和原型,那么就可以用extends进行派生
动态地确定类的继承目标
创建mixin
注意:
extends后可以使用任意表达式,但不是所有表达式最终都能生成合法的类。如果使用null或生成器函数会导致错误,类在这些情况下没有[[construct]]属性
内建对象地继承(未读 p203)
Symbol.species属性
在类的构造函数中使用new.target(未读 p208)
参数:
正则表达式/RegExp对象
10、改进地数组功能
es6
创建数组
es6以前
创建数组:均需列举数组中地元素
调用Array构造函数new
数组字面量
Array.of()
添加原因
帮助开发者们规避通过Array构造函数创建数组时的怪异行为
工作机制
总会创建一个包含所有参数的数组,不因参数的不同而改变
注意·:
Array.of方法不通过Symbol.species属性确定返回值的类型,他使用当前构造函数(也就是of()方法中的this值)来确定正确的返回类型
Array.from()方法
概述
es5中类数组对象转化为数组
参数一
可迭代对象或类数组对象
必选
通过this来确定返回数组类型的
映射转换
参数二
映射函数
该函数,会将类数组对象中的每一个值转换成其他形式,最后将结果储存在结果数组的相应索引中
参数三
表示映射函数的this值
可选
Array.from()转换可迭代对象
能将所有含有Symbol.iterator属性的对象转换为数组
Array.from方法还支持类似数组的对象。所谓类似数组的对象,本质特征只有一点,即必须有length属性
因此,任何有length属性的对象,都可以通过Array.from方法转为数组,而此时扩展运算符就无法转换。
应用
取出一组DOM节点的文本内容
将bool值为false的成员转为0
返回各种数据的类型
将字符串转为数组,然后返回字符串的长度
因为它能正确处理各种 Unicode 字符,可以避免 JavaScript 将大于\uFFFF的 Unicode 字符,算作两个字符的 bug。
为所有数组添加的新办法
find()方法和findIndex()方法
协助开发者在数组中查找任意值
参数
参数一
回调函数
回调函数的参数
该元素(value)
该元素在数组中的索引值(index)
数组本身(arr)
所有数组成员依次执行该回调函数,直到找出第一个返回值为true的成员,然后返回该成员。如果没有符合条件的成员,则返回undefined。
参数二
指定回调函数的this的值
可选
返回值
返回true时,find()方法和findIndex()方法都会立即停止
区别
find返回查找到的值
如所有成员都不符合条件,返回undefined
findIndex返回第一个查到值的索引(位置),
如所有成员都不符合条件,返回-1
优点
按某个条件查找时,用find和findIndex()方法更适合
反之,按某个值匹配的元素时用indexOf和lastIndexOf()更适合
这两个方法都可以发现NaN,弥补了数组的indexOf方法的不足。
es5中
indexOf()
lastIndexOf()
缺点
只能查找一个值
fill方法
功能
用指定的值填充一至多个数组元素
传入一个值时,fill()方法会用这个值重写数组中的所有值
参数
参数一:
指定的值
参数二:
开始索引
可选
参数三
不包含结束索引
不包含结束索引当前值
可选
注意:
当索引值为负数时,这些值会与length值相加来作最终位置
copyWithin()方法
功能
从数组中复制元素的值
参数
1、
设置该位置的值,为得到的值
被粘贴的位置
target
2、
得到该位置的值
被复制得位置
start
3、
指定停止复制值的位置
不包含当前索引所指向的值
end
[set,get,get停止的位置(不包含当前位置的值)]
返回值
修改当前数组本身
遍历数组方法
entries()方法
键值对的遍历
keys()方法
键的遍历
values()方法
值的遍历
flat(),flatMap()
用于将嵌套的数组“拉平”,变成一维的数组。该方法返回一个新数组,对原数据没有影响
flat()默认只会“拉平”一层,如果想要“拉平”多层的嵌套数组,可以将flat()方法的参数写成一个整数,表示想要拉平的层数,默认为1。
flatMap()方法对原数组的每个成员执行一个函数(相当于执行Array.prototype.map()),然后对返回值组成的数组执行flat()方法。该方法返回一个新数组,不改变原数组。
include()
表示某个数组是否包含给定的值,与字符串的includes方法类似。ES2016 引入了该方法
参数
给定的值
搜索的起始位置,默认为0
如果第二个参数为负数,则表示倒数的位置,如果这时它大于数组长度(比如第二个参数为-4,但数组长度为3),则会重置为从0开始
返回值
bool值,是否存在
定型数组
概述
是一种用于处理数值类型数据的专用数组
就是将任何数字转换为一个包含数字比特的数组
引入定型数组是为了提供高性能的算术运算
数值数据类型
有符号的8位整数int8
无符号的8位整数uint8
int 16
uint16
int32
uint32
float32
float64
数组缓冲区
新建数组缓冲区
new操作符
slice()将已有的数组缓冲区来创建一个新的
通过视图操作数组缓冲区
视图:用来操作内存的接口
可以操作与数组缓冲区或缓冲区字节的子集
数据缓冲区:是内存中的一段地址
DataView类型
是一种通用的数组缓冲区视图
其支持所有8种数值型数据类型
获取视图信息
buffer
视图绑定的数组缓冲区
byteOffset
DataView构造函数的第二个参数,默认是0,只有传入参数时才有值
byteLength
DataView构造函数的第三个参数,默认是缓冲区的长度byteLength
读取和写入数据
getInt8(byteOffset,littleEndian)
setInt8(byteOffset,value,littleEndian)
getUnit8(byteOffset,littleEndian)
setUint8(byteOffset,value,littleEndian)
es6之前
检测数组
instanceof
弊端:
假定只有一个全局执行环境。如果有多个框架或全局执行环境时会有不同的构造函数
Array.isArray(value)
目的是最终确定某个值到底是不是数组,而不管他是在哪个全局执行环境中创建的。
转换方法
toString()方法
会返回由数组中每个值得字符串形式拼接而成得一个以逗号分隔的字符串。
valueOf()方法
返回的还是数组本身
toLocaleString()方法
会返回由数组中每个值得字符串形式拼接而成得一个以逗号分隔的字符串。
不同之处
为了取得每一项的值,调用的是每一项的toLocaleString()方法
join()方法
可以使用不同的分隔符来构建字符串
参数:
用作分隔符的字符串,如不传值或传undefined则默认为“,”逗号
栈方法
push()方法
接受任意数量的参数,把他们逐个添加到数组末尾,并返回修改后的数组的长度
返回新数组的长度
pop()方法
删除从末尾移除最后一项,减少数组的length值
返回被移除项的值
队列方法
shift()方法
移除数组中第一个项,并返回该项
返回被移除项的值
unshift()方法
在数组前端添加任意个项,并返回新数组的长度。
返回新数组的长度
重排序方法
reverse()方法
反转数组项的顺序
sort()方法
默认为升序排序数组项
参数:
比较函数
比较函数接收两个参数
第一参数位于第二个参数前的则返回一个负数
相等,为0
第一个位于第二个参数后,则为正数
操作方法
concat()
基于当前数组中的所有项创建一个新数组
slice()方法
基于当前数组中的一个或多个项创建一个新数组。
参数
1、起始位置
2、结束位置
不包含该位置的项
只有一个参数时,从起始位置到数组末尾的所有项
splice()方法
用途
删除
删除第一项的位置
删除的项数
插入
起始位置
0(要删除的项数)
要插入的项
替换
起始位置
要删除的项数
要插入的任意数量的项
位置方法
indexOf()方法
参数:
要查找的项
表示查找起点位置的项(可选)
从数组开头向后查找
没找到返回-1
lastIndexOf()方法
参数:
要查找的项
表示查找起点位置的项(可选)
也是从后面向前数的位置项
从数组的末尾开始向前查找
没找到返回-1
迭代方法
every()
参数
运行的函数(可选)
函数的参数:
item
index
array
运行该函数的作用域对象-影响this值
条件
每一项都返回true
返回值
true
filter()方法
参数
运行的函数(可选)
函数的参数:
item
index
array
运行该函数的作用域对象-影响this值
条件
返回值
返回该函数会返回true的项组成的数组
forEach()
参数
运行的函数(可选)
函数的参数:
item
index
array
运行该函数的作用域对象-影响this值
条件
返回值
无返回值
map()
参数
运行的函数(可选)
函数的参数:
item
index
array
运行该函数的作用域对象-影响this值
条件
返回值
返回每次函数调用的结果组成的数组
some()
参数
运行的函数(可选)
函数的参数:
item
index
array
运行该函数的作用域对象-影响this值
条件
任一项返回ture
返回值
true
归并方法
reduce()
参数
运行的函数(可选)
函数的参数:
prev
前一个值
cur
当前值
index
项的索引、
array
数组对象
作为归并基础的初始值
从数组的第一项开始,逐个遍历到最后
reduceRight()
参数
运行的函数(可选)
函数的参数:
prev
前一个值
cur
当前值
index
项的索引、
array
数组对象
作为归并基础的初始值
从数组的最后一项开始,逐个遍历到第一项
11、Promise与异步编程
异步编程的背景知识
事件模型
回调模式
Promise的基础知识
Promise的生命周期
状态
pending
进行中
Fulfilled
Promise异步操作成功完成
Rejected
Promise异步操作未能成功完成
方法
then()
参数
参数一:当promise状态变为fulfilled时要调用的函数
与异步操作相关附加数据都会传递给这个完成函数
参数二:当状态变为rejected状态时调用的函数
创建未完成的Promise
使用Promise的构造函数
创建已处理的Promise
使用Promise.resolve()
已完成态
使用Promise.reject()
已拒绝态
非Promise的Thenable对象
构成:
then()方法
参数1:resolve
参数2:reject
调用Promise.resolve()方法将Thenable对象转换成一个已完成的Promise
执行器错误
全局的Promise拒绝处理
Node.js环境的拒绝处理
浏览器环境的拒绝处理
unhandledrejection
当Promise被拒绝,并且没有提供拒绝处理程序时,触发该事件
rejectionhandled
当Promise被拒绝时,若拒绝处理程序被调用,触发该事件
接受一个有以下属性的事件对象作为参数
type
事件名称
unhandlerejecttion
rejectionhandled
promise
被拒绝的Promise对象
reason
来自Promise的拒绝值
跟踪未处理拒绝的代码
串联Promise
概念
每次调用then()或catch()方法时实际上创建并返回了另一个Promise。
只有当第一个Promise完成或被拒绝后,第二个才会被拒绝
捕获错误
链式Promise调用可以感知到链中其他Promise的错误
务必在Promise链的末尾留有一个拒绝处理程序以确保能够正确处理所有可能发生的错误
Promise链的返回值
在Promise链中返回Promise
响应多个Promise
Promise.all()方法
概念
只接受一个参数并返回一个Promise
参数:一个含有多个受监视Promise的可迭代对象(例如一个数组)
必须所有Promise都被完成后返回的Promise才会被完成
只要有一个被拒绝,那么返回的Promise没等所有Promise都完成,都立即被拒绝
Promise.race()方法
参数:一个含有多个受监视Promise的可迭代对象(例如一个数组)
只要有一个Promise被解决返回的Promise就被解决
自Promise继承
基于Promise的异步任务执(未读,待完善)
12、代理(Proxy)和反射(Reflection)API(未读,待完善)
13、用模块封装代码
什么是模块
模块是自动运行在严格模式下并且没有办法退出运行的JavaScript代码。
特性:
this的值是undefined;
模块不支持HTML风格的代码注释
脚本,也就是任何不是模块的JavaScript代码
导出的基本语法
export关键字
将一部分已发布的代码暴露给其他模块
可以将expor放在任何变量、函数或类声明的前面
导入的基本语法
import
基本形式
大括号:表示从给定模块导入的绑定(binding)
关键字from:表示从哪个模块导入给定的绑定,该模块由表示模块路径的字符串指定(被成为模块说明符)
导入一个绑定时,他就好像使用const定义的一样,无法定义一个同名变量
导入单个绑定
导入多个绑定
导入整个模块
注意:
不管在import语句中把一个模块写了多少次,该模块将只执行一次
导入绑定的一个微妙怪异之处:
标识符只有在被导出的模块中可以修改,即便是导入绑定的模块也无法更改绑定的值
模块语法的限制
export和import的一个重要的限制是,他们必须在其他语句和函数之外使用
不能动态地导入或导出绑定
导出和导入时重命名
as关键字
模块的默认值
导出默认值
default关键字
导入默认值
用逗号将默认的本地名称与大括号包裹的非默认值分隔开。
在import语句中,默认值必须排在非默认值之前
重新导出一个绑定
无绑定导入
内建对象(如Array和Object)的共享定义可在模块中访问,对这些对象所做的更改将反映在其他模块中
加载模块
在web浏览器中使用模块
在<script>中使用模块
当type属性的值位‘module’时支持加载模块。
将type设置位“module”可以让浏览器所有内联代码/包含在src指定的文件中的代码按照模块而非脚本的方式加载
web浏览器中的模块加载顺序
模块按照他们出现在HTML文件中的顺序执行
不管他是内联还是src属性
按需加载
下载并解析module.js
递归下载并解析module.js中导入的资源
解析内联模块
递归下载并解析内联模块中导入的资源
下载并解析module2.js
递归下载并解析module2.js中导入的资源
加载完成,被完全解析后的执行顺序
递归执行module.js中导入的资源
执行module.js
递归执行内联模块中导入的资源
执行内联模块
递归执行module2.js中导入的资源
执行module2.js
注意:内联模块与另两个模块不同的是:它不必先下载模块代码
web浏览器中异步模块加载
async属性
应用于脚本时
脚本文件将在文件完全下载并解析后执行
不必等待包含的文档完成解析
应用在模块时
脚本文件将在文件完全下载并解析后执行
不必等待包含的文档完成解析
区别:模块在执行前,模块中所有的导入资源都必须下载
将模块作为Worker加载
浏览器模块说明符解析
模块说明符
以/开头的解析为根目录开始
以./开头的解析为当前目录开始
以../开头的解析为父目录开始
URL格式
总结
es6中的模块是一种打包和封装功能的方式
模块的行为与脚本不同,模块不会将它的顶级变量,函数和类修改为全局作用域,而且this值为undefined.
必须导出所有要让模块使用者使用的功能,变量、函数和类都可以导出,每个模块还可以有一个默认的导出值。
导入后的名称表现得像const定义的一样,无法重新声明它
模块只操作全局作用域,则不需导出任何值
通过<script type = "module"加载的模块文件默认具有defer属性。在文档完全被解析之后,模块也按照他们在包含文档中出现顺序依次执行
14、字符串的扩展
方法
字符的Unicode表示法
定位字符位置
之前
charAt
对于utf-16这种4个字节的字符,JavaScript 不能正确处理,字符串长度会误判为2,而且charAt方法无法读取整个字符
charCodeAt
只能分别返回前两个字节和后两个字节的值。
es6
codePointAt
够正确处理 4 个字节储存的字符,返回一个字符的码点。
codePointAt方法会正确返回 32 位的 UTF-16 字符的码点。对于那些两个字节储存的常规字符,它的返回结果与charCodeAt方法相同。
ES6之前的字符串
方法
字符方法
charAt(location:number)
参数是
基于0的字符位置
返回给定位置的哪个字符
charCodeAt()
参数是
基于0的字符位置
返回给定位置字符的字符编码。不是那个字符
方括号加数字索引来访问字符串中的特定字符
String.fromCharCode()方法
接收一个或多个字符编码,然后将他们转换成一个字符串
本质上来看这个方法与实例方法charCodeAt()方法执行的是相反的操作
字符串操作方法
concat()
将一或多个字符串拼接起来
原字符串不变,返回一个新的字符串
slice()
参数
1、子字符串开始的位置
2、子字符串结束的位置,但不包含该位置上的字符
参数是负值时:负值与字符串的长度相加
原字符串不变,返回一个新的字符串
substr()
参数
1、子字符串开始的位置
2、返回字符的个数,默认值为:字符串的末尾作为结束位置
不同点,与另外两个不同的地方
参数是负值时:负值与字符串的长度相加。第二个转化为0。
原字符串不变,返回一个新的字符串
substring()
参数
1、子字符串开始的位置
2、子字符串结束的位置,但不包含该位置上的字符
参数为负值时:所有参数均转换为0。
原字符串不变,返回一个新的字符串
trim()方法
删除前缀,后缀的所有空格
原字符串不变,返回一个新的字符串
localeCompare()方法
比较两个字符串,并返回下列值中的一个:
如果字符串在字母表中应该排在字符串参数前,则返回一个负数-1
如果字符串等于字符串参数,则返回0
如果字符串在字母表中应该排在字符串参数之后,则返回一个正数1
字符串位置方法
indexOf()
参数:
1、子字符串
2、开始查找的位置(包含该位置)
从该位置往后查找
返回:该参数在字符上的位置
规则从前往后查找
lastIndexOf()
参数:
1、子字符串
2、开始查找的位置(包含该位置)
从该位置往前查找
返回:该参数在字符上的位置
规则:从后往前查找
字符串大小转换方法
toLowerCase()
toUpperCase()
toLocaleUpperCase()
toLocalLowerCase()
字符串的模式匹配方法
match()方法
参数:
正则表达式/RegExp对象
search()方法
参数:
字符串/正则表达式/RegExp对象
返回:第一个匹配项的索引,如没有找到返回-1
replace()方法
参数
1、一个RegExg对象/字符串、
字符串的时候,只能匹配第一个,如想匹配其他的,则必须用正则表达式
2、字符串/函数
参数为函数的时候:
会向这个函数传递3个参数
模式的匹配项
模式匹配项在字符串中的位置
原始字符串
用第二个参数替换第一个参数
split()方法
基于指定的分隔符将一个字符串分割成多个子字符串,并将结果放在一个数组中。
参数:
1、字符串/RegExg对象
2、(可选)指定返回数组的大小
替换文本
$$
$
$&
匹配整个模式的子字符串。与RegExg.lastMatch的值相同
$'
匹配的子字符串之前的子字符串。
与RegExg.leftContext的值相同
$`
匹配的子字符串之后的子字符串。
与RegExg.rightContext的值相同
$n
匹配第n各捕获组的子字符串,其中n等于0~9.
$nn
匹配第nn个捕获组的子字符串,其中nn等于01~99.
es6扩展的方法
codePointAt()方法
能正确返回需要4个字节存储的字符编码。js默认以2个字节存储字符
String.fromCodePoint()方法
优化了es5中的fromCharCode()方法
字符串的遍历器接口
for...of
遍历字符串
最大优点:是可以识别大于0xFFFF的码点
for循环会认为它包含2个字符
at()
优化了charAt()方法,识别大于0xFFFF的字符
normalize()
将字符的不同表达方法,统一为同样的形式
参数:
1、NFC,默认参数,标准等价合成
语义,视觉均等价
2、NFD,标准等价分解
在标准等价的前提下.,返回合成字符分解的字符
3、NFKC,兼容等价合成
语义等价,视觉不等价
4、NFKD,兼容等价分解
确定一个字符串是否包含在另一个字符串中
includes()
返回bool值,表示是否找到了参数字符串
参数
字符串
n,表示开始搜索的位置,从第n个到字符串结束的位置
startsWith()
返回bool值,表示参数字符串是否在源字符串的头部
参数
字符串
n,表示开始搜索的位置,从第n个到字符串结束的位置
endsWith()
返回bool值,表示参数字符串是否在源字符串的尾部
参数
字符串
n,表示前n个字符中
repeat()方法
返回一个新字符串,表示将原字符串重复n次
参数如果是小数,会被取整
参数是负数或者infinity,会报错
NaN等同于0
字符串补全长度的功能。
padStart()
用于头部补全
参数
指定字符串最小的长度
用来补全的字符串
padEnd()
用于尾部补全 v
参数
指定字符串最小的长度
用来补全的字符串
模板字符串
未理解
模板编译
标签模板
15、数值的扩展
Math对象的扩展
Math.trunc()
用于去除一个数的小数部分,返回整数部分
对于非数值,Math.trunc内部使用Number方法将其先专为数值
Math.sign()
用来判断一个数到底是正数、负数,还是零。对于非数值,会先将其专为数值
正数
负数
0
-0
NaN
Math.cbrt()
用于计算一个数的立方根
Math.clz32()
0 条评论
下一页