ES6( ECMAScript6),由于是在2015年发布的,所以也称为ECMAScript 2015。
不是所有的es6的新特性浏览器都支持。所以要保证es6能正常的运行,需要了解一下Babel。它是将es6转化为es5,从而执行。
现在来看几个最常用的es6的新特性。
一、let\const声明的变量没有变量提升,会出现not defined。
同一个变量名不能在一个作用域中同时使用let和const声明,会报错
变量不能在作用域外访问
首先我们知道在js中没有块级作用域的概念,只能自己想办法创建块级作用域。
最常比较的就是let和var。es6出现了let,那么这个let就可以完全取代var,且没有副作用。
for(var i = 0; i<10; i++){} alert(i);//10
for (let i = 0; i < 10; i++) {}
console.log(i); //ReferenceError: i is not defined```
let和const的比较
const和let一般优先选择const,尤其是在全局作用域下,应该优先声明的是常量,而不是变量。
const可以提醒阅读的人,这个值不应该被改变,并且const也是一个符合函数式编程思想,运算不改变值,只是用于创建新的值,有利于将来的分布式运算。最后一个原因是JavaScript编译器会对const进行优化。所以多使用const有利于提高程序的运行效率。
{
console.log(x);//not defined
let x= 10;
console.log(x);//10
}
console.log(x);//not defined
二、const声明的变量值不可以修改,但是声明的对象的属性可以修改。
const a = 10;
a = 11;
alert(a);//报错
const obj = {x:1,y:2};
function foo(obj){
alert(obj.x++);//1
alert(obj.y--);//2
}
foo(obj);
三、模板字符串。
在es6中:使用“引起来的字符串中可以使用${变量}来读取变量的值,不用麻烦的字符拼接。
const a = 10;
alert(`这是a 的值 ${a}`);//这是a的值10
四、多行字符串
var centence = "dhuewbfewfb
dnejwnewj
cnekwcnekw"
alert(centence);
这样是不被允许的。会报错,只能通过+拼接。
但在es6中,使用反引号就可以实现多行字符串。
var centence = `dhuewbfewfb
dnejwnewj
cnekwcnekw`;
alert(centence);
五、默认参数defalut和rest
js中默认的是这样,当没有参数时就使用默认的。
function print(width,height,color){
var width = width||50;
var height = height||60;
var color = color || "blue";
alert(width+","+"height"+","+color);
}
print(); // 50,60,blue
在es6中这样实现。这样的写法简略了许多代码。当没有值时采用参数后面的默认值
注:这不是赋值,只是如果没有参数时使用。
function print(width = 50, height = 60, color = "blue"){
alert(`${width} ${height} ${color}`);
}
print();// 50,60,blue
print(100,20,"red");// 100,20,red
rest
function animals(…types){
console.log(types)
}
animals(‘cat’, ‘dog’, ‘fish’) //[“cat”, “dog”, “fish”]
避免使用了arguments。
六、对象中的方法可以不用使用function来进行声明
var obj = {
aa:function(a,b){
return a+b;
}
}
等价于
var obj = {
aa(a,b){
return a+b;
}
}
七、箭头函数
es6为编写函数提供了一种新语法。最常用的特性.
一般写函数的时候是这样的。
function fun(i){
return i+1;
}
es6就可以简化成这样.和上面的是等价的。
var fun = i=> (i + 1);
调用的时候和普通函数一样:alert(fun(3));
它的语法非常简单:标识符=>表达式。你无需输入function和return,一些小括号、大括号以及分号也可以省略。
如果函数比较复杂的话可以使用{}括起来。
es5
function aa(a,b,c){
a ++;
b --;
c *= b;
return a*b *c;
}
es6
let aa=(a,b,c)=>{
a ++;
b --;
c *= b;
return a*b *c;
}
需要多重参数的时候,使用小括号括起来。
还有使用rest参数和箭头函数的例子
const numbers = (…nums) => nums;
numbers(1,2,3,4,5,6,7,8,9); //[1,2,3,4,5,6,7,8,9]
//…nums 表示的是一个数组
const headAndTail = ( head, …tail) => [head, tail];
headAndTail(1,2,3,4,5,6,7,8,9);// [1, [2,3,4,5,6,7,8,9]]
除了这个特性以外,箭头函数还有更重要的用途。
就是关于this的指向。
一般在对象中,为了使this只想当前的对对象,我们通常使用that= this,_this = this等类似的方法来记录this的指向,还得特别小心。
class Animal {
constructor(){
this.type = 'animal'
}
says(say){
setTimeout(function(){
console.log(this.type + ' says ' + say)
}.bind(this), 1000)
}
}
var animal = new Animal()
animal.says('hi') //undefined says hi
因为setTimeout中的this指向的是全局,所以要正确执行这个函数,需要改变this的指向。
可以这样:
says(say){
var that = this;
setTimeout(function(){
console.log(that.type + ' says ' + say)
}, 1000)
}
也可以使用bind.
says(say){
setTimeout(function(){
console.log(that.type + ' says ' + say)
}.bind(this), 1000)
}
但是这儿有了箭头函数就没必要那么麻烦了。
class 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
当我们使用箭头函数时,函数体内的this对象,就是定义时所在的对象,而不是使用时所在的对象。
并不是因为箭头函数内部有绑定this的机制,实际原因是箭头函数根本没有自己的this,它的this是继承外面的,因此内部的this就是外层代码块的this。
使用箭头函数注意几点:
1、函数体内的this对象就是定义时所在的对象,而不是使用时所在对象;
2、不可以当作构造函数使用,也就是不能用new命令实例化一个对象,否则会抛出一个错误;
3、不可以使用arguments对象,该对象在函数体内不存在,如果要用的话,可以用rest参数代替;
4、不可以使用yield命令,箭头函数不能用作Generator函数;
八、解构赋值
ES6允许按照一定模式,从数组和对象中提取值,对变量进行赋值,这被称为解构(Destructuring)。
1.在使用给数组赋值时优先使用解构赋值。
const one = arr[0];
const two = arr[1];
······
const nine = arr[9];
这样赋值是很麻烦的。我们可以这样使用解构赋值:
const[one,two,……nine] = arr;
2.函数的参数如果是对象,优先使用解构赋值
function bb(obj){
const first = obj.name;
const second = obj.age;
}
好一点的办法是:
function bb(obj){
const {first,second} = obj;
}
最好的办法是:
function bb({first,second}){ };
3.如果函数有多个返回值,优先使用对象的解构赋值,而不是数组的解构赋值。
// bad
function processInput(input) {
return [left, right, top, bottom];
}
// good
function processInput(input) {
return { left, right, top, bottom };
}
const { left, right } = processInput(input);
九、模块的导入导出
以前我们写的js代码都没有一个明确的引用关系将代码组织起来,只能依靠第三方工具CommonJs,AMD(requireJs),CMD(seat.js)等等来进行js的组织。
但是现在es6实现了自己的模块化来进行js代码间的关系组织,它可以很好地成为浏览器端和服务器端的通用的模块解决方案。
export 和 export default都是导出文件,函数,常量,模块等。
用import{函数|常量|模块} from “引用路径” 进行导入。
export可以有多个,但export default只能有一个。
//index.js
var a = "123";
function b(){
alert("asdf");
}
导出的方法:
1.export a;
export b;
2. export {a,b};
3. export var a = "123";
export function b(){
alert("asdf");
}
4.export{a as aa, b as bb}以重命名的方式导出;
引入
1.import {a,b} from ‘./index.js’;
2.如果要引入某一个文件的全部的导出的方法
import * as 文件名 form “路径名”;
对象的导出与导入
module.exports = “对象名”;
import 对象名 from 路径;