ES6(2015)-Es10(2019)的总结


ECMAScript是一种由Ecma国际(前身为欧洲计算机制造商协会)在标准ECMA-262中定义的脚本语言规范。

Es6

Let与Const

ES6 新增了let命令,用来声明变量。它的用法类似于var,但是所声明的变量,只在let命令所在的代码块内有效。

let

{
  let a = 10;
  var b = 1;
}

a // ReferenceError: a is not defined.
b // 1

const

const就是constant的缩写,用于声明一个只读的常量。一旦声明,常量的值就不能改变,即不可变量。const定义常量的原理是阻隔变量名所对应的内存地址被改变。


const PI = 3.1415;
PI // 3.1415

PI = 3;
// TypeError: Assignment to constant variable.

ES6 引入了class(类),让JavaScript的面向对象编程变得更加简单和易于理解。

function Point(x, y) {
  this.x = x;
  this.y = y;
}

Point.prototype.toString = function () {
  return '(' + this.x + ', ' + this.y + ')';
};

var p = new Point(1, 2);

ES6 的class可以看作只是一个语法糖,上面的代码用 ES6 的class改写,就是下面这样。

class Point {
  constructor(x, y) {
    this.x = x;
    this.y = y;
  }

  toString() {
    return '(' + this.x + ', ' + this.y + ')';
  }
}

模块化

ECMAScript包含了以往模块加载库的主要功能,还添加了一些非常使用的设计,以提高ECMAScript的模块化管理功能。

(1)引入模块(import)

ES Module中有很多种引入模块的方法,最基本的便是import语句。

import name form 'module-name'
import * as name from 'module-name'
import {member} from 'module-name'
import {meber as alias} from 'module-name'
import 'module-name'

从模块中局部引用的接口定义一个别名,以避免指代不明或接口重名的情况出现。

import {createServer as createHTTPServer} from 'http'
import {createServer as createHTTPSServer} from 'https'

(2)暴露模块(export)

暴露单一接口
如果需要定义一个项目内的工具集模块,需要将其中定义的函数或者对象暴露到该文件所定义的模块上。


//module.js
export const apiRoot='http://example.com/api'
export function method(){
    //...
}
export class foo{
    //...
}

//app.js
import {method,foo} from 'module.js'

暴露模块默认接口
在某些时候,一个模块只需要暴露一个接口,比如需要使用模块机制定义一个只含有一个单一工具类的模块时,就没有必要让这个工具类成为该模块的一部分,而是让这个类成为这个模块。


//client.js
export default class Client{
   //...
}
//app.js
import Client from 'client.js'

混合使用暴露接口语句
开发者可以为一个模块同时定义默认接口和其它命名接口。

//module.js
export default class  Client{
    //...
}
export const foo='bar'

//app.js
import Client,{foo} from 'module'

延展操作符(…)

扩展运算符(spread)是三个点(…)。它好比 rest 参数的逆运算,将一个数组转为用逗号分隔的参数序列。

//例子1
function sum(x, y, z) {
  return x + y + z;
}
const numbers = [1, 2, 3];

//不使用延展操作符
console.log(sum.apply(null, numbers));//通过 apply() 方法,您能够编写用于不同对象的方法。

//使用延展操作符
console.log(sum(...numbers));// 6



//例子2:构造数组
const stuendts = ['Jine','Tom']; 
const persons = ['Tony',... stuendts,'Aaron','Anna'];
conslog.log(persions)// ["Tony", "Jine", "Tom", "Aaron", "Anna"]


//例子3:数组拷贝
var arr = [1, 2, 3];
var arr2 = [...arr]; // 等同于 arr.slice()
arr2.push(4); 
console.log(arr2)//[1, 2, 3, 4]

//例子4:连接多个数组

var arr1 = [0, 1, 2];
var arr2 = [3, 4, 5];
var arr3 = [...arr1, ...arr2];// 将 arr2 中所有元素附加到 arr1 后面并返回
//等同于
var arr4 = arr1.concat(arr2);


//例子4:对象的扩展

var obj1 = { foo: 'bar', x: 42 };
var obj2 = { foo: 'baz', y: 13 };

var clonedObj = { ...obj1 };
// 克隆后的对象: { foo: "bar", x: 42 }

var mergedObj = { ...obj1, ...obj2 };
// 合并后的对象: { foo: "baz", x: 42, y: 13 }

