ES6 详解二: 新增内容概览

ES6 新增内容概览

相比对ES5 不痛不痒的几个改动,ES6新增了大量的内容。这里先简单罗列一下,后续会一个一个仔细解释。

打开ES6支持

chrome 已经支持了很多es6的特性,不过被关闭了,你可以在这里打开 chrome://flags/#enable-javascript-harmony。改完之后记得重启浏览器生效。

这可以查看主流浏览器和自己当前浏览器的兼容性 https://kangax.github.io/compat-table/es6/

编译ES6

有些特性即使打开了chrome的配置,依然不支持,比如 class。这个时候可以用 babel 来把 es6 的代码编译成 es5。它支持绝大部分的特性。

而且查看编译后的代码很容易理解这些特性。

地址:https://github.com/babel/grunt-babel

arrow function

可以用箭头语法来写函数了,很像 lambda 表达式,并且arrow function 会自动绑定this为当前上下文。
目前最新版的 chrome 43 竟然还是不支持,不过最新的火狐已经支持了,可以在火狐下实验。

[1,2,3,4].map(d=>d*d); //单行
//也可以写多行
[1,2,3,4].map(d=>{
    console.log(this);
    return d*d
});

class

现在原生支持 class 关键字来声明一个类了,虽然只是一个语法糖,最终还是基于原型继承实现的。但是毕竟可以很方便的实现创建和继承一个类了。

class People {
    constructor(name) {
        this.name = name;
    }

    sayName() {
        console.log(sayName);
    }
}

增强对象字面量

从上面的类定义可以看出,对象字面量语法做了增强,可以这样写了:

var people = {
      name: "Tom",
      sayName() {    //更方便定义函数
        console.log(this.name);
      },
      [ 'prop_' + (() => 42)() ]: 42    //甚至可以计算属性名
}

字符串模板

还记得在JS中痛苦的拼接html模板么,现在终于有语法支持了,并且用反引号支持多行字符串哦。

var people = {name: "Tom", age: 12};
var html = `
  • name: ${people.name}
  • age: ${people.age}
`;

destructuring

这个应该翻译成析构吗。不是很好解释,看下面的代码就很明白。简单的说,就是可以用一个对象来给一个对象的每一个属性赋值(或者数组)。

var [a,b,c]=[1,2,3];    //通过数组给多个变量赋值
var {name, age} = {name: "Tom", age:12} //通过一个对象来给多个变量赋值

//用对象来定义参数
function g({name: x}) {
    console.log(x);
}
g({name: 5})

函数默认变量和延展属性

现在可以在函数声明的时候指定一个默认值,还有react中奇怪的三个点号就是这里的延展属性

function say(name="Tom") {
    return name;
}

function a(x, ...y) {//延展属性
  console.log(x,y)
}
a(1,2,3,4);

let & const

可以通过 let 和 const 来声明块级作用于的变量(通过 var 声明的是函数级作用域)。而且 const 声明的是不可变变量。

{
    let x=1;
    console.log(x);
}
console.log(x);
const y=2;

Iterators + For..Of

Iterator 用来实现一个可以用 for 关键字遍历的对象:

let students = {
  [Symbol.iterator]() {
    let current = 1;
    return {
      next() {
        return {done: current > 100, value: current++};
        }
    }
  }
}

for(s of students) {
  console.log(s);
}
//输出 0 - 100

yield

JS终于支持大名顶顶的 yield 了,就是在一个函数内部可以返回多次 return 一个变量。如果用 yield 来实现上面的代码,应该是这样的

let students = {
  [Symbol.iterator]: function*() {
    for(var i=0;i<=100;i++) {
      yield i;
    }
  }
}

for(var s of students) {
  console.log(s);
}

unicode

原生支持 unicode,暂时不是很了解这个。

modules

这个必须有!对模块的语法级支持。

export function sum(x, y) {
  return x + y;
}

import sum from "math"
sum(1,2);

Map + Set + WeakMap + WeakSet

map 和 set 是一种数据结构,没什么好讲的。 WeakMap 和 WeakSet 用来防止内存泄露,后面有详细讲解。

#map
var m = new Map();
m.set("a", 1);
m.get("a")

#set
var s = new Set();
s.add("a");
s.add("b");
s.add("a"); //不变,因为 a 已经存在了

proxy

这里的proxy和 jQuery.proxy 可是两码事,不是用来绑定this的。它和 java 的annotation,python 的 decorator 类似。就是它可以代理一个对象的所有行为,比如你取一个对象的属性,正常是直接取,但是加了 proxy之后,“取”的这个操作会先传个proxy,他来决定到底怎么取。

var target = {};
var handler = {
    get: function (receiver, name) {
        return `Hello, ${name}!`;
    }
};

var p = new Proxy(target, handler);
p.world === 'Hello, world!';

当然他不止可以代理 get,还有 set, has 等一堆操作可以被代理。

Symbol

Sybmol 用来创建唯一不可变字符串,后面有详细讲解。

继承内置类

现在内置的 Array, Date 和 Element 都可以被继承了

新增的 Math + Number + String + Array + Object APIs

这些是以前就有的类型,不过这次增加了一大推新的API:

"abcd".include("bc");

promise

大家很熟悉的 promise, 现在原生支持了.

反射

估计类似java的反射,可以通过反射机制去操作运行时的对象。

尾递归调用优化

如果不知道什么是尾递归,可以参考这里 http://www.zhihu.com/question/20761771

ES6规定了解释器必须对尾递归进行优化,无论你的尾递归有多少次调用再也不会造成栈溢出了。

function factorial(n, acc = 1) {
    'use strict';
    if (n <= 1) return acc;
    return factorial(n - 1, n * acc);
}

factorial(100000)

上面这个是计算阶乘的,现在在任何浏览器中运行都会造成栈溢出。

后面针对几个重点逐个解析。

这里主要参考这篇文章:
- https://github.com/lukehoban/es6features

你可能感兴趣的:(es6详解)