常用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 }