网站首页 > 技术文章 正文
ECMAScript 6使用教程
前言:
ECMAScript 6.0(以下简称 ES6)是 JavaScript 语言的下一代标准,已经在 2015 年 6 月正式发布了。它的目标,是使得 JavaScript 语言可以用来编写复杂的大型应用程序,成为企业级开发语言。
? 正式名称就是《ECMAScript 2015 标准》(简称 ES2015)。2016 年 6 月,小幅修订的《ECMAScript 2016 标准》(简称 ES2016)如期发布,这个版本可以看作是 ES6.1 版,因为两者的差异非常小(只新增了数组实例的includes方法和指数运算符),基本上是同一个标准。根据计划,2017 年 6 月发布 ES2017 标准。
注意:各大浏览器的最新版本,对 ES6 的支持可以查看kangax.github.io/compat-table/es6/。随着时间的推移,支持度已经越来越高了,超过 90%的 ES6 语法特性都实现了。 但是生产环境依然需要考虑兼容问题,毕竟IE 系列浏览器版本更新慢。
? Babel](https://babeljs.io/) 是一个广泛使用的 ES6 转码器,可以将 ES6 代码转为 ES5 代码,从而在现有环境执行。这意味着,你可以用 ES6 的方式编写程序,又不用担心现有环境是否支持。
在ES5 也设定严格模式,用于改良部分不合理和怪异现象: 在js代码开头前 添加: 'use strict';
一、let 与 const
ES6中新增 let 声明变量,与原来的var 类似 ,通过const 声明常量(声明时赋值)。
###1.不存在变量提升brbr###2.不允许重复定义变量brbr###3.块级作用域
二、字符串扩展
- 新增方法includes():返回布尔值,表示是否找到了参数字符串。 brlet s = 'Hello world!';brbrs.startsWith('Hello') // truebrs.endsWith('!') // truebrs.includes('o') // truebr=================这三个方法都支持第二个参数,表示开始搜索的位置。=================brs.startsWith('world', 6) // truebrs.endsWith('Hello', 5) // truebrs.includes('Hello', 6) // falserepeat() :返回一个新字符串,表示将原字符串重复n次。 br'x'.repeat(3) // "xxx"br'hello'.repeat(2) // "hellohello"br'na'.repeat(0) // ""padStart(),padEnd() :ES2017 引入了字符串补全长度的功能。如果某个字符串不够指定长度,会在头部或尾部补全。padStart()用于头部补全,padEnd()用于尾部补全。 br'x'.padStart(5, 'ab') // 'ababx'br'x'.padStart(4, 'ab') // 'abax'brbr'x'.padEnd(5, 'ab') // 'xabab'br'x'.padEnd(4, 'ab') // 'xaba'brbr#####如果原字符串的长度,等于或大于最大长度,则字符串补全不生效,返回原字符串。
- 字符串模板: 用于解决,变量与字符串拼接的繁琐操作问题。 br// 字符串中嵌入变量brlet name = "Bob", time = "today";br`Hello ${name}, how are you ${time}?`
三、变量的解构赋值:
#ES6 允许按照一定模式,从数组和对象中提取值,对变量进行赋值,这被称为解构(Destructuring)。
brlet [a, b, c] = [1, 2, 3];br可以从数组中提取值,按照对应位置,对变量赋值:br a = 1; br b = 2;br c = 3;
本质上,这种写法属于“模式匹配”,只要等号两边的模式相同,左边的变量就会被赋予对应的值。下面是一些使用嵌套数组进行解构的例子。
brlet [foo, [[bar], baz]] = [1, [[2], 3]];brfoo // 1brbar // 2brbaz // 3brbrlet [ , , third] = ["foo", "bar", "baz"];brthird // "baz"brbrlet [x, , y] = [1, 2, 3];brx // 1bry // 3brbrlet [head, ...tail] = [1, 2, 3, 4];brhead // 1brtail // [2, 3, 4]brbrlet [x, y, ...z] = ['a'];brx // "a"bry // undefinedbrz // []
另一种情况是不完全解构,即等号左边的模式,只匹配一部分的等号右边的数组。这种情况下,解构依然可以成功。
brlet [x, y] = [1, 2, 3];brx // 1bry // 2brbrlet [a, [b], d] = [1, [2, 3], 4];bra // 1brb // 2brd // 4
对象结构赋值:
对象的解构与数组有一个重要的不同。数组的元素是按次序排列的,变量的取值由它的位置决定;而对象的属性没有次序,变量必须与属性同名,才能取到正确的值。
brlet { foo, bar } = { foo: "aaa", bar: "bbb" };brfoo // "aaa"brbar // "bbb"
如果变量名与属性名不一致,必须写成下面这样。
brlet { foo: baz } = { foo: 'aaa', bar: 'bbb' };brbaz // "aaa"brbrlet obj = { first: 'hello', last: 'world' };brlet { first: f, last: l } = obj;brf // 'hello'brl // 'world'
对象的解构赋值的内部机制,是先找到同名属性,然后再赋给对应的变量。真正被赋值的是后者,而不是前者。
brlet { foo: baz } = { foo: "aaa", bar: "bbb" };brbaz // "aaa"brfoo // error: foo is not defined
函数的参数也可以使用解构赋值
brfunction add([x, y]){br return x + y;br}brbradd([1, 2]); // 3
实际使用 :提取 JSON 数据
brlet jsonData = {br id: 42,br status: "OK",br data: [867, 5309]br};brbrlet { id, status, data: number } = jsonData;brbrconsole.log(id, status, number);br// 42, "OK", [867, 5309]
四、数组扩展
- 扩展运算符 (...) ,对象中也可以使用。 brconsole.log(...[1, 2, 3])br// 1 2 3brbrconsole.log(1, ...[2, 3, 4], 5)br// 1 2 3 4 5brbr可以替代apply 的使用:brMath.min.apply([3,43,5,76,7,5]); //es5做法brbrMath.min(...[3,43,5,76,7,5]);//es6做法brbr=====================解构赋值中使用=======================brconst [first, ...rest] = [1, 2, 3, 4, 5];brfirst // 1brrest // [2, 3, 4, 5]brbrconst [first, ...rest] = [];brfirst // undefinedbrrest // []brbrconst [first, ...rest] = ["foo"];brfirst // "foo"brrest // []brbr=====================字符串展开运算符==========================br[...'hello']br// [ "h", "e", "l", "l", "o" ] brbr=========================数组合并=============================brlet arr = [1,2,3,4];brlet arr2 = ['a','b','c'];brlet arr3 = [...arr,...arr2]; // = > [1,2,3,4,'a','b','c']
- Array.from 方法用于将两类对象转为真正的数组
brlet arrayLike = {br '0': 'a',br '1': 'b',br '2': 'c',br length: 3br};brbr// ES5的写法brvar arr1 = [].slice.call(arrayLike); // ['a', 'b', 'c']brbr// ES6的写法brlet arr2 = Array.from(arrayLike); // ['a', 'b', 'c']
- Array.of方法用于将一组值,转换为数组。 brArray.of(3, 11, 8) // [3,11,8]brArray.of(3) // [3]brArray.of(3).length // 1
- fill() 填充数组 br['a', 'b', 'c'].fill(7)br// [7, 7, 7]brbrnew Array(3).fill(7)br// [7, 7, 7]brbr####fill方法用于空数组的初始化非常方便。数组中已有的元素,会被全部抹去。
- entries(),keys()和values() 遍历 brfor (let index of ['a', 'b'].keys()) {br console.log(index);br}br// 0br// 1brbrfor (let elem of ['a', 'b'].values()) {br console.log(elem);br}br// 'a'br// 'b'brbrfor (let [index, elem] of ['a', 'b'].entries()) {br console.log(index, elem);br}br// 0 "a"br// 1 "b"
- includes() 方法返回一个布尔值,表示某个数组是否包含给定的值 br[1, 2, 3].includes(2) // truebr[1, 2, 3].includes(4) // falsebr[1, 2, NaN].includes(NaN) // true
- for of 循环 br1. for…of循环可以代替数组实例的forEach方法,不同于forEach方法,它可以与break、continue和return配合使用。brbr2. for…in循环主要是为遍历对象而设计的,不适用于遍历数组。 brbr3. JavaScript 原有的for…in循环,只能获得对象的键名,不能直接获取键值。ES6 提供for…of循环,允许遍历获得键值。
五、函数扩展
1.ES6 允许为函数的参数设置默认值,即直接写在参数定义的后面。
brfunction log(x, y = 'World') {br console.log(x, y);br}brbrlog('Hello') // Hello Worldbrlog('Hello', 'China') // Hello Chinabrlog('Hello', '') // Hello
2.参数变量是默认声明的,所以不能用let或const再次声明。
brfunction foo(x = 5) {br let x = 1; // errorbr const x = 2; // errorbr}
3.reset 参数
brfunction add(...values) {br let sum = 0;brbr for (var val of values) {br sum += val;br }brbr return sum;br}brbradd(2, 5, 3) // 10
4.箭头函数
brvar f = v => v;brbr// 等同于brvar f = function (v) {br return v;br};brbr======================如果箭头函数不需要参数或需要多个参数,就使用一个圆括号代表参数部分。brvar f = () => 5;br// 等同于brvar f = function () { return 5 };brbrvar sum = (num1, num2) => num1 + num2;br// 等同于brvar sum = function(num1, num2) {br return num1 + num2;br};brbr=======如果箭头函数的代码块部分多于一条语句,就要使用大括号将它们括起来,并且使用return语句返回。brvar sum = (num1, num2) => { return num1 + num2; }brbr================================箭头函数中,锁定this 指向问题==============================br var obj = {br interval:function(){br setInterval(function(){br console.log(this) // 默认指向window 对象br })br }br } br br //es6 箭头函数br var obj = {br interval:function(){br setInterval(()=>{br console.log(this) //obj对象br })br }br }
5.双冒号运算符
br箭头函数可以绑定this对象,大大减少了显式绑定this对象的写法(call、apply、bind)。但是,箭头函数并不适用于所有场合,所以现在有一个提案,提出了“函数绑定”(function bind)运算符,用来取代call、apply、bind调用。brbr函数绑定运算符是并排的两个冒号(::),双冒号左边是一个对象,右边是一个函数。该运算符会自动将左边的对象,作为上下文环境(即this对象),绑定到右边的函数上面。br========================================================================brfoo::bar;br// 等同于brbar.bind(foo);brbrfoo::bar(...arguments);br// 等同于brbar.apply(foo, arguments);
六、对象扩展
1.简化对象写法
brconst foo = 'bar';brconst baz = {foo};brbaz // {foo: "bar"}brbr// 等同于brconst baz = {foo: foo};brbr================================================brlet birth = '2000/01/01';brbrconst Person = {brbr name: '张三',brbr //等同于birth: birthbr birth,brbr // 等同于hello: function ()...br hello() { console.log('我的名字是', this.name); }brbr};
2.解构赋值 与 展开运算符
brlet { x, y, ...z } = { x: 1, y: 2, a: 3, b: 4 };brx // 1bry // 2brz // { a: 3, b: 4 }brbr=======================================================brlet z = { a: 3, b: 4 };brlet n = { ...z };brn // { a: 3, b: 4 }
3.Object.is 比较两个值是否严格相等,与严格比较运算符(===)的行为基本一致。
brObject.is('foo', 'foo')br// truebrObject.is({}, {})br// false
4.Object.assign 用于对象的合并,将源对象(source)的所有可枚举属性,复制到目标对象(target)。
brconst target = { a: 1 };brbrconst source1 = { b: 2 };brconst source2 = { c: 3 };brbrObject.assign(target, source1, source2);brtarget // {a:1, b:2, c:3}brbr#Object.assign方法的第一个参数是目标对象,后面的参数都是源对象。
5.新增设置,读取原型对象的方法,此处不展开说明,请自行了解。
七、Set 与 Map 数据结构
1.ES6 提供了新的数据结构 Set。它类似于数组,但是成员的值都是唯一的,没有重复的值。(简单说就是可用于去重)
br// 例一brconst set = new Set([1, 2, 3, 4, 4]);br[...set]br// [1, 2, 3, 4]brbr// 例二brconst items = new Set([1, 2, 3, 4, 5, 5, 5, 5]);britems.size // 5
Map它类似于对象,也是键值对的集合,但是“键”的范围不限于字符串,各种类型的值(包括对象)都可以当作键。也就是说,Object 结构提供了“字符串—值”的对应,Map 结构提供了“值—值”的对应,是一种更完善的 Hash 结构实现。
br#键值对,键可以是对象。brconst map1 = new Map()brconst objkey = {p1: 'v1'}brbrmap1.set(objkey, 'hello')brconsole.log(map1.get(objkey))brbr==========================================brbrconst map = new Map([br ['name', '张三'],br ['title', 'Author']br]);brbrmap.size // 2brmap.has('name') // truebrmap.get('name') // "张三"brmap.has('title') // truebrmap.get('title') // "Author"
八、Promise 异步对象
Promise(承诺) 是异步编程的一种解决方案,比传统的解决方案——回调函数和事件——更合理和更强大。 Promise对象代表一个异步操作,有三种状态:pending(进行中)、fulfilled(已成功)和rejected(已失 败),简单说就是一个容器,里面保存着某个未来才会结束的事件(通常是一个异步操作)的结果。
br###基本用法brconst promise = new Promise(function(resolve, reject) {br // ... some codebrbr if (/* 异步操作成功 */){br resolve(value);br } else {br reject(error);br }br});brbrpromise.then(function(value) {br // successbr}, function(error) {br // failurebr});brbr=================================================================================br#下面是异步加载图片的例子。brfunction loadImageAsync(url) {br return new Promise(function(resolve, reject) {br const image = new Image();brbr image.onload = function() {br resolve(image);br };brbr image.onerror = function() {br reject(new Error('Could not load image at ' + url));br };brbr image.src = url;br });br}brbr##这样做,避免回调函数多层嵌套之间的杂乱结构。br=======================================================================br###以下为封装一个ajax代码实例brconst getJSON = function(url) {br const promise = new Promise(function(resolve, reject){br const handler = function() {br if (this.readyState !== 4) {br return;br }br if (this.status === 200) {br resolve(this.response);br } else {br reject(new Error(this.statusText));br }br };br const client = new XMLHttpRequest();br client.open("GET", url);br client.onreadystatechange = handler;br client.responseType = "json";br client.setRequestHeader("Accept", "application/json");br client.send();brbr });brbr return promise;br};brbrgetJSON("/posts.json").then(function(json) {br console.log('Contents: ' + json);br}, function(error) {br console.error('出错了', error);br});
Promise.all() 多个异步操作 ,都执行完成
Promise.race() race(竞速) ,只要有谁先执行完成,即算为完成。
九、Generator 生成器
Generator 函数是 ES6 提供的一种异步编程解决方案,语法行为与传统函数完全不同。
brfunction* helloWorldGenerator() {br yield 'hello';br yield 'world';br return 'ending';br}brbrvar hw = helloWorldGenerator();brbr###next() 方法执行一次 ,运行一次 (踹一脚,走一步)brhw.next()br// { value: 'hello', done: false }brbrhw.next()br// { value: 'world', done: false }brbrhw.next()br// { value: 'ending', done: true }brbrhw.next()br// { value: undefined, done: true }
异步操作 : async 、 await
十、面向对象
###### 1.新增类的概念
brclass Point {br constructor(x, y) {br this.x = x;br this.y = y;br }brbr toString() {br return '(' + this.x + ', ' + this.y + ')';br }br}
2.extends 实现类的继承 : 在子类中调用父类构造,实现继承,注意必须在构造器中使用super()
brclass ColorPoint extends Point {br constructor(x, y, color) {br super(x, y); // 调用父类的constructor(x, y)br this.color = color;br }brbr toString() {br return this.color + ' ' + super.toString(); // 调用父类的toString()br }br}
3.constructor 构造器函数(初始化对象)
十一、模块化开发
目的: 为了解决js中将大程序拆分若干个小文件,通过一定的方式引入项目。(例如:css 样式中,我们可以通过@import 导入外部的css文件)
1.导入 import
import { stat, exists, readFile } from 'fs';
import customName from './export-default';
2.导出模块 export
export var firstName = 'Michael';
export var lastName = 'Jackson';
export var year = 1958;
3.export default 默认导出
import customName from './export-default';
customName(); // 'foo'
猜你喜欢
- 2024-11-21 浅析GIF 格式图片的存储与解析
- 2024-11-21 如何用2 KB代码实现3D赛车游戏?2kPlus Jam大赛了解一下
- 2024-11-21 快速了解ES6的代理与反射
- 2024-11-21 「实战」蘑菇街 PC 端首页,瀑布流布局的实现原理与细节技巧
- 2024-11-21 Knative 驾驭篇:带你 '纵横驰骋' Knative 自动扩缩容实现
- 2024-11-21 一道二进制子串算法,让面试官都解不出来?
- 2024-11-21 高级前端进阶,为什么要使用call、apply、bind?
- 2024-11-21 碎片时间学编程「202]:分组数组元素
- 2024-11-21 从入门到入土:Lambda完整学习指南,包教包会(上)
- 2024-11-21 碎片时间学编程「58]:取消组合数组元素
- 标签列表
-
- content-disposition (47)
- nth-child (56)
- math.pow (44)
- 原型和原型链 (63)
- canvas mdn (36)
- css @media (49)
- promise mdn (39)
- readasdataurl (52)
- if-modified-since (49)
- css ::after (50)
- border-image-slice (40)
- flex mdn (37)
- .join (41)
- function.apply (60)
- input type number (64)
- weakmap (62)
- js arguments (45)
- js delete方法 (61)
- blob type (44)
- math.max.apply (51)
- js (44)
- firefox 3 (47)
- cssbox-sizing (52)
- js删除 (49)
- js for continue (56)
- 最新留言
-