当前位置: 首页 > news >正文

江苏网站建设网络公司免费域名cn

江苏网站建设网络公司,免费域名cn,上线了 建立网站,在建设部网站修正 ES6是ECMA为JavaScript制定的第6个标准版本#xff0c;相关历史可查看此章节《ES6-ECMAScript6简介》。 标准委员会最终决定#xff0c;标准在每年6月正式发布并作为当年的正式版本#xff0c;接下来的时间里就在此版本的基础上进行改动#xff0c;直到下一年6月草案…修正 ES6是ECMA为JavaScript制定的第6个标准版本相关历史可查看此章节《ES6-ECMAScript6简介》。 标准委员会最终决定标准在每年6月正式发布并作为当年的正式版本接下来的时间里就在此版本的基础上进行改动直到下一年6月草案就自然变成新一年的版本这样一来就无需以前的版本号只要用年份标记即可。ECMAscript 2015是在2015年6月发布ES6的第一个版本。以此类推ECMAscript 2016是ES6的第二个版本、 ECMAscript 2017是ES6的第三个版本。**ES6**既是一个历史名词也是一个泛指含义是5.1版本以后的JavaScript下一代标准目前涵盖了ES2015、ES2016、ES2017、ES2018、ES2019。 所以有些文章上提到的ES7(实质上是ES2016)、ES8(实质上是ES2017)、ES9(实质上是ES2018)、ES10(实质上是ES2019)实质上都是一些不规范的概念。从ES1到ES6每个标准都是花了好几年甚至十多年才制定下来你一个ES6到ES7ES7到ES8才用了一年按照这样的定义下去那不是很快就ES20了。用正确的概念来说ES6目前涵盖了**ES2015(ES6.0)、ES2016(ES6.1)、ES2017(ES6.2)、ES2018(ES6.3)、ES2019**(ES6.4)。 另外ES6更新的内容主要分为以下几点 表达式声明、解构赋值内置对象字符串扩展、数值扩展、对象扩展、数组扩展、函数扩展、正则扩展、Symbol、Set、Map、Proxy、Reflect语句与运算Class、Module、Iterator异步编程Promise、Generator、Async ES2015 声明 const命令声明常量 let命令声明变量 作用 作用域 全局作用域函数作用域function() {}块级作用域{} 作用范围 var在全局代码中执行const和let只能在代码块中执行 赋值使用 const声明常量后必须立马赋值let声明变量后可立马赋值或使用时赋值 声明方法var、const、let、function、class、import 重点难点 不允许重复声明未定义就使用会报错const和let不存在变量提升暂时性死区只要块级作用域内存在const和let所声明常量和变量就绑定此区域不再受外部影响 解构赋值 字符串解构const [a, b, c, d, e] hello 数值解构const { toString: s } 123 布尔值解构const { toString: b } true 对象解构 形式const { x, y } { x: 1, y: 2 }默认const { x, y 2 } { x: 1 }改名const { x, y: z } { x: 1, y: 2 } 数组解构 规则数据结构具有Iterator接口可采用数组形式的解构赋值形式const [x, y] [1, 2]默认const [x, y 2] [1] 函数参数解构 数组解构function Func([x 0, y 1]) {} 对象解构function Func({ x 0, y 1 } {}) {} 应用场景 交换变量值[x, y] [y, x]返回函数多个值const [x, y, z] Func()定义函数参数Func([1, 2])提取JSON数据const { name, version } packageJson定义函数参数默认值function Func({ x 1, y 2 } {}) {}遍历Map结构for (let [k, v] of Map) {}输入模块指定属性和方法const { readFile, writeFile } require(fs) 重点难点 匹配模式只要等号两边的模式相同左边的变量就会被赋予对应的值解构赋值规则只要等号右边的值不是对象或数组就先将其转为对象解构默认值生效条件属性值严格等于undefined解构遵循匹配模式解构不成功时变量的值等于undefinedundefined和null无法转为对象因此无法进行解构 字符串扩展 Unicode表示法大括号包含表示Unicode字符(\u{0xXX}或\u{0XXX}) 字符串遍历可通过for-of遍历字符串 字符串模板可单行可多行可插入变量的增强版字符串 标签模板函数参数的特殊调用 String.raw()返回把字符串所有变量替换且对斜杠进行转义的结果 String.fromCodePoint()返回码点对应字符 codePointAt()返回字符对应码点(String.fromCodePoint()的逆操作) normalize()把字符的不同表示方法统一为同样形式返回新字符串(Unicode正规化) repeat()把字符串重复n次返回新字符串 matchAll()返回正则表达式在字符串的所有匹配 includes()是否存在指定字符串 startsWith()是否存在字符串头部指定字符串 endsWith()是否存在字符串尾部指定字符串 重点难点 以上扩展方法均可作用于由4个字节储存的Unicode字符上 数值扩展 二进制表示法0b或0B开头表示二进制(0bXX或0BXX) 八进制表示法0o或0O开头表示二进制(0oXX或0OXX) Number.EPSILON数值最小精度 Number.MIN_SAFE_INTEGER最小安全数值(-2^53) Number.MAX_SAFE_INTEGER最大安全数值(2^53) Number.parseInt()返回转换值的整数部分 Number.parseFloat()返回转换值的浮点数部分 Number.isFinite()是否为有限数值 Number.isNaN()是否为NaN Number.isInteger()是否为整数 Number.isSafeInteger()是否在数值安全范围内 Math.trunc()返回数值整数部分 Math.sign()返回数值类型(正数1、负数-1、零0) Math.cbrt()返回数值立方根 Math.clz32()返回数值的32位无符号整数形式 Math.imul()返回两个数值相乘 Math.fround()返回数值的32位单精度浮点数形式 Math.hypot()返回所有数值平方和的平方根 Math.expm1()返回e^n - 1 Math.log1p()返回1 n的自然对数(Math.log(1 n)) Math.log10()返回以10为底的n的对数 Math.log2()返回以2为底的n的对数 Math.sinh()返回n的双曲正弦 Math.cosh()返回n的双曲余弦 Math.tanh()返回n的双曲正切 Math.asinh()返回n的反双曲正弦 Math.acosh()返回n的反双曲余弦 Math.atanh()返回n的反双曲正切 对象扩展 简洁表示法直接写入变量和函数作为对象的属性和方法({ prop, method() {} }) 属性名表达式字面量定义对象时使用[]定义键([prop]不能与上同时使用) 方法的name属性返回方法函数名 取值函数(getter)和存值函数(setter)get/set 函数名(属性的描述对象在get和set上)bind返回的函数bound 函数名Function构造函数返回的函数实例anonymous 属性的可枚举性和遍历描述对象的enumerable super关键字指向当前对象的原型对象(只能用在对象的简写方法中method() {}) Object.is()对比两值是否相等 Object.assign()合并对象(浅拷贝)返回原对象 Object.getPrototypeOf()返回对象的原型对象 Object.setPrototypeOf()设置对象的原型对象 proto返回或设置对象的原型对象 属性遍历 描述自身、可继承、可枚举、非枚举、Symbol遍历 for-in遍历对象自身可继承可枚举属性Object.keys()返回对象自身可枚举属性的键组成的数组Object.getOwnPropertyNames()返回对象自身可继承可枚举非枚举属性的键组成的数组Object.getOwnPropertySymbols()返回对象Symbol属性的键组成的数组Reflect.ownKeys()返回对象自身可继承可枚举非枚举Symbol属性的键组成的数组 规则 首先遍历所有数值键按照数值升序排列其次遍历所有字符串键按照加入时间升序排列最后遍历所有Symbol键按照加入时间升序排列 数组扩展 扩展运算符(…)转换数组为用逗号分隔的参数序列([...arr]相当于rest/spread参数的逆运算) Array.from()转换具有Iterator接口的数据结构为真正数组返回新数组 类数组对象包含length的对象、Arguments对象、NodeList对象可遍历对象String、Set结构、Map结构、Generator函数 Array.of()转换一组值为真正数组返回新数组 copyWithin()把指定位置的成员复制到其他位置返回原数组 find()返回第一个符合条件的成员 findIndex()返回第一个符合条件的成员索引值 fill()根据指定值填充整个数组返回原数组 keys()返回以索引值为遍历器的对象 values()返回以属性值为遍历器的对象 entries()返回以索引值和属性值为遍历器的对象 数组空位ES6明确将数组空位转为undefined(空位处理规不一建议避免出现) 扩展应用 克隆数组const arr [...arr1]合并数组const arr [...arr1, ...arr2]拼接数组arr.push(...arr1)代替applyMath.max.apply(null, [x, y]) Math.max(...[x, y])转换字符串为数组[...hello]转换类数组对象为数组[...Arguments, ...NodeList]转换可遍历对象为数组[...String, ...Set, ...Map, ...Generator]与数组解构赋值结合const [x, ...rest/spread] [1, 2, 3]计算Unicode字符长度Array.from(hello).length [...hello].length 重点难点 使用keys()、values()、entries()返回的遍历器对象可用for-of自动遍历或next()手动遍历 函数扩展 参数默认值为函数参数指定默认值 指定某个参数不得省略省略即抛出错误function Func(x throwMissing()) {}将参数默认值设为undefined表明此参数可省略Func(undefined, 1)形式function Func(x 1, y 2) {}参数赋值惰性求值(函数调用后才求值)参数位置尾参数参数作用域函数作用域声明方式默认声明不能用const或let再次声明length返回没有指定默认值的参数个数与解构赋值默认值结合function Func({ x 1, y 2 } {}) {}应用 rest/spread参数(…) 返回函数多余参数 形式以数组的形式存在之后不能再有其他参数作用代替Arguments对象length返回没有指定默认值的参数个数但不包括rest/spread参数 严格模式在严格条件下运行JS 应用只要函数参数使用默认值、解构赋值、扩展运算符那么函数内部就不能显式设定为严格模式 name属性返回函数的函数名 将匿名函数赋值给变量空字符串(ES5)、变量名(ES6)将具名函数赋值给变量函数名(ES5和ES6)bind返回的函数bound 函数名(ES5和ES6)Function构造函数返回的函数实例anonymous(ES5和ES6) 箭头函数()函数简写 并非因为内部有绑定this的机制而是根本没有自己的this导致内部的this就是外层代码块的this因为没有this因此不能用作构造函数无参数() {}单个参数x {}多个参数(x, y) {}解构参数({x, y}) {}嵌套使用部署管道机制this指向固定化 尾调用优化只保留内层函数的调用帧 定义函数尾调用自身作用只要使用尾递归就不会发生栈溢出相对节省内存实现把所有用到的内部变量改写成函数的参数并使用参数默认值定义某个函数的最后一步是调用另一个函数形式function f(x) { return g(x); }尾调用尾递归 箭头函数误区 函数体内的this是定义时所在的对象而不是使用时所在的对象可让this指向固定化这种特性很有利于封装回调函数不可当作构造函数因此箭头函数不可使用new命令不可使用yield命令因此箭头函数不能用作Generator函数不可使用Arguments对象此对象在函数体内不存在(可用rest/spread参数代替)返回对象时必须在对象外面加上括号 正则扩展 变更RegExp构造函数入参允许首参数为正则对象尾参数为正则修饰符(返回的正则表达式会忽略原正则表达式的修饰符) 正则方法调用变更字符串对象的match()、replace()、search()、split()内部调用转为调用RegExp实例对应的RegExp.prototype[Symbol.方法] u修饰符Unicode模式修饰符正确处理大于\uFFFF的Unicode字符 点字符(.)Unicode表示法量词预定义模式i修饰符转义 y修饰符粘连修饰符确保匹配必须从剩余的第一个位置开始全局匹配(与g修饰符作用类似) unicode是否设置u修饰符 sticky是否设置y修饰符 flags正则表达式的修饰符 重点难点 y修饰符隐含头部匹配标志^单单一个y修饰符对match()只能返回第一个匹配必须与g修饰符联用才能返回所有匹配 Symbol 定义独一无二的值声明const set Symbol(str)入参字符串(可选)方法 Symbol()创建以参数作为描述的Symbol值(不登记在全局环境)Symbol.for()创建以参数作为描述的Symbol值如存在此参数则返回原有的Symbol值(先搜索后创建登记在全局环境)Symbol.keyFor()返回已登记的Symbol值的描述(只能返回Symbol.for()的key)Object.getOwnPropertySymbols()返回对象中所有用作属性名的Symbol值的数组 内置 Symbol.hasInstance指向一个内部方法当其他对象使用instanceof运算符判断是否为此对象的实例时会调用此方法Symbol.isConcatSpreadable指向一个布尔值定义对象用于Array.prototype.concat()时是否可展开Symbol.species指向一个构造函数当实例对象使用自身构造函数时会调用指定的构造函数Symbol.match指向一个函数当实例对象被String.prototype.match()调用时会重新定义match()的行为Symbol.replace指向一个函数当实例对象被String.prototype.replace()调用时会重新定义replace()的行为Symbol.search指向一个函数当实例对象被String.prototype.search()调用时会重新定义search()的行为Symbol.split指向一个函数当实例对象被String.prototype.split()调用时会重新定义split()的行为Symbol.iterator指向一个默认遍历器方法当实例对象执行for-of时会调用指定的默认遍历器Symbol.toPrimitive指向一个函数当实例对象被转为原始类型的值时会返回此对象对应的原始类型值Symbol.toStringTag指向一个函数当实例对象被Object.prototype.toString()调用时其返回值会出现在toString()返回的字符串之中表示对象的类型Symbol.unscopables指向一个对象指定使用with时哪些属性会被with环境排除 数据类型 UndefinedNullStringNumberBooleanObject(包含Array、Function、Date、RegExp、Error)Symbol 应用场景 唯一化对象属性名属性名属于Symbol类型就都是独一无二的可保证不会与其他属性名产生冲突消除魔术字符串在代码中多次出现且与代码形成强耦合的某一个具体的字符串或数值遍历属性名无法通过for-in、for-of、Object.keys()、Object.getOwnPropertyNames()、JSON.stringify()返回只能通过Object.getOwnPropertySymbols返回启用模块的Singleton模式调用一个类在任何时候返回同一个实例(window和global)使用Symbol.for()来模拟全局的Singleton模式 重点难点 Symbol()生成一个原始类型的值不是对象因此Symbol()前不能使用new命令Symbol()参数表示对当前Symbol值的描述相同参数的Symbol()返回值不相等Symbol值不能与其他类型的值进行运算Symbol值可通过String()或toString()显式转为字符串Symbol值作为对象属性名时此属性是公开属性但不是私有属性Symbol值作为对象属性名时只能用方括号运算符([])读取不能用点运算符(.)读取Symbol值作为对象属性名时不会被常规方法遍历得到可利用此特性为对象定义非私有但又只用于内部的方法 Set Set 定义类似于数组的数据结构成员值都是唯一且没有重复的值声明const set new Set(arr)入参具有Iterator接口的数据结构属性 constructor构造函数返回Setsize返回实例成员总数 方法 add()添加值返回实例delete()删除值返回布尔值has()检查值返回布尔值clear()清除所有成员keys()返回以属性值为遍历器的对象values()返回以属性值为遍历器的对象entries()返回以属性值和属性值为遍历器的对象forEach()使用回调函数遍历每个成员 应用场景 去重字符串[...new Set(str)].join()去重数组[...new Set(arr)]或Array.from(new Set(arr))集合数组 声明const a new Set(arr1)、const b new Set(arr2)并集new Set([...a, ...b])交集new Set([...a].filter(v b.has(v)))差集new Set([...a].filter(v !b.has(v))) 映射集合 声明let set new Set(arr)映射set new Set([...set].map(v v * 2))或set new Set(Array.from(set, v v * 2)) 重点难点 遍历顺序插入顺序没有键只有值可认为键和值两值相等添加多个NaN时只会存在一个NaN添加相同的对象时会认为是不同的对象添加值时不会发生类型转换(5 ! 5)keys()和values()的行为完全一致entries()返回的遍历器同时包括键和值且两值相等 WeakSet 定义和Set结构类似成员值只能是对象声明const set new WeakSet(arr)入参具有Iterator接口的数据结构属性 constructor构造函数返回WeakSet 方法 add()添加值返回实例delete()删除值返回布尔值has()检查值返回布尔值 应用场景 储存DOM节点DOM节点被移除时自动释放此成员不用担心这些节点从文档移除时会引发内存泄漏临时存放一组对象或存放跟对象绑定的信息只要这些对象在外部消失它在WeakSet结构中的引用就会自动消失 重点难点 成员都是弱引用垃圾回收机制不考虑WeakSet结构对此成员的引用成员不适合引用它会随时消失因此ES6规定WeakSet结构不可遍历其他对象不再引用成员时垃圾回收机制会自动回收此成员所占用的内存不考虑此成员是否还存在于WeakSet结构中 Map Map 定义类似于对象的数据结构成员键可以是任何类型的值声明const set new Map(arr)入参具有Iterator接口且每个成员都是一个双元素数组的数据结构属性 constructor构造函数返回Mapsize返回实例成员总数 方法 get()返回键值对set()添加键值对返回实例delete()删除键值对返回布尔值has()检查键值对返回布尔值clear()清除所有成员keys()返回以键为遍历器的对象values()返回以值为遍历器的对象entries()返回以键和值为遍历器的对象forEach()使用回调函数遍历每个成员 重点难点 遍历顺序插入顺序对同一个键多次赋值后面的值将覆盖前面的值对同一个对象的引用被视为一个键对同样值的两个实例被视为两个键键跟内存地址绑定只要内存地址不一样就视为两个键添加多个以NaN作为键时只会存在一个以NaN作为键的值Object结构提供字符串—值的对应Map结构提供值—值的对应 WeakMap 定义和Map结构类似成员键只能是对象声明const set new WeakMap(arr)入参具有Iterator接口且每个成员都是一个双元素数组的数据结构属性 constructor构造函数返回WeakMap 方法 get()返回键值对set()添加键值对返回实例delete()删除键值对返回布尔值has()检查键值对返回布尔值 应用场景 储存DOM节点DOM节点被移除时自动释放此成员键不用担心这些节点从文档移除时会引发内存泄漏部署私有属性内部属性是实例的弱引用删除实例时它们也随之消失不会造成内存泄漏 重点难点 成员键都是弱引用垃圾回收机制不考虑WeakMap结构对此成员键的引用成员键不适合引用它会随时消失因此ES6规定WeakMap结构不可遍历其他对象不再引用成员键时垃圾回收机制会自动回收此成员所占用的内存不考虑此成员是否还存在于WeakMap结构中一旦不再需要成员会自动消失不用手动删除引用弱引用的只是键而不是值值依然是正常引用即使在外部消除了成员键的引用内部的成员值依然存在 Proxy 定义修改某些操作的默认行为声明const proxy new Proxy(target, handler)入参 target拦截的目标对象handler定制拦截行为 方法 Proxy.revocable()返回可取消的Proxy实例(返回{ proxy, revoke }通过revoke()取消代理) 拦截方式 get()拦截对象属性读取set()拦截对象属性设置返回布尔值has()拦截对象属性检查k in obj返回布尔值deleteProperty()拦截对象属性删除delete obj[k]返回布尔值defineProperty()拦截对象属性定义Object.defineProperty()、Object.defineProperties()返回布尔值ownKeys()拦截对象属性遍历for-in、Object.keys()、Object.getOwnPropertyNames()、Object.getOwnPropertySymbols()返回数组getOwnPropertyDescriptor()拦截对象属性描述读取Object.getOwnPropertyDescriptor()返回对象getPrototypeOf()拦截对象原型读取instanceof、Object.getPrototypeOf()、Object.prototype.__proto__、Object.prototype.isPrototypeOf()、Reflect.getPrototypeOf()返回对象setPrototypeOf()拦截对象原型设置Object.setPrototypeOf()返回布尔值isExtensible()拦截对象是否可扩展读取Object.isExtensible()返回布尔值preventExtensions()拦截对象不可扩展设置Object.preventExtensions()返回布尔值apply()拦截Proxy实例作为函数调用proxy()、proxy.apply()、proxy.call()construct()拦截Proxy实例作为构造函数调用new proxy() 应用场景 Proxy.revocable()不允许直接访问对象必须通过代理访问一旦访问结束就收回代理权不允许再次访问get()读取未知属性报错、读取数组负数索引的值、封装链式操作、生成DOM嵌套节点set()数据绑定(Vue数据绑定实现原理)、确保属性值设置符合要求、防止内部属性被外部读写has()隐藏内部属性不被发现、排除不符合属性条件的对象deleteProperty()保护内部属性不被删除defineProperty()阻止属性被外部定义ownKeys()保护内部属性不被遍历 重点难点 要使Proxy起作用必须针对实例进行操作而不是针对目标对象进行操作没有设置任何拦截时等同于直接通向原对象属性被定义为不可读写/扩展/配置/枚举时使用拦截方法会报错代理下的目标对象内部this指向Proxy代理 Reflect 定义保持Object方法的默认行为方法 get()返回对象属性set()设置对象属性返回布尔值has()检查对象属性返回布尔值deleteProperty()删除对象属性返回布尔值defineProperty()定义对象属性返回布尔值ownKeys()遍历对象属性返回数组(Object.getOwnPropertyNames()Object.getOwnPropertySymbols())getOwnPropertyDescriptor()返回对象属性描述返回对象getPrototypeOf()返回对象原型返回对象setPrototypeOf()设置对象原型返回布尔值isExtensible()返回对象是否可扩展返回布尔值preventExtensions()设置对象不可扩展返回布尔值apply()绑定this后执行指定函数construct()调用构造函数创建实例 设计目的 将Object属于语言内部的方法放到Reflect上将某些Object方法报错情况改成返回false让Object操作变成函数行为Proxy与Reflect相辅相成 废弃方法 Object.defineProperty() Reflect.defineProperty()Object.getOwnPropertyDescriptor() Reflect.getOwnPropertyDescriptor() 重点难点 Proxy方法和Reflect方法一一对应Proxy和Reflect联合使用前者负责拦截赋值操作后者负责完成赋值操作 数据绑定观察者模式 const observerQueue new Set(); const observe fn observerQueue.add(fn); const observable obj new Proxy(obj, {set(tgt, key, val, receiver) {const result Reflect.set(tgt, key, val, receiver);observerQueue.forEach(v v());return result;} });const person observable({ age: 25, name: Yajun }); const print () console.log(${person.name} is ${person.age} years old); observe(print); person.name Joway;Class 定义对一类具有共同特征的事物的抽象(构造函数语法糖) 原理类本身指向构造函数所有方法定义在prototype上可看作构造函数的另一种写法(Class Class.prototype.constructor) 方法和关键字 constructor()构造函数new命令生成实例时自动调用extends继承父类super新建父类的thisstatic定义静态属性方法get取值函数拦截属性的取值行为set存值函数拦截属性的存值行为 属性 proto构造函数的继承(总是指向父类)proto.proto子类的原型的原型即父类的原型(总是指向父类的__proto__)prototype.proto属性方法的继承(总是指向父类的prototype) 静态属性定义类完成后赋值属性该属性不会被实例继承只能通过类来调用 静态方法使用static定义方法该方法不会被实例继承只能通过类来调用(方法中的this指向类而不是实例) 继承 父类静态属性方法可被子类继承子类继承父类后可从super上调用父类静态属性方法作为函数调用只能在构造函数中调用super()内部this指向继承的当前子类(super()调用后才可在构造函数中使用this)作为对象调用在普通方法中指向父类的原型对象在静态方法中指向父类ES5实质先创造子类实例的this再将父类的属性方法添加到this上(Parent.apply(this))ES6实质先将父类实例的属性方法加到this上(调用super())再用子类构造函数修改this实质super显示定义使用constructor() { super(); }定义继承父类没有书写则显示定义子类继承父类子类使用父类的属性方法时必须在构造函数中调用super()否则得不到父类的this 实例类相当于实例的原型所有在类中定义的属性方法都会被实例继承 显式指定属性方法使用this指定到自身上(使用Class.hasOwnProperty()可检测到)隐式指定属性方法直接声明定义在对象原型上(使用Class.__proto__.hasOwnProperty()可检测到) 表达式 类表达式const Class class {}name属性返回紧跟class后的类名属性表达式[prop]Generator方法* mothod() {}Async方法async mothod() {} this指向解构实例属性或方法时会报错 绑定thisthis.mothod this.mothod.bind(this)箭头函数this.mothod () this.mothod() 属性定义位置 定义在构造函数中并使用this指向定义在类最顶层 new.target确定构造函数是如何调用 原生构造函数 String()Number()Boolean()Array()Object()Function()Date()RegExp()Error() 重点难点 在实例上调用方法实质是调用原型上的方法Object.assign()可方便地一次向类添加多个方法(Object.assign(Class.prototype, { ... }))类内部所有定义的方法是不可枚举的(non-enumerable)构造函数默认返回实例对象(this)可指定返回另一个对象取值函数和存值函数设置在属性的Descriptor对象上类不存在变量提升利用new.target Class写出不能独立使用必须继承后才能使用的类子类继承父类后this指向子类实例通过super对某个属性赋值赋值的属性会变成子类实例的属性使用super时必须显式指定是作为函数还是作为对象使用extends不仅可继承类还可继承原生的构造函数 私有属性方法 const name Symbol(name); const print Symbol(print); class Person {constructor(age) {this[name] Bruce;this.age age;}[print]() {console.log(${this[name]} is ${this.age} years old);} }复制 继承混合类 function CopyProperties(target, source) {for (const key of Reflect.ownKeys(source)) {if (key ! constructor key ! prototype key ! name) {const desc Object.getOwnPropertyDescriptor(source, key);Object.defineProperty(target, key, desc);}} } function MixClass(...mixins) {class Mix {constructor() {for (const mixin of mixins) {CopyProperties(this, new mixin());}}}for (const mixin of mixins) {CopyProperties(Mix, mixin);CopyProperties(Mix.prototype, mixin.prototype);}return Mix; } class Student extends MixClass(Person, Kid) {}Module 命令 默认导入导出export { default } from person整体导入导出export * from person按需导入导出export { age, name, sex } from person改名导入导出export { name as newName } from person具名改默认导入导出export { name as default } from person默认改具名导入导出export { default as name } from person默认导入import Person from person整体导入import * as Person from person按需导入import { age, name, sex } from person改名导入import { name as newName } from person自执导入import person复合导入import Person, { name } from person默认导出export default Person(导入时可指定模块任意名称无需知晓内部真实名称)单独导出export const name Bruce按需导出export { age, name, sex }(推荐)改名导出export { name as newName }export规定模块对外接口import导入模块内部功能复合模式export命令和import命令结合在一起写成一行变量实质没有被导入当前模块相当于对外转发接口导致当前模块无法直接使用其导入变量 继承默认导出和改名导出结合使用可使模块具备继承性设计思想尽量地静态化使得编译时就能确定模块的依赖关系以及输入和输出的变量严格模式ES6模块自动采用严格模式(不管模块头部是否添加use strict) 模块方案 CommonJS用于服务器(动态化依赖)AMD用于浏览器(动态化依赖)CMD用于浏览器(动态化依赖)UMD用于浏览器和服务器(动态化依赖)ESM用于浏览器和服务器(静态化依赖) 加载方式 运行时加载 定义整体加载模块生成一个对象再从对象上获取需要的属性和方法进行加载(全部加载)影响只有运行时才能得到这个对象导致无法在编译时做静态优化 编译时加载 定义直接从模块中获取需要的属性和方法进行加载(按需加载)影响在编译时就完成模块加载效率比其他方案高但无法引用模块本身(本身不是对象)可拓展JS高级语法(宏和类型校验) 加载实现 传统加载通过script进行同步或异步加载脚本 同步加载script src/scriptDefer异步加载script src defer/script(顺序加载渲染完再执行)Async异步加载script src async/script(乱序加载下载完就执行) 模块加载script typemodule src/script(默认是Defer异步加载) CommonJS和ESM的区别 CommonJS输出值的拷贝ESM输出值的引用 CommonJS一旦输出一个值模块内部的变化就影响不到这个值ESM是动态引用且不会缓存值模块里的变量绑定其所在的模块等到脚本真正执行时再根据这个只读引用到被加载的那个模块里去取值 CommonJS是运行时加载ESM是编译时加载 CommonJS加载模块是对象(即module.exports)该对象只有在脚本运行完才会生成ESM加载模块不是对象它的对外接口只是一种静态定义在代码静态解析阶段就会生成 Node加载 背景CommonJS和ESM互不兼容目前解决方案是将两者分开采用各自的加载方案 区分要求ESM采用.mjs后缀文件名 require()不能加载.mjs文件只有import命令才可加载.mjs文件.mjs文件里不能使用require()必须使用import命令加载文件 驱动node --experimental-modules file.mjs 限制Node的import命令目前只支持加载本地模块(file:协议)不支持加载远程模块 加载优先级 脚本文件省略后缀名依次尝试加载四个后缀名文件(.mjs、.js、.json、node)以上不存在尝试加载package.json的main字段指定的脚本以上不存在依次尝试加载名称为index四个后缀名文件(.mjs、.js、.json、node)以上不存在报错 不存在的内部变量arguments、exports、module、require、this、__dirname、__filename CommonJS加载ESM 不能使用require()只能使用import() ESM加载CommonJS 自动将module.exports转化成export defaultCommonJS输出缓存机制在ESM加载方式下依然有效采用import命令加载CommonJS模块时不允许采用按需导入应使用默认导入或整体导入 循环加载 定义脚本A的执行依赖脚本B而脚本A的执行又依赖脚本B加载原理 CommonJSrequire()首次加载脚本就会执行整个脚本在内存里生成一个对象缓存下来二次加载脚本时直接从缓存中获取ESMimport命令加载变量不会被缓存而是成为一个指向被加载模块的引用 循环加载 CommonJS只输出已经执行的部分还未执行的部分不会输出ESM需开发者自己保证真正取值时能够取到值(可把变量写成函数形式函数具有提升作用) 重点难点 ES6模块中顶层this指向undefined不应该在顶层代码使用this一个模块就是一个独立的文件该文件内部的所有变量外部无法获取export命令输出的接口与其对应的值是动态绑定关系即通过该接口可获取模块内部实时的值import命令大括号里的变量名必须与被导入模块对外接口的名称相同import命令输入的变量只读(本质是输入接口)不允许在加载模块的脚本里改写接口import命令命令具有提升效果会提升到整个模块的头部首先执行重复执行同一句import语句只会执行一次export default命令只能使用一次export default命令导出的整体模块在执行import命令时其后不能跟大括号export default命令本质是输出一个名为default的变量后面不能跟变量声明语句export default命令本质是将后面的值赋给名为default的变量可直接将值写在其后export default命令和export {}命令可同时存在对应复合导入export命令和import命令可出现在模块任何位置只要处于模块顶层即可不能处于块级作用域import()加载模块成功后此模块会作为一个对象当作then()的参数可使用对象解构赋值来获取输出接口同时动态加载多个模块时可使用Promise.all()和import()相结合来实现import()和结合async/await来书写同步操作的代码 单例模式跨模块常量 // 常量跨文件共享 // person.js const NAME Bruce; const AGE 25; const SEX male; export { AGE, NAME, SEX };// file1.js import { AGE } from person; console.log(AGE);// file2.js import { AGE, NAME, SEX } from person; console.log(AGE, NAME, SEX);默认导入互换整体导入 import Person from person; console.log(Person.AGE);import * as Person from person; console.log(Person.default.AGE);Iterator 定义为各种不同的数据结构提供统一的访问机制原理创建一个指针指向首个成员按照次序使用next()指向下一个成员直接到结束位置(数据结构只要部署Iterator接口就可完成遍历操作)作用 为各种数据结构提供一个统一的简便的访问接口使得数据结构成员能够按某种次序排列ES6创造了新的遍历命令for-ofIterator接口主要供for-of消费 形式for-of(自动去寻找Iterator接口)数据结构 集合Array、Object、Set、Map原生具备接口的数据结构String、Array、Set、Map、TypedArray、Arguments、NodeList 部署默认部署在Symbol.iterator(具备此属性被认为可遍历的iterable)遍历器对象 next()下一步操作返回{ done, value }(必须部署)return()for-of提前退出调用返回{ done: true }throw()不使用配合Generator函数使用 ForOf循环 定义调用Iterator接口产生遍历器对象(for-of内部调用数据结构的Symbol.iterator()) 遍历字符串for-in获取索引for-of获取值(可识别32位UTF-16字符) 遍历数组for-in获取索引for-of获取值 遍历对象for-in获取键for-of需自行部署 遍历Setfor-of获取值 for (const v of set) 遍历Mapfor-of获取键值对 for (const [k, v] of map) 遍历类数组包含length的对象、Arguments对象、NodeList对象(无Iterator接口的类数组可用Array.from()转换) 计算生成数据结构Array、Set、Map keys()返回遍历器对象遍历所有的键values()返回遍历器对象遍历所有的值entries()返回遍历器对象遍历所有的键值对 与for-in区别 有着同for-in一样的简洁语法但没有for-in那些缺点、不同于forEach()它可与break、continue和return配合使用提供遍历所有数据结构的统一操作接口 应用场景 改写具有Iterator接口的数据结构的Symbol.iterator解构赋值对Set进行结构扩展运算符将部署Iterator接口的数据结构转为数组yield*yield*后跟一个可遍历的数据结构会调用其遍历器接口接受数组作为参数的函数for-of、Array.from()、new Set()、new WeakSet()、new Map()、new WeakMap()、Promise.all()、Promise.race() Promise 定义包含异步操作结果的对象 状态 进行中pending已成功resolved已失败rejected 特点 对象的状态不受外界影响一旦状态改变就不会再变任何时候都可得到这个结果 声明new Promise((resolve, reject) {}) 出参 resolve将状态从未完成变为成功在异步操作成功时调用并将异步操作的结果作为参数传递出去reject将状态从未完成变为失败在异步操作失败时调用并将异步操作的错误作为参数传递出去 方法 Promise实例原封不动地返回入参Thenable对象将此对象转为Promise对象并返回(Thenable为包含then()的对象执行then()相当于执行此对象的then())不具有then()的对象将此对象转为Promise对象并返回状态为resolved不带参数返回Promise对象状态为resolved入参具有Iterator接口的数据结构成功只有全部实例状态变成resolved最终状态才会变成resolved失败其中一个实例状态变成rejected最终状态就会变成rejected第一参数状态变为resolved时调用第二参数状态变为rejected时调用(可选)then()分别指定resolved状态和rejected状态的回调函数catch()指定发生错误时的回调函数Promise.all()将多个实例包装成一个新实例返回全部实例状态变更后的结果数组(齐变更再返回)Promise.race()将多个实例包装成一个新实例返回全部实例状态优先变更后的结果(先变更先返回)Promise.resolve()将对象转为Promise对象(等价于new Promise(resolve resolve()))Promise.reject()将对象转为状态为rejected的Promise对象(等价于new Promise((resolve, reject) reject())) 应用场景 加载图片AJAX转Promise对象 重点难点 只有异步操作的结果可决定当前状态是哪一种其他操作都无法改变这个状态状态改变只有两种可能从pending变为resolved、从pending变为rejected一旦新建Promise对象就会立即执行无法中途取消不设置回调函数内部抛错不会反应到外部当处于pending时无法得知目前进展到哪一个阶段实例状态变为resolved或rejected时会触发then()绑定的回调函数resolve()和reject()的执行总是晚于本轮循环的同步任务then()返回新实例其后可再调用另一个then()then()运行中抛出错误会被catch()捕获reject()的作用等同于抛出错误实例状态已变成resolved时再抛出错误是无效的不会被捕获等于没有抛出实例状态的错误具有冒泡性质会一直向后传递直到被捕获为止错误总是会被下一个catch()捕获不要在then()里定义rejected状态的回调函数(不使用其第二参数)建议使用catch()捕获错误不要使用then()第二个参数捕获没有使用catch()捕获错误实例抛错不会传递到外层代码即不会有任何反应作为参数的实例定义了catch()一旦被rejected并不会触发Promise.all()的catch()Promise.reject()的参数会原封不动地作为rejected的理由变成后续方法的参数 Generator 定义封装多个内部状态的异步编程解决方案 形式调用Generator函数(该函数不执行)返回指向内部状态的指针对象(不是运行结果) 声明function* Func() {} 方法 next()使指针移向下一个状态返回{ done, value }(入参会被当作上一个yield命令表达式的返回值)return()返回指定值且终结遍历Generator函数返回{ done: true, value: 入参 }throw()在Generator函数体外抛出错误在Generator函数体内捕获错误返回自定义的new Errow() yield命令声明内部状态的值(return声明结束返回的值) 遇到yield命令就暂停执行后面的操作并将其后表达式的值作为返回对象的value下次调用next()时再继续往下执行直到遇到下一个yield命令没有再遇到yield命令就一直运行到Generator函数结束直到遇到return语句为止并将其后表达式的值作为返回对象的valueGenerator函数没有return语句则返回对象的value为undefined yield*命令在一个Generator函数里执行另一个Generator函数(后随具有Iterator接口的数据结构) 遍历通过for-of自动调用next() 作为对象属性 全写const obj { method: function*() {} }简写const obj { * method() {} } 上下文执行产生的上下文环境一旦遇到yield命令就会暂时退出堆栈(但并不消失)所有变量和对象会冻结在当前状态等到对它执行next()时这个上下文环境又会重新加入调用栈冻结的变量和对象恢复执行 方法异同 相同点next()、throw()、return()本质上是同一件事作用都是让函数恢复执行且使用不同的语句替换yield命令不同点 next()将yield命令替换成一个值return()将yield命令替换成一个return语句throw()将yield命令替换成一个throw语句 应用场景 异步操作同步化表达控制流管理为对象部署Iterator接口把Generator函数赋值给对象的Symbol.iterator从而使该对象具有Iterator接口作为具有Iterator接口的数据结构 重点难点 每次调用next()指针就从函数头部或上次停下的位置开始执行直到遇到下一个yield命令或return语句为止函数内部可不用yield命令但会变成单纯的暂缓执行函数(还是需要next()触发)yield命令是暂停执行的标记next()是恢复执行的操作yield命令用在另一个表达式中必须放在圆括号里yield命令用作函数参数或放在赋值表达式的右边可不加圆括号yield命令本身没有返回值可认为是返回undefinedyield命令表达式为惰性求值等next()执行到此才求值函数调用后生成遍历器对象此对象的Symbol.iterator是此对象本身在函数运行的不同阶段通过next()从外部向内部注入不同的值从而调整函数行为首个next()用来启动遍历器对象后续才可传递参数想首次调用next()时就能输入值可在函数外面再包一层一旦next()返回对象的done为truefor-of遍历会中止且不包含该返回对象函数内部部署try-finally且正在执行try那么return()会导致立刻进入finally执行完finally以后整个函数才会结束函数内部没有部署try-catchthrow()抛错将被外部try-catch捕获throw()抛错要被内部捕获前提是必须至少执行过一次next()throw()被捕获以后会附带执行下一条yield命令函数还未开始执行这时throw()抛错只可能抛出在函数外部 首次next()可传值 function Wrapper(func) {return function(...args) {const generator func(...args);generator.next();return generator;} } const print Wrapper(function*() {console.log(First Input: ${yield});return done; }); print().next(hello);ES2016 数值扩展 指数运算符(**)数值求幂(相当于Math.pow()) 数组扩展 includes()是否存在指定成员 ES2017 声明 共享内存和原子操作由全局对象SharedArrayBuffer和Atomics实现将数据存储在一块共享内存空间中这些数据可在JS主线程和web-worker线程之间共享 字符串扩展 padStart()把指定字符串填充到字符串头部返回新字符串 padEnd()把指定字符串填充到字符串尾部返回新字符串 对象扩展 Object.getOwnPropertyDescriptors()返回对象所有自身属性(非继承属性)的描述对象 Object.values()返回以值组成的数组 Object.entries()返回以键和值组成的数组 函数扩展 函数参数尾逗号允许函数最后一个参数有尾逗号 Async 定义使异步函数以同步函数的形式书写(Generator函数语法糖) 原理将Generator函数和自动执行器spawn包装在一个函数里 形式将Generator函数的*替换成async将yield替换成await 声明 具名函数async function Func() {}函数表达式const func async function() {}箭头函数const func async() {}对象方法const obj { async func() {} }类方法class Cla { async Func() {} } await命令等待当前Promise对象状态变更完毕 正常情况后面是Promise对象则返回其结果否则返回对应的值后随Thenable对象将其等同于Promise对象返回其结果 错误处理将await命令Promise对象放到try-catch中(可放多个) Async对Generator改进 内置执行器更好的语义更广的适用性返回值是Promise对象 应用场景 按顺序完成异步操作 重点难点 Async函数返回Promise对象可使用then()添加回调函数内部return返回值会成为后续then()的出参内部抛出错误会导致返回的Promise对象变为rejected状态被catch()接收到返回的Promise对象必须等到内部所有await命令Promise对象执行完才会发生状态改变除非遇到return语句或抛出错误任何一个await命令Promise对象变为rejected状态整个Async函数都会中断执行希望即使前一个异步操作失败也不要中断后面的异步操作 将await命令Promise对象放到try-catch中await命令Promise对象跟一个catch() await命令Promise对象可能变为rejected状态最好把其放到try-catch中多个await命令Promise对象若不存在继发关系最好让它们同时触发await命令只能用在Async函数之中否则会报错数组使用forEach()执行async/await会失效可使用for-of和Promise.all()代替可保留运行堆栈函数上下文随着Async函数的执行而存在执行完成就消失 ES2018 字符串扩展 放松对标签模板里字符串转义的限制遇到不合法的字符串转义返回undefined并且从raw上可获取原字符串 对象扩展 扩展运算符(…)转换对象为用逗号分隔的参数序列({ ...obj }相当于rest/spread参数的逆运算) 扩展应用 克隆对象const obj { __proto__: Object.getPrototypeOf(obj1), ...obj1 }合并对象const obj { ...obj1, ...obj2 }转换字符串为对象{ ...hello }转换数组为对象{ ...[1, 2] }与对象解构赋值结合const { x, ...rest/spread } { x: 1, y: 2, z: 3 }(不能复制继承自原型对象的属性)修改现有对象部分属性const obj { x: 1, ...{ x: 2 } } 正则扩展 s修饰符dotAll模式修饰符使.匹配任意单个字符(dotAll模式) dotAll是否设置s修饰符 后行断言x只有在y后才匹配 后行否定断言x只有不在y后才匹配 Unicode属性转义匹配符合Unicode某种属性的所有字符 正向匹配\p{PropRule}反向匹配\P{PropRule}限制\p{...}和\P{...}只对Unicode字符有效使用时需加上u修饰符 具名组匹配为每组匹配指定名字(?GroupName) 声明const time 2017-09-11、const regexp /(?year\d{4})-(?month\d{2})-(?day\d{2})/u匹配time.replace(regexp, $day/$month/$year)形式str.exec().groups.GroupName解构赋值替换 Promise finally()指定不管最后状态如何都会执行的回调函数 Async 异步迭代器(for-wait-of)循环等待每个Promise对象变为resolved状态才进入下一步 ES2019 字符串扩展 直接输入U2028和U2029字符串可直接输入行分隔符和段分隔符 JSON.stringify()改造可返回不符合UTF-8标准的字符串 trimStart()消除字符串头部空格返回新字符串 trimEnd()消除字符串尾部空格返回新字符串 对象扩展 Object.fromEntries()返回以键和值组成的对象(Object.entries()的逆操作) 数组扩展 flat()扁平化数组返回新数组 flatMap()映射且扁平化数组返回新数组(只能展开一层数组) 函数扩展 toString()改造返回函数原始代码(与编码一致) catch()参数可省略catch()中的参数可省略 Symbol description返回Symbol值的描述 ES提案 声明 globalThis对象作为顶层对象指向全局环境下的this do表达式封装块级作用域的操作返回内部最后执行表达式的值(do{}) throw表达式直接使用throw new Error()无需()或{}包括 !#命令指定脚本执行器(写在文件首行) 数值扩展 数值分隔符(_)使用_作为千分位分隔符(增加数值的可读性) BigInt()创建任何位数的整数(新增的数据类型使用n结尾) 对象扩展 链判断操作符(?.)是否存在对象属性(不存在返回undefined且不再往下执行) 空判断操作符(??)是否值为undefined或null是则使用默认值 函数扩展 函数部分执行复用函数功能(?表示单个参数占位符...表示多个参数占位符) 管道操作符(|)把左边表达式的值传入右边的函数进行求值(f(x) x | f) 绑定运算符(:函数绑定(左边是对象右边是函数取代bind、apply、call调用) bindbar.bind(foo) foo::bar applybar.apply(foo, arguments) foo::bar(...arguments) Proxy Promise.try()不想区分是否同步异步函数包装函数为实例使用then()指定下一步流程使用catch()捕获错误 Realm 定义提供沙箱功能允许隔离代码防止被隔离的代码拿到全局对象声明new Realm().global Class 静态属性使用static定义属性该属性不会被实例继承只能通过类来调用 私有属性使用#定义属性该属性只能在类内部访问 私有方法使用#定义方法该方法只能在类内部访问 装饰器使用注释或修改类和类方法 Module import()动态导入(返回Primise) 背景import命令被JS引擎静态分析先于模块内的其他语句执行无法取代require()的动态加载功能提案建议引入import()来代替require()位置可在任何地方使用区别require()是同步加载import()是异步加载场景按需加载、条件加载、模块路径动态化 import.meta返回脚本元信息 Async 顶层Await允许在模块的顶层独立使用await命令(借用await解决模块异步加载的问题)
http://www.hkea.cn/news/14271073/