箭头函数(=>)

箭头函数,顾名思义便是使用箭头(=>)进行定义的函数,属于匿名函数(Anonymous Function)一类。
相对于传统的function语句,箭头函数在简单函数使用中更为简洁直观。

var sum = (num1, num2) => { return num1 + num2; }
//等同于
var sum = function(num1, num2) {
    return num1 + num2;
};

函数参数默认值

ES6支持在定义函数的时候为其设置默认值:

function foo(height = 50, color = 'red')
{
    // ...
}

不使用默认值:

function foo(height, color)
{
    var height = height || 50;
    var color = color || 'red';
    //...
}
```js



## 模板字符串

当我们使用普通的字符串时,会使用单引号或双引号来包裹字符串的内容,在ES2015的模板字符串中使用反勾号````js
var name = 'Your name is ' + first + ' ' + last + '.'
//使用模板字符串:
var name = `Your name is ${first} ${last}.`

在ES6中通过${}就可以完成字符串的拼接,只需要将变量放在大括号之中。

解构赋值

解构赋值语法是JavaScript的一种表达式,可以方便的从数组或者对象中快速提取值赋给定义的变量。

获取数组中的值

从数组中获取值并赋值到变量中,变量的顺序与数组中对象顺序对应。

//例1
let a = 1;
let b = 2;
let c = 3;

//ES6 允许写成下面这样。
let [a, b, c] = [1, 2, 3];


//例2
let [foo, [[bar], baz]] = [1, [[2], 3]];
foo // 1
bar // 2
baz // 3

//例3:如果你要忽略某些值,你可以按照下面的写法获取你想要的值
var [first, , , last] = foo;
console.log(first); // "one"
console.log(last); // "four"

//例4
let [x, , y] = [1, 2, 3];
x // 1
y // 3

//例5:

let [head, ...tail] = [1, 2, 3, 4];
head // 1
tail // [2, 3, 4]

//例6
let [x, y, ...z] = ['a'];
x // "a"
y // undefined
z // []

如果解构不成功,变量的值就等于undefined。

let [foo] = [];
let [bar, foo] = [1];

不完全解构

let [x, y] = [1, 2, 3];
x // 1
y // 2

let [a, [b], d] = [1, [2, 3], 4];
a // 1
b // 2
d // 4

如果没有从数组中的获取到值,你可以为变量设置一个默认值。


var a, b;

[a=5, b=7] = [1];
console.log(a); // 1
console.log(b); // 7

通过解构赋值可以方便的交换两个变量的值。


var a = 1;
var b = 3;

[a, b] = [b, a];
console.log(a); // 3
console.log(b); // 1

获取对象中的值

解构不仅可以用于数组,还可以用于对象。

//例子1
let { foo, bar } = { foo: 'aaa', bar: 'bbb' };
foo // "aaa"
bar // "bbb"

//例子2
const student = {
  name:'Ming',
  age:'18',
  city:'Shanghai'  
};

const {name,age,city} = student;
console.log(name); // "Ming"
console.log(age); // "18"
console.log(city); // "Shanghai"

对象属性简写

在ES6中允许我们在设置一个对象的属性的时候不指定属性名。

不使用ES6


const name='Ming',age='18',city='Shanghai';

const student = {
    name:name,
    age:age,
    city:city
};
console.log(student);//{name: "Ming", age: "18", city: "Shanghai"}


//使用ES6
const name='Ming',age='18',city='Shanghai';

const student = {name,age,city};

console.log(student);//{name: "Ming", age: "18", city: "Shanghai"}

Promise

Promise意在让异步代码变得干净和直观,让异步代码变得井然有序。
Promise在设计上具有原子性,即只有三种状态:等待(Pending)、成功(Fulfilled)、失败(Rejected)。在调用支持Promise的异步方法时,逻辑变得非常简单,在大规模的软件工程开发中具有良好的健壮性。

下面代码创造了一个Promise实例。

const promise = new Promise(function(resolve, reject) {
  // ... some code

  if (/* 异步操作成功 */){
    resolve(value);
  } else {
    reject(error);
  }
});

Promise构造函数接受一个函数作为参数,该函数的两个参数分别是resolve和reject。它们是两个函数,由 JavaScript 引擎提供,不用自己部署。

resolve函数的作用是,将Promise对象的状态从“未完成”变为“成功”(即从 pending 变为 resolved),在异步操作成功时调用,并将异步操作的结果,作为参数传递出去;reject函数的作用是,将Promise对象的状态从“未完成”变为“失败”(即从 pending 变为 rejected),在异步操作失败时调用,并将异步操作报出的错误,作为参数传递出去。

下面是一个Promise对象的简单例子。

function timeout(ms) {
  return new Promise((resolve, reject) => {
    setTimeout(resolve, ms, 'done');
  });
}
timeout(100).then((value) => {
  console.log(value);
});

上面代码中,timeout方法返回一个Promise实例,表示一段时间以后才会发生的结果。过了指定的时间(ms参数)以后,Promise实例的状态变为resolved,就会触发then方法绑定的回调函数。

Es7

求幂运算符(**)

在 ES7 中引入指数运算符 ** ,用来实现幂运算,功能与 Math.pow 相同,这个运算符是简化版的 Math.pow(x, y)。

5**2 //25
3**2 //9

注意任何数字,包括 NaN,它的0次幂都是1。如果指数是NaN,结果总是NaN,无论底数是什么。

9**0   //1
99**NaN  //NaN 

Array.prototype.includes()方法

includes()作用,是查找一个值在不在数组里,若是存在则返回true,不存在返回false.

1.基本用法:

['a', 'b', 'c'].includes('a')     // true
['a', 'b', 'c'].includes('d')     // false

2.接收俩个参数:要搜索的值和搜索的开始索引

['a', 'b', 'c', 'd'].includes('b')         // true
['a', 'b', 'c', 'd'].includes('b', 1)      // true
['a', 'b', 'c', 'd'].includes('b', 2)      // false

fromIndex 参数值也可以为负数,那样从倒数第N个位置开始搜索指定的值。

[‘a’, ‘b’, ‘c’, ‘d’].includes(‘b’,-2) // false
[‘a’, ‘b’, ‘c’, ‘d’].includes(‘c’, -2) // true

Es8

async/await

Object.values()

Object.values()方法返回一个给定对象中所有可枚举属性值的数组,值的顺序与使用

const person = { name: 'Fred', age: 87 }
Object.values(person) // ['Fred', 87]

返回数组的成员顺序,与属性的遍历部分介绍的排列规则一致

const obj = {100 : "a", 2 : "b", 7 : "c"};
console.log(Object.values(obj));   //["b", "c", "a"]

属性名为数值的属性,是按照数值大小,从小到大遍历的,因此返回的顺序是b、c、a。

Object.values() 也适用于数组


const people = ['Fred', 'Tony']
Object.values(people) // ['Fred', 'Tony']

Object.entries()

Object.entries方法返回一个数组,成员是参数对象自身的(不含继承的)所有可遍历(enumerable)属性的键值对数组

传入对象

var obj = { foo: 'bar', baz: 42 };
console.log(Object.entries(obj));

传入数组

const arr = [1, 2, 3]; 
console.log(Object.entries(arr));  // [['0', 1], ['1', '2'], ['2', '3']]

传入json数组

const arr = [1, 2, 3]; 
console.log(Object.entries(arr));  // [['0', 1], ['1', '2'], ['2', '3']]

传入对象

var obj = { foo: 'bar', baz: 42 };
console.log(Object.entries(obj));

传入对象

var obj = { foo: 'bar', baz: 42 };
console.log(Object.entries(obj));

字符串填充(padStart 和 padEnd)

字符串填充的目的是 向字符串添加字符,使字符串达到指定的长度。ES2017引入了两个 String 方法:padStart() 和 padEnd() 。

padStart()用于头部补全,padEnd()用于尾部补全。


'a'.padStart(4,"bc")  //结果:bcba
'a'.padEnd(4,"bc")  //结果:abcb

如果本身长度超过补全长度,则不变化

'aaa'.padStart(2,"bc")  //结果:aaa
'aaa'.padEnd(2,"bc")  //结果:aaa

如果不填写第二个补全内容参数,默认用空格补全

'a'.padStart(2)  //结果:' a'
'a'.padEnd(2)  //结果:'a '

函数参数列表结尾允许逗号

Object.getOwnPropertyDescriptors()

ShareArrayBuffer和Atomics对象,用于从共享内存位置读取和写入


文章作者: BiLiang
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 BiLiang !
评论
  目录