快速了解ES6

ECMAScript6(简称ES6),是JavaScript的下一代标准,由于ES6是在2015年发布的,因此又称ECMAScript2015(ES6 === ECMAScript2015)html

目前不是全部的浏览器都彻底兼容ES6,但不少程序猿已经开始使用ES6了,因此了解并逐步掌握ES6,甚至在你的项目中使用ES6,是很是有必要的,至少也要看得懂小伙伴写的ES6代码吧?编程

在说ES6以前,咱们先来了解下Babel,这是个什么鬼?它是一个普遍使用的ES6转码器,能够将咱们写的ES6代码转换成能在当前全部浏览器中执行的ES5代码。你能够在你习惯使用的工具中集成Babel,方便它来工做,具体使用请查看Babel官网(http://babeljs.io)数组

下面咱们来看下最经常使用的一些ES6特性:浏览器

  • let,const
  • class,extends,super
  • arrow functions
  • template string
  • destructuring
  • default
  • rest arguments

let,const

let是用来声明变量的,与var类似,const是定义常量的。咱们先来看下面的例子缓存

while (true) {
    var name = 'obama';
    console.log(name);        //obama
    break;
}

console.log(name);            //obama

在ES5中只有全局做用域和函数做用域,没有块级做用域,因此上面的代码中,while循环体内的name变量覆盖了上面声明的全局name变量,最后输出的就是被覆盖的变量值。而let为JavaScript增长了块级做用域,用它声明的变量只在当前的代码块内有效。babel

let name = 'zach';
while (true) {
    let name = 'obama';
    console.log(name);            //obama
    break;
}

console.log(name);                //zach

另一个问题,就是计数循环闭包

var a = [];
for (var i = 0; i < 10; i++) {
    a[i] = function () {
        console.log(i);
    }
}
a[6]();        //10

用var定义的i值,成了全局变量,会致使最后的i值是最后一轮循环完成后的值,而使用let就不会有这个问题。app

var a = [];
for (let i = 0; i < 10; i++) {
    a[i] = function () {
        console.log(i);
    }
}
a[6]();        //6

下面咱们再来看个例子,页面上有5个类名相同的元素,咱们经过点击这些元素,分别弹出他们在集合中的序号编程语言

var clickBoxs = documnet.querySelectorAll('clickBox');
for (var i = 0; i < clickBoxs.length; i++) {
    clickBoxs[i].onclick = function () {
        alert(i);
    }
}

很不幸,每次弹出的都是5.for循环中用var定义的i,已是全局变量,在执行弹出时,实际上i已经累加到了5,若是咱们将var换成let,就能够在每次点击的时候获得咱们想要的结果。函数

再来想一想如何使用闭包来解决这个问题呢?

function iteratorFactory (i) {
    var onclick = function (e) {
        alert(i);
    }
    return onclick;
}

var clickBoxs = document.querySelectorAll('clickBox');
for (var i = 0; i < clickBoxs.length; i++) {
    clickBoxs[i].onclick = iteratorFactory(i);
}

const用来声明常量,一旦声明,常量的值是不能被改变的。

const PI = Math.PI;

###class,extends,super

这三个特性让咱们从JavaScript的原型面向对象中解脱出来,它们让JavaScript具备了像传统高级编程语言那样的写法。

class Animal {
    constructor () {
        this.type = 'animal';
    }

    says (message) {
        console.log(this.type + ' says ' + message);
    }
}

let animal = new Animal();
animal.says('hello');        //animal says hello

class Cat extends Animal {
    constructor () {
        super();
        this.type = 'cat';
    }
}

let cat = new Cat();
cat.says('hello');        //cat says hello

上面的代码首先定义了一个class,里面有个constructor,这是构造函数,this关键字指向当前类的实例对象。 class之间能够经过extends关键字实现继承,上面的代码中,Cat类经过extends继承了Animal类的全部属性和方法。 在子类中的constructor中,必须调用super方法,这是为了继承父类中的this。

arrow function

箭头函数,这是ES6最经常使用的特性,用它来写function比ES5的更加简介和清晰。

function(i){return i + 1;}        //ES5
(i) => i + 1;                    //ES6

若是有多行代码或代码比较复杂的,须要使用{}把代码包裹起来

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

(x, y) => {x++; y--; return x + y;}

箭头函数除了在写法上更加简洁以外,还有一个功能,更加明确了this的指向

class Animal {
    constructor () {
        this.type = 'animal';
    }

    says (message) {
        setTimeout (function () {
           console.log(this.type + ' says ' + message); 
        },1000);
    }
}

var animal = new Animal();
animal.says('hi');            //undefined says hi

上面的例子运行后,获得的结果是undefined says hi,跟咱们预想的不同,是由于在setTimeout中,this已经指向了全局。如今,咱们有两个传统的方法来解决

第一种,将this传递给self,也就是将this对象缓存起来

says (message) {
    var self = this;
    setTimeout(function () {
        console.log(self.type + ' says ' + message);
    }, 1000);
}

第二种,使用bind(this)

says (message) {
    setTimeout(function () {
        console.log(this.type + ' says ' + message);
    }.bind(this), 1000);
}

OK,如今咱们有了箭头函数,就不用这么麻烦了。

class Animal {
    constructor () {
        this.type = 'animal';
    }

    says (message) {
        setTimeout(() => {
            console.log(this.type + ' says ' + message);
        }, 1000);
    }
}

var animal = new Animal();
animal.says('hi');            //animal says hi

使用箭头函数时,函数体内的this就是定义时所在的对象,而不是使用时的对象。

template string

这玩意叫模板变量,它有什么用呢? 当咱们须要在JS中插入大量的html内容时,传统的写法很麻烦,因此咱们常常会引入一些模板工具库,咱们先来看下下面的代码

$('#result').append(
    "There are <b>" + basket.count + "</b>" + 
    "items in your basket, " + 
    "<em>" + basket.onSale +
    "</em> are on sale!"
);

咱们须要用一大堆的‘+’来连接文本和变量,而有了ES6的模板变量后,咱们能够这样写

$("#result").append(`
    There are <b>${basket.count}</b> items
    in your basket, <em>${basket.onSale}</em>
    are on sale!
`);

咱们用反引号" ` "来标示起始和结束,用" ${} "来引用变量,并且全部的空格和缩进都会被保留。

destructuring

ES6容许按照必定的模式,从数组和对象中取值,对变量进行赋值,这被称为解构(Destructuring)。

let cat = 'ken';
let dog = 'lili';
let zoo = {cat: cat, dog: dog};
console.log(zoo);                //Object {cat: "ken", dog: "lili"}

在ES6中,咱们能够这样写

let cat = 'ken';
let dog = 'lili';
let zoo = {cat, dog};
console.log(zoo);            //Object {cat: "ken", dog: "lili"}

反过来能够这么写

let dog = {type: 'animal', many: 2};
let {type, many} = dog;
console.log(type, many);                //animal 2

default, rest

default就是默认值的意思,若是在调用函数时候没有传参数,传统作法是加上这么一句,type = type || 'cat' 来指定默认值

function animal (type) {
    type = type || 'cat';
    console.log(type);
}

animal();                //cat

若是用ES6,就能够这样写

function animal (type = 'cat') {
    console.log(type);
}

animal();

rest的语法也很简单,看例子

function animals(...types) {
    console.log(types)
}

animals('cat', 'dog', 'fish');            //['cat', 'dog', 'fish']

若是不适用ES6的语法,那么咱们必须使用ES5的arguments

以上就是ES6中最经常使用的语法,能够说这20%的语法在使用中占了80%的使用率。

未完,待续...

相关文章
相关标签/搜索