相关文章:

  • 怎样解析网站域名质量最好的购物平台
  • 产品类网站实创装饰官网
  • 宁波网站建设价格建筑工地招工
  • 加热器网站怎么做的wordpress边栏时间
  • 网站建设需要注册42类吗电商网站 收费与免费
  • 石家庄网站服务线上电商怎么做
  • .name后缀的网站龙岩app设计
  • 公司网站开发怎么收费wordpress mu模式
  • 男女做羞羞事试看网站hao123主页
  • 做队徽的网站做网站前端工资
  • phpstudy建设网站教程著名营销成功案例
  • 怎样做农村电商网站一个网站的预算
  • 赤峰建设局网站后期网站
  • 隆基泰和 做网站wordpress无法添加媒体
  • 河北中石化建设网站WordPress能连接支付端口吗
  • 装修平台自己做网站有几个sem是什么岗位
  • 大连有做途家网站吗湖南企业网站定制
  • 网站文章只被收录网站首页做个手机app软件需要多少钱
  • 南阳谁会做网站prozac
  • 江苏优化网站价格用手机做网站
  • 公司网站备案怎么做中国万网注册网站
  • html 学习网站网站关键词调整 收录
  • 网站建设中html代码做视频上传多少个网站
  • 如何查看网站建设的时间旅游网络营销论文
  • 如何查询网站使用什么框架做的做网站文字编辑好不好
  • 网站建设费汇算清缴做下载网站赚钱
  • 网站建设开票名称怎么写在线设计师平台
  • 网站找百度做可以嘛seo的理解
  • 济南建网站市场网络营销最好的方法
  • 旅游网站组织结构图怎么做wordpress 个人 主题