每天一点ES6(二)

来源:互联网 发布:购物网站数据库表设计 编辑:程序博客网 时间:2024/06/06 19:29

箭头函数(Arrow Functions)

// ES5var t= values.reduce(function (a, b) {  return a + b;}, 0);// ES6var t= values.reduce((a, b) => a + b, 0);

一个箭头函数表达式的语法比一个函数表达式更短,并且不绑定自己的 thisargumentssuper或 new.target

不绑定 this

在箭头函数出现之前,每个新定义的函数都有其自己的 this 值(例如,构造函数的 this 指向了一个新的对象;严格模式下的函数的 this 值为 undefined;如果函数是作为对象的方法被调用的,则其 this 指向了那个调用它的对象)。在面向对象风格的编程中,这会带来很多困扰。

function Person() {    // 构造函数 Person() 定义的 `this` 就是新实例对象自己    this.age = 0;    setInterval(function growUp() {        // 在非严格模式下,growUp() 函数定义了其内部的 `this`为全局对象,         // 不同于构造函数Person()的定义的 `this`        this.age++;    }, 3000);}var p = new Person();

在 ECMAScript 3/5 中,这个问题通过把this的值赋给变量,然后将该变量放到闭包中来解决。

function Person() {    var self = this;     // 也有人选择使用 `that` 而非 `self`, 只要保证一致就好.    self.age = 0;    setInterval(function growUp() {        // 回调里面的 `self` 变量就指向了期望的那个对象了        self.age++;    }, 3000);}var p = new Person();

除此之外,还可以使用 bind 函数,把期望的 this 值传递给 growUp() 函数。

箭头函数会捕获其所在上下文的  this 值,作为自己的 this 值,因此下面的代码将如期运行。

function Person() {      this.age = 0;      setInterval(() => {        // 回调里面的 `this` 变量就指向了期望的那个对象了        this.age++;    }, 3000);}var p = new Person();
destructuring是解构的意思,ES6允许按照一定模式,从数组和对象中提取值,对变量进行赋值,这被称为解构(Destructuring)


let [foo, [[bar], baz]] = [1, [[2], 3]];foo // 1bar // 2baz // 3let [ , , third] = ["foo", "bar", "baz"];third // "baz"let [x, , y] = [1, 2, 3];x // 1y // 3let [head, ...tail] = [1, 2, 3, 4];head // 1tail // [2, 3, 4]let [x, y, ...z] = ['a'];x // "a"y // undefinedz // []

let [x, y] = [1, 2, 3];x // 1y // 2let [a, [b], d] = [1, [2, 3], 4];a // 1b // 2d // 4
默认值

let [foo = true] = [];foo // truelet [x, y = 'b'] = ['a']; // x='a', y='b'let [x, y = 'b'] = ['a', undefined]; // x='a', y='b'
let [x = 1, y = x] = [];     // x=1; y=1let [x = 1, y = x] = [2];    // x=2; y=2let [x = 1, y = x] = [1, 2]; // x=1; y=2let [x = y, y = 1] = [];     // ReferenceError
对象解构赋值

let { bar, foo } = { foo: "aaa", bar: "bbb" };foo // "aaa"bar // "bbb"let { baz } = { foo: "aaa", bar: "bbb" };baz 
let { foo: baz } = { foo: "aaa", bar: "bbb" };baz // "aaa"foo // error: foo is not defined

字符串的解构赋值

const [a, b, c, d, e] = 'hello';a // "h"b // "e"c // "l"d // "l"e // "o"



用途

(1)交换变量的值

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

(2)从函数返回多个值

函数只能返回一个值,如果要返回多个值,只能将它们放在数组或对象里返回。有了解构赋值,取出这些值就非常方便。

// 返回一个数组function example() {  return [1, 2, 3];}let [a, b, c] = example();// 返回一个对象function example() {  return {    foo: 1,    bar: 2  };}let { foo, bar } = example();

(3)函数参数的定义

解构赋值可以方便地将一组参数与变量名对应起来。

// 参数是一组有次序的值function f([x, y, z]) { ... }f([1, 2, 3]);// 参数是一组无次序的值function f({x, y, z}) { ... }f({z: 3, y: 2, x: 1});

(4)提取JSON数据

解构赋值对提取JSON对象中的数据,尤其有用。

let jsonData = {  id: 42,  status: "OK",  data: [867, 5309]};let { id, status, data: number } = jsonData;console.log(id, status, number);// 42, "OK", [867, 5309]

上面代码可以快速提取 JSON 数据的值。

(5)函数参数的默认值

jQuery.ajax = function (url, {  async = true,  beforeSend = function () {},  cache = true,  complete = function () {},  crossDomain = false,  global = true,  // ... more config}) {  // ... do stuff};

指定参数的默认值,就避免了在函数体内部再写var foo = config.foo || 'default foo';这样的语句。

(6)遍历Map结构

任何部署了Iterator接口的对象,都可以用for...of循环遍历。Map结构原生支持Iterator接口,配合变量的解构赋值,获取键名和键值就非常方便。

var map = new Map();map.set('first', 'hello');map.set('second', 'world');for (let [key, value] of map) {  console.log(key + " is " + value);}// first is hello// second is world

如果只想获取键名,或者只想获取键值,可以写成下面这样。

// 获取键名for (let [key] of map) {  // ...}// 获取键值for (let [,value] of map) {  // ...}

(7)输入模块的指定方法

加载模块时,往往需要指定输入哪些方法。解构赋值使得输入语句非常清晰。

const { SourceMapConsumer, SourceNode } = require("source-map");