编程技术文章分享与教程

网站首页 > 技术文章 正文

ECMAScript 6使用教程总结

hmc789 2024-11-21 15:55:08 技术文章 1 ℃

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.块级作用域

二、字符串扩展

  1. 新增方法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#####如果原字符串的长度,等于或大于最大长度,则字符串补全不生效,返回原字符串。
  2. 字符串模板: 用于解决,变量与字符串拼接的繁琐操作问题。 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]




四、数组扩展

  1. 扩展运算符 (...) ,对象中也可以使用。 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']
  2. 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']
  1. Array.of方法用于将一组值,转换为数组。 brArray.of(3, 11, 8) // [3,11,8]brArray.of(3) // [3]brArray.of(3).length // 1
  2. fill() 填充数组 br['a', 'b', 'c'].fill(7)br// [7, 7, 7]brbrnew Array(3).fill(7)br// [7, 7, 7]brbr####fill方法用于空数组的初始化非常方便。数组中已有的元素,会被全部抹去。
  3. 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"
  4. includes() 方法返回一个布尔值,表示某个数组是否包含给定的值 br[1, 2, 3].includes(2) // truebr[1, 2, 3].includes(4) // falsebr[1, 2, NaN].includes(NaN) // true
  5. 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'
标签列表
最新留言