前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >ES6新特性速览

ES6新特性速览

作者头像
张子阳
发布2018-09-30 10:01:31
5970
发布2018-09-30 10:01:31
举报

ES6新特性速览

2018-2-5 作者: 张子阳 分类: Web前端

引言

ES6引入了很多新的语言特性和能力,这篇文章仅快速地做一个概览。包括let、解构、箭头函数、模块化、Spread运算符 等。ES6还有很多更深入的内容,有时间再单独总结。大部分的ES6新特性,最新版的Chrome浏览器都原生支持,所以下面大多数代码不需要使用Babel转码器即可直接运行。但是模块化的import和export则暂未支持,只能通过Babel经过webpack等工具打包后使用。

let和var

let具有括号作用域,而var仅有函数作用域,没有括号作用域,因此在大多数情况下都推荐使用let。下面是简单的对比。

代码语言:txt
复制
for(var i=0; i<3; i++){}
console.log(i); // 3

for(let j=0; j<3; j++){}
console.log(j); // Uncaught ReferenceError: j is not defined

使用var时,为了避免变量冲突,通常是使用立即执行函数来建立一个块级作用域:

代码语言:txt
复制
(function(){
    var i = 1;
    console.log("a:", i); // 1    
})();

console.log("b:", i);     // Uncaught ReferenceError: i is not defined

如果是代码块,变量在代码块结束后依然会存在:

代码语言:txt
复制
{
    var j = 1;
    console.log("a:", j); // 1   
}

console.log("b:", j);   // 1 

使用let则不会有这个问题:

代码语言:txt
复制
{
    let i = 1;
    console.log("a:", i); // 1   
}

console.log("b:", i);  // Uncaught ReferenceError: i is not defined

一个典型的作用域问题是:遍历li对象,并赋予点击事件:

代码语言:txt
复制
<ul>
    <li>项目A</li>
    <li>项目B</li>
    <li>项目C</li>
</ul>
代码语言:txt
复制
var arr = document.querySelectorAll("li");

for(var i=0; i<arr.length; i++){
    arr[i].onclick = function(){
        alert("你点击了第"+ i +"个项目");
    }
}

console.log("i:", i); // 3

此时,不管点击哪个li,都会弹出“你点击了第3个项目”,因为在for循环结束后,i依然“活着”,并且值为3。

只需要将var i=0 改为 let i=0,则没有这个问题。而在let出现以前,传统的解决方案依然是利用函数作用域,将i作为立即执行函数的参数,写一个闭包函数:

代码语言:txt
复制
var arr = document.querySelectorAll("li");

for(var i=0; i<arr.length; i++){
    (function(x){
        arr[x].onclick = function(){
            alert("你点击了第"+ x +"个项目");
        }    
    })(i);    
}

const

服务端的很多语言都有const,例如我比较熟悉的C#,顾名思义,变量用const声明后值不可以再变。

代码语言:txt
复制
const PI = 3.1415926;
PI = 3;      // Uncaught TypeError: Assignment to constant variable.

const还有两个注意事项,1:声明时就需要赋值。

代码语言:txt
复制
const PI;           // Uncaught SyntaxError: Missing initializer in const declaration
PI = 3.1415926;

2:如果是对象,可以修改内部值,但不能重新赋值。

代码语言:txt
复制
const loc = { x:1 , y: 2}
loc.x = 3;
console.log(loc);       // {x:3, y:2}

loc = {}      // Uncaught TypeError: Assignment to constant variable.

箭头函数

箭头函数类似C#中的lambda表达式,大多数情况下,可以作为函数的简写形式。

代码语言:txt
复制
function multiply(x){
    return x*2;
}

// 相当于
const multiply = (x) => {
    return x*2;
}

当函数体只有一行return时,可以再次简化,省略掉花括号和return关键字。

代码语言:txt
复制
const multiply = (x) => x*2;

当只有一个输入参数时,参数的圆括号()也可以省略掉。(如果有多个参数或者没有参数,则必须有圆括号)。

代码语言:txt
复制
const multiply = x => x*2;

var i = multiply(1);
console.log(i);     // 2

箭头函数和普通函数最重要的一个区别,就是this关键字绑定到了函数定义时的作用域,而非函数运行时的作用域。下面是一个例子:

代码语言:txt
复制
function Product(){
    this.title = "NS Switch";
    
    this.showName1 = function(){
        console.log(this)
        console.log("showName1:", this.title);
    }
    
    this.showName2 = ()=>{
        console.log(this)
        console.log("showName2:", this.title);
    }
}

var p = new Product();

var showName1 = p.showName1;
var showName2 = p.showName2;
showName1();        // Uncaught TypeError: Cannot read property 'title' of undefined
showName2();        // NS Switch

setTimeout(p.showName1, 1000)   // this为window,this.title为undefined
setTimeout(p.showName2, 1000)   // NS Switch

import和export

import和export用于支持模块化(modules)。假设utility.js用来创建模块,而page.js使用该模块,则用法如下所示:

方式1:使用default关键字

代码语言:txt
复制
// utility.js
const Person = {
    name : "jimmy"
}

export default Person
代码语言:txt
复制
// page.js
import util from "./utility.js"

console.log(util);      // {name:"jimmy"}

方式2:多个对象时使用星号 *

代码语言:txt
复制
// utility.js
export const Person = {
    name : "jimmy"
}

export const Student = {
    score: 100
}
代码语言:txt
复制
// page.js
import * as util from "./utility.js"

console.log(util.Person);      // {name:"jimmy"}
console.log(util.Student);      // {score:100}

方式3:多个对象时使用析构

模块导出不变。模块引入才用下面的方式。

代码语言:txt
复制
// page.js
import { Person, Student } from "./utility.js"

console.log(Person);      // {name:"jimmy"}
console.log(Student);      // {score:100}

Spread和Rest运算符

这两个运算符的表示方法都是三个点:...,根据使用的位置来区分。

Spread运算符:用于展开数组或者对象。

代码语言:txt
复制
// 数组展开
var oldArr = [1,2,3]
var newArr = [0, ...oldArr, 4]
console.log(newArr);    // [0,1,2,3,4]
代码语言:txt
复制
// 对象展开
var oldObj = { x:1, y:2}
var newObj = { ...oldObj, z:3 }
console.log(newObj);    // {x: 1, y: 2, z: 3}

需要注意的是,当新对象的属性名重复时,会进行覆盖:

代码语言:txt
复制
var oldObj = { x:1, y:2}
var newObj = {...oldObj, y:3 }
console.log(newObj);    // {x: 1, y: 3}

Rest运算符:用于个数不定的函数参数

可以看到,实际上相当于将不定个数的函数参数合并成了数组。

代码语言:txt
复制
function total(...args){
    var t = 0;
    for(let i=0; i< args.length;i++){
        t += args[i]
    }
    return t;
}
console.log(total(1,2)) // 3
console.log(total(3,4,5)) // 12

析构(destructering)

更方便地将数组元素或者对象属性提取出来保存到变量中。

代码语言:txt
复制
// 析构数组
const arr = [1,2,3]
var [x, y] = arr;
console.log(x, y);    // 1, 2

var [, , z] = arr;
console.log(z);    // 3
代码语言:txt
复制
// 析构对象
const obj = { x:1, y:2, z:3 }
var {x, z} = obj;
console.log(x, z); // 1, 3

感谢阅读,希望这篇文章能给你带来帮助!

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2018-2-5,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • ES6新特性速览
    • 引言
      • let和var
        • const
          • 箭头函数
            • import和export
              • Spread和Rest运算符
                • 析构(destructering)
                领券
                问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档