ES6新特性 ゝ一世哀愁。 2022-09-06 15:27 318阅读 0赞 ### 文章目录 ### * 一、ECMASript 介绍 * 二、ES6 新特性 * * 2.1 let、const 关键字 * 2.2 变量的解构赋值 * 2.3 模板字符串 * 2.4 对象简写写法 * 2.6 箭头函数 * 2.7 函数参数默认值 * 2.8 rest 参数 * 2.9 spread 扩展运算符 * 2.10 Symbol * 2.11 迭代器 * 2.12 生成器 generator 函数 * 2.13 Promise 的使用 * 2.14 Set * 2.15 Map * 2.16 class 类 * 2.17 数值扩展 * 2.18. 对象扩展 * 2.19. 模块化 # 一、ECMASript 介绍 # `ECMA`(`European Computer Manufacturers Association`)中文名称为欧洲计算机制造商协会,这个组织的目标是评估、开发和认可电信和计算机标准。1994年后该组织改名为`ECMA`国际。 `ECMAScript`是由`ECMA`国际通过 [ECMA-262 ][ECMA-262]标准化的脚本程序设计语言。 `ECMA-262`(`ECMAScript`) [历史版本查看网址][Link 1]: <table> <thead> <tr> <th>版本</th> <th>年份</th> <th>说明</th> </tr> </thead> <tbody> <tr> <td>第1版</td> <td>1997年</td> <td>制定了语言的基本语法</td> </tr> <tr> <td>第2版</td> <td>1998年</td> <td>较小改动</td> </tr> <tr> <td>第3版</td> <td>1999年</td> <td>引入正则、异常处理、格式化输出等。IE开始支持</td> </tr> <tr> <td>第4版</td> <td>2007年</td> <td>过于激进,未发布</td> </tr> <tr> <td>第5版</td> <td>2009年</td> <td>引入严格模式、JSON,扩展对象、数组、原型、字符串、日期方法</td> </tr> <tr> <td>第6版</td> <td>2015年</td> <td>模块化、面向对象语法、Promise、箭头函数、let、const、数组解构赋值等等</td> </tr> <tr> <td>第7版</td> <td>2016年</td> <td>幂运算符、数组扩展、Async/await关键字</td> </tr> <tr> <td>第8版</td> <td>2017年</td> <td>Async/await、字符串扩展</td> </tr> <tr> <td>第9版</td> <td>2018年</td> <td>对象解构赋值、正则扩展</td> </tr> <tr> <td>第10版</td> <td>2019年</td> <td>扩展对象、数组方法</td> </tr> <tr> <td>ES.next</td> <td>动态指向下一个版本</td> <td></td> </tr> </tbody> </table> **谁在维护`ECMA-262`?** `TC39`(`Technical Committee 39`)是推进`ECMAScript`发展的委员会。其会员都是公司(其中主要是浏览器厂商,有苹果、谷歌、微软、因特尔等)。`TC39`定期召开会议,会议由会员公司的代表与特邀专家出席 **`ES6`的好处:** * 版本变动内容最多,具有里程碑意义 * 加入许多新的语法特性,编程实现更简单、高效 * 前端发展趋势,就业必备技能 # 二、ES6 新特性 # ## 2.1 let、const 关键字 ## **① let 关键字** `let`关键字用来声明变量,使用`let`声明的变量有几个特点: * 不允许重复声明 * 块级作用域 * 不存在变量提升 * 不影响作用域链 应用场景:声明变量都使用`let` **② const 关键字** `const`关键字用来声明常量,`const`声明有以下特点: * 声明必须赋初始值 * 标识符一般为大写 * 不允许重复声明 * 值不允许修改 * 块儿级作用域 注意: 对象属性修改和数组元素变化不会触发`const`错误 应用场景:声明对象类型使用`const`,非对象类型声明选择`let` **③ var与let、const的区别** 1. `var`声明的变量均为全局变量,而`let`和`const`声明的变量均为局部变量 2. `var`声明变量存在变量提升,`let`和`const`不存在变量提升,即`var`定义的变量可以先使用后定义 3. 同一作用域下`let`和`const`不能声明同名变量,而`var`可以 4. 暂存死区 var a = 100; if(1){ a = 10;//就近原则 //在当前块作用域中存在a使用let/const声明的情况下,给a赋值10时,只会在当前作用域找变量a, //而这时,还未到声明时候,所以控制台Error:a is not defined let a = 1; } ## 2.2 变量的解构赋值 ## `ES6`允许按照一定模式,从数组和对象中提取值,对变量进行赋值,这被称为解构赋值。 注意:频繁使用对象方法、数组元素,就可以使用解构赋值形式。 /** * 数组 */ const city = ['Beijing', 'Shanghai', 'Guangzhou', 'Shenzhen'] let [bj, sh, gz, sz] = city //Beijing Shanghai Guangzhou Shenzhen console.log(bj + " " + sh + " " + gz + " " + sz) /** * 对象 */ const person = { name: 'jack', age: 21 } let { age } = person //21 console.log(age) ## 2.3 模板字符串 ## 模板字符串是增强版的字符串,用反引号(\`)标识,特点: * 字符串中可以出现换行符 * 可以使用`${xxx}`形式输出变量 注意:当遇到字符串与变量拼接的情况使用模板字符串。 let name = 'jack' //我的名字是jack console.log('我的名字是'+`${ name}`) name = 'rose' //我的名字是rose console.log('我的名字是'+`${ name}`) ## 2.4 对象简写写法 ## `ES6`允许在大括号里面,直接写入变量和函数,作为对象的属性和方法。这样的书写更加简洁。 const name ='jack' const eat = function(){ console.log('eat......') } const person = { name, eat, //方法的简写 sleep(){ console.log('sleep......') } } person.sleep() person.eat() ## 2.6 箭头函数 ## `ES6`允许使用箭头(`=>`)定义函数。箭头函数的注意点: * 如果形参只有一个,则小括号可以省略 * 函数体如果只有一条语句,则花括号可以省略,函数的返回值为该条语句的执行结果 * 箭头函数this指向声明时所在作用域下`this`的值 * 箭头函数不能作为构造函数实例化 * 不能使用`arguments` //1、箭头函数的使用 let add = (a, b) => { return a + b } console.log(add(1, 1))//2 //2、this 是静态的. this 始终指向函数声明时所在作用域下的 this 的值 function getName() { console.log(this.name) } const getName2 = () => { console.log(this.name) } window.name = '北京'; const city = { name: "Beijing", remark:"centre" } getName()//北京 getName2()//北京 getName.call(city);//Beijing getName2.call(city);//北京 //2. 不能作为构造实例化对象 // let Person = (name, age) => { // this.name = name; // this.age = age; // } // const me = new Person('xiao',30);//Person is not a constructor //3. 不能使用 arguments 变量 // let fn = () => { // console.log(arguments); // } // fn(1,2,3);//arguments is not defined > 箭头函数不会更改this指向,用来指定回调函数会非常合适 ## 2.7 函数参数默认值 ## //1、ES6允许给函数参数赋值初始值, 一般位置要靠后(潜规则) const add = (a, b, c = 10) => { return a + b + c } console.log(add(1,2,3))//6 console.log(add(1,2))//13 //2、与解构赋值结合 function connect({ host="127.0.0.1", username,password, port}){ console.log(host) console.log(username) console.log(password) console.log(port) } connect({ host: 'mysql.com', username: 'root', password: 'root', port: 3306 }) ## 2.8 rest 参数 ## `ES6`引入`rest`参数,用于获取函数的实参,用来代替`arguments`; 注意:`rest`参数非常适合不定个数参数函数的场景。 /** * 作用与 arguments 类似 */ function add(...args){ console.log(args); } add(1,2,3,4,5); /** * rest 参数必须是最后一个形参 */ function minus(a,b,...args){ console.log(a,b,args); } minus(100,1,2,3,4,5,19); ## 2.9 spread 扩展运算符 ## 扩展运算符(`spread`)也是三个点(…)。它好比`rest`参数的逆运算,将一个数组转为用逗号分隔的参数序列,对数组进行解包。 const heros = ['德莱厄斯', '德莱文'] function show() { console.log(arguments) } show(...heros) ///[Arguments] { '0': '德莱厄斯', '1': '德莱文' } const skillOne = { q: '致命打击' } const skillTwo = { w: '勇气' } const skillThree = { e: '审判' } const skillFour = { r: '德玛西亚正义' } const gailun = { ...skillOne, ...skillTwo, ...skillThree, ...skillFour } console.log(gailun) //{ q: '致命打击', w: '勇气', e: '审判', r: '德玛西亚正义' } ## 2.10 Symbol ## **① Symbol 基本使用** `ES6`引入了一种新的原始数据类型`Symbol`,表示独一无二的值。它是 `JavaScript`语言的第七种数据类型,是一种类似于字符串的数据类型。 `Symbol`特点: * `Symbol`的值是唯一的,用来解决命名冲突的问题 * `Symbol`值不能与其他数据进行运算 * `Symbol`定义的对象属性不能使用`for...in`循环遍历,但是可以使用 `Reflect.ownKeys`来获取对象的所有键名;使用 `Object.getOwnPropertySymbols`来获取对象的所有`Symbol`键名 注: 遇到唯一性的场景时要想到`Symbol` //1、Symbol的基本使用 let s1 = Symbol() console.log(s1, typeof s1)//Symbol() 'symbol' //2、添加标识的Symbol let s2 = Symbol('Beijing') let s3 = Symbol('Beijing') console.log(s2 == s3)//false //3、使用Symbol.for定义 let s4 = Symbol.for('Shanghai') let s5 = Symbol.for('Shanghai') console.log(s4 == s5)//true //4、不能与其他数据进行运算 let s6 = s2 + "city"//Cannot convert a Symbol value to a string **② Symbol创建对象属性** let person = { name:"Jack", //创建独一无二的Symbol属性方法 [Symbol('say')]: function(){ console.log("我可以说话") }, [Symbol('draw')]: function(){ console.log('我可以画画'); } } const symbolProperties = Object.getOwnPropertySymbols(person) person[symbolProperties[0]]()//我可以说话 const allProperties = Reflect.ownKeys(person) person[allProperties[2]]()//我可以画画 **③ Symbol内置值** 除了定义自己使用的`Symbol`值以外,`ES6`还提供了11个内置的`Symbol`值,指向语言内部使用的方法。可以称这些方法为魔术方法,因为它们会在特定的场景下自动执行。 <table> <thead> <tr> <th>值</th> <th>说明</th> </tr> </thead> <tbody> <tr> <td>Symbol.hasInstance</td> <td>当其他对象使用 instanceof 运算符,判断是否为该对象的实例时,会调用这个方法</td> </tr> <tr> <td>Symbol.isConcatSpreadable</td> <td>对象的 Symbol.isConcatSpreadable 属性等于的是一个布尔值,表示该对象用于Array.prototype.concat()时,是否可以展开。</td> </tr> <tr> <td>Symbol.species</td> <td>创建衍生对象时,会使用该属性</td> </tr> <tr> <td>Symbol.match</td> <td>当执行str.match(myObject) 时,如果该属性存在,会调用它,返回该方法的返回值</td> </tr> <tr> <td>Symbol.replace</td> <td>当该对象被str.replace(myObject)方法调用时,会返回该方法的返回值</td> </tr> <tr> <td>Symbol.search</td> <td>当该对象被str. search (myObject)方法调用时,会返回该方法的返回值</td> </tr> <tr> <td>Symbol.split</td> <td>当该对象被str. split (myObject)方法调用时,会返回该方法的返回值</td> </tr> <tr> <td>Symbol.iterator</td> <td>对象进行for…of循环时,会调用Symbol.iterator方法,返回该对象的默认遍历器</td> </tr> <tr> <td>Symbol.toPrimitive</td> <td>该对象被转为原始类型的值时,会调用这个方法,返回该对象对应的原始类型值</td> </tr> <tr> <td>Symbol. toStringTag</td> <td>在该对象上面调用 toString 方法时,返回该方法的返回值</td> </tr> <tr> <td>Symbol. unscopables</td> <td>该对象指定了使用with关键字时,哪些属性会被with环境排除</td> </tr> </tbody> </table> class Person{ static[Symbol.hasInstance](param){ console.log(param)//{ name: 'jack' } return true } } let o ={ name :'jack'} console.log(o instanceof Person)//true const arr = [1,2,3]; const arr2 = [4,5,6]; arr2[Symbol.isConcatSpreadable] = false; //[ 1,2,3,[ 4, 5, 6, [Symbol(Symbol.isConcatSpreadable)]: false ] ] console.log(arr.concat(arr2)); ## 2.11 迭代器 ## 遍历器(`Iterator`)就是一种机制。它是一种接口,为各种不同的数据结构提供统一的访问机制。任何数据结构只要部署`Iterator`接口,就可以完成遍历操作。 `ES6`创造了一种新的遍历命令`for...of`循环,`Iterator`接口主要供`for...of`消费。原生具备`iterator`接口的数据类型:`Array`、`Arguments`、`Set`、`Map`、`String`、`TypedArray`、`NodeList`。 工作原理: 1. 创建一个指针对象,指向当前数据结构的起始位置 2. 第一次调用对象的`next`方法,指针自动指向数据结构的第一个成员 3. 接下来不断调用`next`方法,指针一直往后移动,直到指向最后一个成员 4. 每调用`next`方法返回一个包含`value`和`done`属性的对象 //1、使用for...of遍历数组 const heros = ['盖伦','拉克丝','赵信'] for (let hero of heros) { console.log(hero) } //2、使用iterator const itr = heros[Symbol.iterator]() console.log(itr.next())//{ value: '盖伦', done: false } console.log(itr.next())//{ value: '拉克丝', done: false } console.log(itr.next())//{ value: '赵信', done: false } console.log(itr.next())//{ value: undefined, done: true } ## 2.12 生成器 generator 函数 ## 生成器函数是`ES6`提供的一种异步编程解决方案,语法行为与传统函数完全不同。说明: * `*`的位置没有限制 * 生成器函数返回的结果是迭代器对象,调用迭代器对象的`next`方法可以得到`yield`语句后的值 * `yield`相当于函数的暂停标记,也可以认为是函数的分隔符,每调用一次`next`方法,执行一段代码 * `next`方法可以传递实参,作为`yield`语句的返回值 /** * generator生成器函数的使用 */ function* gen() { yield 'a' yield 'b' yield 'c' } let itr = gen() for (let v of itr) { console.log(v) // a b c } /** * 带参数的生成器函数 */ function* gen2(arg) { console.log("arg=" + arg)// arg=a let r1 = yield 111 console.log("arg=" + r1)// arg=b let r2 = yield 222 console.log("arg=" + r2)// arg=c let r3 = yield 333 console.log("arg=" + r3)// arg=d } let itr2 = gen2('a') console.log(itr2.next())// { value: 111, done: false } console.log(itr2.next('b'))// { value: 222, done: false } console.log(itr2.next('c'))// { value: 333, done: false } console.log(itr2.next('d'))// { value: undefined, done: true } `generator`函数的作用: 1. `generator`可以在执行过程中多次返回变量状态的函数 2. 把异步回调代码变成同步代码,使代码变得有层次感,不需要大量的嵌套 **① 生成器函数实际应用-解决回调地狱** //原方法 setTimeout(() => { setTimeout(() => { setTimeout(() => { }, 1000); }, 1000); }, 1000); //使用generator函数 function func() { setTimeout(() => { iterator.next(); }, 1000) } function* gen4() { yield func() yield func() yield func() } const iterator = gen4() iterator.next() **② 生成器函数实际应用-顺序调用方法** //模拟获取用户数据、订单数据、商品数据 function execute(data) { setTimeout(()=>{ itr5.next(data); }, 1000); } function * gen5(args){ let users = yield execute('用户数据'); console.log(users)//用户数据 let orders = yield execute('订单数据'); console.log(orders)//订单数据 let goods = yield execute('商品数据'); console.log(goods)//商品数据 } let itr5 = gen5(); itr5.next(); ## 2.13 Promise 的使用 ## 详细见[ Promise 的使用][Promise] ## 2.14 Set ## `ES6`提供了新的数据结构`Set`(集合)。它类似于数组,但成员的值都是唯一的,集合实现了`iterator`接口,所以可以使用扩展运算符和`or...of...`进行遍历,集合的属性和方法: * `size`:返回集合的元素个数 * `add`:增加一个新元素,返回当前集合 * `delete`:删除元素,返回`boolean`值 * `has`:检测集合中是否包含某个元素,返回`boolean`值 * `clear`:清空集合,返回`undefined` //创建一个空集合 let s = new Set() //创建一个非空集合 let s1 = new Set([1, 1, 2, 2, 3, 3, 4]) console.log(s1)//Set { 1, 2, 3, 4 } console.log(s1.size)//4 console.log(s1.delete(1))//true console.log(s1)//Set { 2, 3, 4 } console.log(s1.has(2))//true s1.clear() console.log(s1)//Set {} ## 2.15 Map ## `ES6`提供了`Map`数据结构。它类似于对象,也是键值对的集合。但是键的范围不限于字符串,各种类型的值(包括对象)都可以当作键。`Map`也实现了`iterator`接口,所以可以使用扩展运算符和`for...of...`进行遍历。`Map`的属 性和方法: * `size`:返回`Map`的元素个数 * `set`:增加一个新元素,返回当前`Map` * `get`:返回键名对象的键值 * `has`:检测`Map`中是否包含某个元素,返回`boolean`值 * `clear`:清空集合,返回`undefined` //创建一个空map let m = new Map() //创建一个非空map let m1 = new Map([['name','jack'],['age',18]]) console.log(m1)//Map { 'name' => 'jack', 'age' => 18 } console.log(m1.size)//2 m1.set('age',20) console.log(m1)//Map { 'name' => 'jack', 'age' => 20 } console.log(m1.has('name'))//true m1.clear() console.log(m1)//Map {} ## 2.16 class 类 ## `ES6`提供了更接近传统语言的写法,引入了`Class`(类)这个概念,作为对象的模板。通过`class`关键字,可以定义类。基本上,`ES6`的class可以看作只是一个语法糖,它的绝大部分功能,`ES5`都可以做到,新的`class`写法只是让对象原型的写法更加清晰、更像面向对象编程的语法而已。知识点: * `class`声明类 * `constructor`定义构造函数初始化 * `extends`继承父类 * `super`调用父级构造方法 * `static`定义静态方法和属性 * 父类方法可以重写 //父类 class Phone { //构造方法 constructor(brand, color, price) { this.brand = brand; this.color = color; this.price = price; } //对象方法 call() { console.log('我可以打电话!!!') } } //子类 class SmartPhone extends Phone { constructor(brand, color, price, size) { super(brand, color, price) this.size = size } //子类方法 photo() { console.log('我可以拍照!!!') } //重写父类方法 call() { console.log('我可以打视频电话!!!') } static playGame(){ console.log('我可以打游戏!!!') } } //实例化对象 const Nokia = new Phone('诺基亚', '灰色', 230) const iPhone12 = new SmartPhone('苹果', '白色', 5488, '6.2inch') iPhone12.photo()//调用重写方法 iPhone12.call()//调用重写方法 SmartPhone.playGame()//调用静态方法 ## 2.17 数值扩展 ## //1、Number.EPSILON 是 JavaScript 表示的最小精度,接近于 2.2204460492503130808472633361816E-16 function equal(a, b) { if (Math.abs(a - b) < Number.EPSILON) { return true } else { return false } } console.log(0.1 + 0.2 == 0.3)//false console.log(equal(0.1 + 0.2, 0.3))//true //2、0b二进制、0o八进制、0x十六进制 console.log(0b1010)//10 console.log(0o777)//511 console.log(100)//100 console.log(0xff)//255 //3、Number.isFinite 检测一个数值是否为有限数 console.log(Number.isFinite(100))//true console.log(Number.isFinite(100/0))//false console.log(Number.isFinite(Infinity))//false //4、Number.isNaN 检测一个数值是否为 NaN console.log(Number.isNaN(123)) //false //5. Number.parseInt Number.parseFloat字符串转整数 console.log(Number.parseInt('5211314love'))//5211314 console.log(Number.parseFloat('3.1415926神奇'))//3.1415926 //6. Number.isInteger 判断一个数是否为整数 console.log(Number.isInteger(5))//true console.log(Number.isInteger(2.5))//false //7. Math.trunc 将数字的小数部分抹掉 console.log(Math.trunc(3.5))//3 //8. Math.sign 判断一个数到底为正数 负数 还是零 console.log(Math.sign(100))//1 console.log(Math.sign(0))//0 console.log(Math.sign(-20000))//-1 ## 2.18. 对象扩展 ## `ES6`新增了一些`Object`对象的方法 * `Object.is`:比较两个值是否严格相等,与`===`行为基本一致(包括 `NaN`) * `Object.assign`:对象的合并,将源对象的所有可枚举属性,复制到目标对象 * `__proto__`、`setPrototypeOf`: `setPrototypeOf`:可以直接设置对象的原型 //1、Object.is 判断两个值是否完全相等 console.log(1 === 1) //true console.log(Object.is(NaN, NaN)) //true console.log(NaN === NaN) //false //2、Object.assign 对象的合并 const config1 = { host: 'localhost', port: 3306, custom1: '1' } const config2 = { host: '127.0.0.1', port: 3307, custom2: '2' } console.log(Object.assign(config1, config2)) //3. Object.setPrototypeOf 设置原型对象 Object.getPrototypeof const school = { name: 'Peking' } const cities = { location: ['北京','上海','深圳'] } Object.setPrototypeOf(school, cities) console.log(Object.getPrototypeOf(school))//{ location: [ '北京', '上海', '深圳' ] } console.log(school)//{ name: 'Peking' } ## 2.19. 模块化 ## 详细见[ ES6 模块化][ES6] [ECMA-262]: https://www.ecma-international.org/publications/standards/Standard.htm [Link 1]: https://www.ecma-international.org/publications-and-standards/standards/ [Promise]: https://blog.csdn.net/qq_38697437/article/details/119817348 [ES6]: https://hucheng.blog.csdn.net/article/details/119886466
相关 ES6新特性 ES6, 全称 ECMAScript 6.0 ,是 JavaScript 的下⼀个版本标准,2015.06 发版。ES6 主要是为了解决 ES5 的先天不⾜,⽐如 Jav... 矫情吗;*/ 2024年04月21日 08:03/ 0 赞/ 112 阅读
相关 ES6新特性 文章目录 一、ECMASript 介绍 二、ES6 新特性 2.1 let、const 关键字 2.2 变量的解构赋值 ゝ一世哀愁。/ 2022年09月06日 15:27/ 0 赞/ 319 阅读
相关 ES5&ES6新特性 ES5和6的一些新特性 1、let和const var有一个问题,就是定义的变量有时会莫名奇妙的成为全局变量。 for(var i = 0; i < 淡淡的烟草味﹌/ 2022年04月11日 12:13/ 0 赞/ 371 阅读
相关 es6新特性 1.let && const •都是块级作用域 •不能重复定义 •避免了变量提升 ① let命令也用于声明对象,但是作用域为局部。 ![在这里插入图片描述][ 红太狼/ 2022年03月07日 21:24/ 0 赞/ 406 阅读
相关 es6新特性 es6语法 > es6语法用起来是十分方便的,但是有些浏览器还是不支持,但是做大型项目中基本上要用到转码器(babel转码器),可以把es6语法转为es5直接使用。 T 落日映苍穹つ/ 2022年01月25日 15:30/ 0 赞/ 409 阅读
相关 ES6新特性 转:[https://www.jianshu.com/p/87008f4f8513][https_www.jianshu.com_p_87008f4f8513] co Bertha 。/ 2022年01月12日 02:19/ 0 赞/ 388 阅读
相关 ES6新特性 转自:[https://www.jianshu.com/p/87008f4f8513][https_www.jianshu.com_p_87008f4f8513] 1.con 冷不防/ 2021年12月18日 07:07/ 0 赞/ 383 阅读
相关 es6新特性 https://www.cnblogs.com/minghui007/p/8177925.html 转载于:https://www.cnblogs.com/LWWTT/p/1 野性酷女/ 2021年11月02日 14:58/ 0 赞/ 552 阅读
相关 ES6新特性 1.变量声明let和const 在ES6以前,var关键字声明变量。无论声明在何处,都会被视为声明在函数的最顶部(不在函数内即在全局作用域的最顶部)。这就是函数变量提升例如: 我会带着你远行/ 2021年10月29日 07:08/ 0 赞/ 561 阅读
相关 ES6新特性 1.声明变量的关键字:const 和 let JavaScript ES6中引入了另外两个声明变量的关键字:const和let。在ES6中,我们将很少能看到var了。 co 电玩女神/ 2021年09月17日 01:12/ 0 赞/ 550 阅读
还没有评论,来说两句吧...