1.箭头函数(=>)
ES6中引入了箭头函数符来代替function,也就是说在定义方法的时候可以不再写function,=>的左边即为函数名和参数,右边即为执行操作和返回值。
例如:
function(i){return i + 1; } //ES5 (i) => i + 1 //ES6
如果方法比较复杂,则执行的操作需要用{}包裹起来。例如:
function(x, y) { //ES5 x++; y--; return x + y; } (x, y) => {x++; y--; return x+y} //ES6
引入箭头函数不仅使得写法更加简洁清晰,同时也解决了js中this作用域的问题。
在ES5中,函数当中的this仅指代当前函数,如果函数当中还包含函数,那么this的使用就需要相当小心。例如:
class Animal { constructor(){ this.type = 'animal' //这里的this指代Animal对象 } says(say){ setTimeout(function(){ console.log(this.type + ' says ' + say)//这里的this紧指代setTimeout的执行函数,而该函数中并没有type属性 }, 1000) } } var animal = new Animal() animal.says('hi') //undefined says hi 传统的做法有以下2种: 第一种:声明一个变量指代最外层对象的this,然后在内层函数中使用该变量。例如: says(say){ var self = this; setTimeout(function(){ console.log(self.type + ' says ' + say) }, 1000) }
第二种:使用bind(this),bind方法会新创建一个绑定函数,当调用这个绑定函数的时候会以bind方法的第一个参数修改函数内部的this指向。例如:
says(say){ setTimeout(function(){ console.log(this.type + ' says ' + say) }.bind(this), 1000)//用says的this对象替代setTimeout执行方法的this对象 }
由于箭头函数内部并没有定义this对象,所以函数内部的this完全是继承的外部的,所以ES6中将不必担心上面的问题。例如:
lass Animal { constructor(){ this.type = 'animal' } says(say){ setTimeout( () => { console.log(this.type + ' says ' + say) }, 1000) } } var animal = new Animal() animal.says('hi') //animal says hi
2.变量声明(let、const)
ES6中新引入了2个变量的声明let和const,他们的作用基本跟var相同,具体区别如下:
var 声明的变量作用在全局或者方法体内。块级变量只能使用全局变量或方法体的变量。
let声明的变量只作用在代码块。可以完全使用let代替var。
const只是用来声明常量的,且一旦声明常量的值就不能改变了。能够更清晰的表明这是常量,不能修改。
先来看一个let和var使用区别的例子:
var name = 'zach' while (true) { var name = 'obama' console.log(name) //obama break } console.log(name) //obama //由于var作用域只有全局和函数内部,所以第二次声明的作用域跟第一次声明一致。
let name = 'zach' while (true) { let name = 'obama' console.log(name) //obama break } console.log(name) //zach //let的作用域只存在于块级内部。
var由于作用域的问题存在循环变量泄漏为全局变量的问题。如下:
var a = []; for (var i = 0; i < 10; i++) { a[i] = function () { console.log(i); }; } a[6](); // 10
上面代码就是因为i被泄漏为了全局变量,当循环完成后i已经为10了,所以无论数组下标是几的结果都是10。
传统的解决方案是采用闭包。例如:
var a = []; for (var i = 0; i < 10; i++) { a[i] = getA(i); } function getA(i){ var showA = function () { console.log(i); }; return showA; } a[6](); // 6
ES6使用let的解决方法如下:
var a = []; for (let i = 0; i < 10; i++) { a[i] = function () { console.log(i); }; } a[6](); // 6
const只是用来声明常量,当我们试图修改它声明的常量时,浏览器会报错。
其最好的应用场景是,当我们引入第三方插件库的时候可以保证插件声明不重复。
需注意:静态字符串声明统一使用单引号或反引号,不使用双引号,动态字符串使用反引号。例如:
const PI = Math.PI const monent = require('moment') const b = `foo${a}bar`;