常用ES6语法总结

参考链接:http://es6.ruanyifeng.com/

const

声明一个只读的常量。

改变常量的值会报错。只声明不赋值也会报错。只在声明所在的块级作用域内有效。声明的常量不会提升,只能在声明的位置后面使用,否则会报错。重复声明会报错。

let

声明变量。用法类似于var,但所声明的变量只在let命令所在的代码块里有效。

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

上面代码中,用var声明的变量i,在全局范围内有效,全局只有一个变量i,循环内被赋给数组a的函数内部的i指向的是全局变量i。所以数组所有成员里的i都指的同一个i,最后输出的是最后一轮的i的值,也就是10。

使用let声明的变量i,当前i只在本轮循环有效,所以每一次循环的i其实都是一个新的变量。所以最后输出的是6。

块级作用域

ES6中的{}内是一个块级作用域。

块级作用域的出现,使立即执行函数表达式不再必要了。

//立即执行函数的写法
(function () {
    var tmp = 123;
    //一段代码
})

//块级作用域的写法
{
    let tmp = 123;
    //一段代码
}

函数的扩展

箭头函数

ES6允许使用箭头定义函数。

var f = v => v;

//等同于
var f = function (v) {
    return v;
}

如果箭头函数不需要参数或需要多个参数,使用圆括号代表参数部分。

var f = () => 5;
//等同于
var f = function () {
    return 5;
}


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

如果箭头函数的代码块部分多余一条语句,就使用大括号把它们括起来,并且使用return语句返回。

var sum = (num1, num2) => {
    return num1 + num2
};

由于大括号被解释为代码块,所以如果箭头函数直接返回一个对象,必须在对象外面加上括号,否则会报错。

var getObject = () => {a:1, b:2};    //报错

var getObject = () => ({a: 1, b: 2});    //不报错

箭头函数函数体内的this指向函数定义时所在的对象,而不是调用时所在的对象

var Factory = function () {
    this.a = 'a';
    this.b = 'b';
    this.c = {
        a: 'c.a',
        b: function () {
            return this.a;
        }
    }
}
console.log(new Factory().c.b());   //'c.a'


var Factory = function () {
    this.a = 'a';
    this.b = 'b';
    this.c = {
        a: 'c.a',
        b: () => this.a
    }
}
console.log(new Factory().c.b());   //'a'

 函数参数的默认值

ES6之前不能直接为函数的参数指定默认值,只能采用变通的方法。

{
    //ES5/ES3的写法
    function f(x, y) {
        y = y || 7;
        return x + y;
    }

    console.log(f(1));  //8
    console.log(f(1, 3));   //4
}

{
    //ES6写法
    function f(x, y = 7) {
        return x + y;
    }

    console.log(f(1));  //8
    console.log(f(1, 3));   //4
}

利用参数默认值,可以指定某一个参数不得省略,如果省略就抛出一个错误

{
    function check() {
        throw new Error('x参数不能为空');
    }

    function f(x = check(), y = 7) {
        return x + y;
    }

    f();   //报错,x参数不能为空
}

rest参数(扩展运算符)

Proxy(代理)

在目标对象之前架设一层拦截,外界对该对象的访问,都必须先通过这层拦截,因此提供了一种可以对外界的访问进行过滤和修改的机制。以创建一个sex私有属性为例:

 1 {
 2     //ES3
 3     function Person() {
 4         var data = {
 5             name: 'es3',
 6             sex: 'male'
 7         }
 8         this.get = function (key) {
 9             return data[key];
10         }
11         this.set = function (key, value) {
12             if (key !== 'sex') {
13                 data[key] = value;
14             }
15         }
16     }
17 
18     var person = new Person();
19     console.table({name: person.get('name'), sex: person.get('sex')});
20     person.set('sex', 'female')
21     person.set('name', 'es3+')
22     console.table({name: person.get('name'), sex: person.get('sex')});
23     //name的值改变了,sex的值没有变化
24 }
25 {
26     //ES5
27     var Person = {
28         name: 'es5',
29     };
30     Object.defineProperty(Person, 'sex', {
31         writable: false,
32         value: 'male'
33     });
34     console.table({name: Person.name, sex: Person.sex});
35     Person.name = 'es5+';
36     Person.sex = 'female';
37     console.table({name: Person.name, sex: Person.sex});
38     //name的值改变了,sex的值没有变化
39 }
40 {
41     //ES6
42     let Person = {
43         name: 'es6',
44         sex: 'male'
45     };
46     let person = new Proxy(Person, {
47         get(target, key){
48             return target[key];
49         },
50         set(target, key, value){
51             "use strict";
52             if (key !== 'sex') {
53                 target[key] = value;
54             }
55         }
56     });
57     console.table({name: person.name, sex: person.sex});
58     person.sex = 'female';
59     person.name = 'es6+'
60     console.table({name: person.name, sex: person.sex});
61     //name的值改变了,sex的值没有变化
62 
63 }
posted @ 2018-03-27 15:28  懒懒同学不懒  阅读(157)  评论(0编辑  收藏  举报