ES6

ES6的特性比较多,在这里列举几个常用的:

类class

熟悉java等面向对象语言的开发者肯定都十分了解class,对于ES6来说,class就是个语法糖,只是让对象原型的写法变得更加简单和易于理解,我这里就不展开了。

模块化Module

模块的功能主要由export和import组成,每个模块都有自己单独的作用域,模块之间的相互调用关系是通过export来规定模块对外暴露的接口,通过import来引用其他模块提供的接口,同时还为模块创造了命名空间,防止函数的命名冲突。

导出变量:export var name='xxx'

导出常量:export const age='xx'

导出多个变量:export {name,age}

导出函数:export function

导入:import {xxx} from 'xxx'

块级作用域

使用var定义的变量为函数级作用域

使用let和const定义的变量为块级作用域

模板字符串

模板字符串使得字符串的拼接更加的简洁、直观

用反引号包裹字符串,变量放在${}中

//不使用模板字符串
var name='your name is'+first+'.'

//使用模板字符串
var name=`your name is ${first}.`

 

Promise

promise是异步编程的一种解决方案,比传统的回调函数和事件更加合理和强大。简单来说,promise是一个容器,里面保存了一个在未来才会结束的事件,这种“承诺将来会实现的对象”在JavaScript中被称为promise对象。

promise对象有三个状态:pending(进行中)、fulfilled(resolved已成功)和rejected(已失败)

基本用法:

创建一个promise实例

const promise = new Promise(function(resolve, reject) {
  // Promise构造函数接受一个函数作为参数,该函数的两个参数分别是resolvereject。它们是两个函数,由 JavaScript 引擎提供,不用自己部署。

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

Promise实例生成以后,可以用then方法分别指定resolved状态和rejected状态的回调函数。

promise.then(function(value) {
  // success
}, function(error) {
  // failure
});

then方法可以接受两个回调函数作为参数。第一个回调函数是Promise对象的状态变为resolved时调用,第二个回调函数是Promise对象的状态变为rejected时调用。其中,第二个函数是可选的,不一定要提供。这两个函数都接受Promise对象传出的值作为参数。

 

再看下面这个例子,这个test()函数有两个参数,这两个参数都是函数,如果执行成功,我们将调用resolve('200 OK'),如果执行失败,我们将调用reject('timeout in ' + timeOut + ' seconds.')。可以看出,test()函数只关心自身的逻辑,并不关心具体的resolvereject将如何处理结果。

function test(resolve, reject) {
    var timeOut = Math.random() * 2;
    log('set timeout to: ' + timeOut + ' seconds.');
    setTimeout(function () {
        if (timeOut < 1) {
            log('call resolve()...');
            resolve('200 OK');
        }
        else {
            log('call reject()...');
            reject('timeout in ' + timeOut + ' seconds.');
        }
    }, timeOut * 1000);
}
new Promise(test).then(function (result) {
    console.log('成功:' + result);
}).catch(function (reason) {
    console.log('失败:' + reason);
});

可见Promise最大的好处是在异步执行的流程中,把执行代码和处理结果的代码清晰地分离了

Async/await

ES2018引入异步迭代器,await可以和for ...of循环一起使用,以串行的方式运行异步操作

async函数返回一个 Promise 对象,可以使用then方法添加回调函数。当函数执行的时候,一旦遇到await就会先返回,等到异步操作完成,再接着执行函数体内后面的语句。即async函数必须等到内部所有的 await 命令的Promise对象执行完,才会发生状态改变。

await 放置在Promise调用之前,await 强制后面点代码等待,直到Promise对象resolve,得到resolve的值作为await表达式的运算结果

await只能在async函数内部使用,用在普通函数里就会报错

下面是一个例子:

async function getStockPriceByName(name) {
  const symbol = await getStockSymbol(name);
  const stockPrice = await getStockPrice(symbol);
  return stockPrice;
}

getStockPriceByName('goog').then(function (result) {
  console.log(result);
});

上面代码是一个获取股票报价的函数,函数前面的async关键字,表明该函数内部有异步操作。调用该函数时,会立即返回一个Promise对象。

proxy

Proxy 可以理解成,在目标对象之前架设一层“拦截”,外界对该对象的访问,都必须先通过这层拦截,因此提供了一种机制,可以对外界的访问进行过滤和改写。Proxy 这个词的原意是代理,用在这里表示由它来“代理”某些操作,可以译为“代理器”。

ES6 原生提供 Proxy 构造函数,用来生成 Proxy 实例。new Proxy()表示生成一个Proxy实例,target参数表示所要拦截的目标对象,handler参数也是一个对象,用来定制拦截行为。

var proxy = new Proxy(target, handler);

 Proxy 支持的拦截操作一共 13 种,戳这里~

只要是proxy对象的方法,就能在reflect对象上找到对应的方法。

reflect:

  • 可以拿到语言内部的方法(如Object.defineProperty)
  • 修改某些Object方法的返回结果,让其变得更合理
  • 让Obect操作都变成函数行为,而非命令式

Iterator和for...of

 任何数据结构只要部署 Iterator 接口,就可以完成遍历操作(即依次处理该数据结构的所有成员)

作用有三个:一是为各种数据结构,提供一个统一的、简便的访问接口;二是使得数据结构的成员能够按某种次序排列;三是 ES6 创造了一种新的遍历命令for...of循环,Iterator 接口主要供for...of消费。

原生具备 Iterator 接口的数据结构如下。

  • Array
  • Map
  • Set
  • String
  • TypedArray
  • 函数的 arguments 对象
  • NodeList 对象

Generator

Generator函数两个特征:

  • 关键字function和函数名之间有一个星号
  • 函数体内部使用yield表达式,定义不同的内部状态

由于 Generator 函数返回的遍历器对象,只有调用next方法才会遍历下一个内部状态,所以其实提供了一种可以暂停执行的函数。yield表达式就是暂停标志。

遍历器对象的next方法的运行逻辑如下。

(1)遇到yield表达式,就暂停执行后面的操作,并将紧跟在yield后面的那个表达式的值,作为返回的对象的value属性值。

(2)下一次调用next方法时,再继续往下执行,直到遇到下一个yield表达式。

(3)如果没有再遇到新的yield表达式,就一直运行到函数结束,直到return语句为止,并将return语句后面的表达式的值,作为返回的对象的value属性值。

(4)如果该函数没有return语句,则返回的对象的value属性值为undefined

async函数就是将 Generator 函数的星号(*)替换成async,将yield替换成await,是Generator函数的语法糖

箭头函数

 =>不只是关键字function的简写,它还带来了其他好处,箭头函数与包围它的代码共享同一个this,有经验的JavaScript开发者都熟悉诸如var self=this或var that=this这种引用外围this的模式,但借助=>就不需要这种模式了

//无参数,返回1
()=>1
//有参数x,返回x+1
x=>x+1
//有两个参数,返回a+b
(a,b)=>a+b
//箭头后面是用花括号括起的函数体,需要自行通过return来返回值
()=>{
    alert("foo");
        }
    

扩展操作符...

扩展运算符可以在函数调用/数组构造时,将数组表达式或者string在语法层面展开,还可以在构造对象时,将对象表达式按key-value的方式展开等等,接下来我来介绍一些常见的用法:

对象的扩展运算符:用于取出参数对象中的所有可遍历属性,拷贝到当前对象之中

let bar = { a: 1, b: 2 };
let baz = { ...bar }; // { a: 1, b: 2 }
//等价于Object.assign({}, bar)

数组的扩展运算符:

可以将数组转化为参数数列

function add(x, y) {
  return x + y;
}

const numbers = [4, 38];
add(...numbers) // 42

可以复制数组:

const arr1 = [1, 2];
const arr2 = [...arr1];

可以与解构赋值结合起来,用于生成数组:

const [first, ...rest] = [1, 2, 3, 4, 5];
first // 1
rest  // [2, 3, 4, 5]
//如果将扩展运算符用于数组赋值,只能放在参数的最后一位,否则会报错。

可以将字符串转为数组:

[...'hello']
// [ "h", "e", "l", "l", "o" ]

我们都知道阮一峰老师写了本es6入门的书,详细学习去那里啦~

 

posted @ 2019-10-13 14:08  KWskrrrr  阅读(106)  评论(0编辑  收藏  举报