JS 开发者必须知道的七个 ES6 新特性

es6

1. ES6中的默认参数

var link = function (height, color, url) {
    var height = height || 50
    var color = color || 'red'
    var url = url || 'http://azat.co'
}

2. ES6中的模版表达式

模版表达式在其他语言中一般是为了在模版字符串中输出变量,所以在ES5中,我们非得把字符串破开变成这样:

	
var name = 'Your name is ' + first + ' ' + last + '.'
var url = 'http://localhost:3000/api/messages/' + id

幸运的是在ES6中我们有了新语法,在反引号包裹的字符串中,使用${NAME}语法来表示模板字符:


var name = `Your name is ${first} ${last}`
var url = `http://localhost:3000/api/messages/${id}`

3. ES6中的多行字符串

另一个好吃的语法糖就是多行字符串,以前我们的实现是像这样的:

var roadPoem = 'Then took the other, as just as fair,nt'
    + 'And having perhaps the better claimnt'
    + 'Because it was grassy and wanted wear,nt'
    + 'Though as for that the passing therent'
    + 'Had worn them really about the same,nt'
 
var fourAgreements = 'You have the right to be you.n
    You can only be you when you do your best.'

但是在ES6中,只要充分利用反引号。

var roadPoem = `Then took the other, as just as fair,
    And having perhaps the better claim
    Because it was grassy and wanted wear,
    Though as for that the passing there
    Had worn them really about the same,`
 
var fourAgreements = `You have the right to be you.
    You can only be you when you do your best.`

4. ES6中的拆包表达式

拆包可能是一个比较难理解的概念,因为这里面真的是有魔法发生。假如说你有一个简单的赋值表达式,把对象中的housemouse赋值为housemouse的变量。

 

var data = $('body').data(), // 假设data中有mouse和house的值
  house = data.house,
  mouse = data.mouse

另一个拆包的实例(Node.js):

var jsonMiddleware = require('body-parser').json
 
var body = req.body, // body中有用户名和密码值
  username = body.username,
  password = body.password

 

但是在ES6中我们可以用以下语句替换:

var { house, mouse} = $('body').data() // 我们会拿到house和mouse的值的
 
var {jsonMiddleware} = require('body-parser')
 
var {username, password} = req.body

甚至在数组中也能用,简直疯狂!

var [col1, col2]  = $('.column'),
  [line1, line2, line3, , line5] = file.split('n')

 

习惯拆包语法可能需要一些时间,但是这绝对是糖衣炮弹

 

5.块级作用域的letconst

你可能早就听过对ES6中的let那些奇怪的传说,我记得我第一次到伦敦时为那些TO LET牌子感到非常困惑。但是ES6中的let和出租无关,这不算是语法糖,它很复杂。let是一个更新的var,可以让你把变量作用域限制在当前块里。我们用{}来定义块,但是在ES5中这些花括号起不到任何作用。

function calculateTotalAmount (vip) {
  var amount = 0
  if (vip) {
    var amount = 1
  }
  { // 让块来的更疯狂
    var amount = 100
    {
      var amount = 1000
      }
  }  
  return amount
}
 
console.log(calculateTotalAmount(true))

 

运行结果将会是1000。天啊!这是多大的一个Bug。在ES6中,我们用let来限制变量作用域为函数内。

function calculateTotalAmount (vip) {
  var amount = 0 // 或许应该用let, 但你可以混用
  if (vip) {
    let amount = 1 // 第一个数量为 0
  } 
  { // 更多的块
    let amount = 100 // 第一个数量为 0
    {
      let amount = 1000 // 第一个数量为 0
      }
  }  
  return amount
}
 
console.log(calculateTotalAmount(true))

运行结果是0,因为在if块中也有let。如果什么都没有的话(amount=1),那么结果将会是1

说到const,事情就简单多了。他仅仅产生是一个不可变的变量,并且他的作用域也像let一样只有块级。为了演示,这里有定义了一堆常量,并且由于作用域的原因,这些定义都是有效的。

function calculateTotalAmount (vip) {
  const amount = 0  
  if (vip) {
    const amount = 1 
  } 
  { // 更多的块
    const amount = 100 
    {
      const amount = 1000
      }
  }  
  return amount
}
 
console.log(calculateTotalAmount(true))

依我愚见,letconst让这门语言变得更加复杂,没有这些的时候我们只有一条路可以走,但是现在可以要考虑更多的情景。;-(

6. ES6中的类

如果你喜欢面向对象编程,那么你会特别喜欢这个特性。他让你编写和继承类时就跟在Facebook上发一个评论这么简单。

在ES5中,因为没有class关键字(但它是毫无作用的保留字),类的创建和使用是让人十分痛苦的事情。更惨的是,很多伪类的实现像pseude-classicalclassicalfunctional让人越来越摸不着头脑,为JavaScript的信仰战争火上浇油。

我不会给你展示在ES5中怎么去编写一个类(是啦是啦从对象可以衍生出来其他的类和对象),因为有太多方法去完成。我们直接看ES6的示例,告诉你ES6的类会用prototype来实现而不是function。现在有一个baseModel类,其中我们可以定义构造函数和getName()方法。

class baseModel {
  constructor(options = {}, data = []) { // class constructor
        this.name = 'Base'
    this.url = 'http://azat.co/api'
        this.data = data
    this.options = options
    }
 
    getName() { // class method
        console.log(`Class name: ${this.name}`)
    }
}

注意到我给optionsdata用了默认参数,而且方法名再也不用加上function或者:了。还有一个很大的区别,你不能像构造函数里面一样向this.Name指派值。怎么说呢,和函数有相同缩进的代码里,你不能向name赋值。如果有这个需要的话,在构造函数里面完成。

使用NAME extends PARENT_NAME语法,AccountModelbaseModel继承而来。

class AccountModel extends baseModel {
    constructor(options, data) {

调用父类构造函数时,只需带上参数轻松的调用super()方法。

        super({private: true}, ['32113123123', '524214691']) //call the parent method with super
        this.name = 'Account Model'
        this.url +='/accounts/'
    }

想要高级一点的话,你可以像这样弄一个getter方法,这样accountsData就会变成一个属性。

    get accountsData() { // 返回计算后的数据
        // ... make XHR
        return this.data
    }
}

现在你要怎么用这个魔咒,很简单,就跟让三岁小孩相信圣诞老人存在一样。

let accounts = new AccountModel(5)
accounts.getName()
console.log('Data is %s', accounts.accountsData)

如果好奇输出结果的话:

Class name: Account Model
Data is 32113123123,524214691

7. ES6中的模块化

你可能知道,ES6之前JavaScript并没有对模块化有过原生的支持,人们想出来AMDRequireJSCommenJS等等,现在终于有importexport运算符来实现了。

ES5中你会用script标签和IIFE(立即执行函数),或者是其他的像AMD之类的库,但是ES6中你可以用export来暴露你的类。我是喜欢Node.js的人,所以我用和Node.js语法一样的CommonJS,然后用Browserfy来浏览器化。现在我们有一个port变量和getAccounts方法,在ES5中:

module.exports = {
  port: 3000,
  getAccounts: function() {
    ...
  }
}

在ES5的main.js中,用require('模块')来导入:

var service = require('module.js')
console.log(service.port) // 3000

但是在ES6中,我们用exportimport。比如这是ES6中的module.js文件:

export var port = 3000
export function getAccounts(url) {
  ...
}

在需要引入的main.js文件中,可以用import {名称} from '模块'语法:

import {port, getAccounts} from 'module'
console.log(port) // 3000

或者就直接在main.js中引入所有的变量:

import * as service from 'module'
console.log(service.port) // 3000

个人来说,我觉得这样的模块化有些搞不懂。确实,这样会更传神一些 。但是Node.js中的模块不会马上就改过来,浏览器和服务器的代码最好是用同样的标准,所以目前我还是会坚持CommonJS/Node.js的方式。

目前来说浏览器对ES6的支持还遥遥无期(本文写作时),所以你需要一些像jspm这样的工具来用ES6的模块。

想要了解更多ES6中的模块化和例子的话,来看这篇文章,不管怎么说,写现代化的JavaScript吧!

  1. ES6速查手册PDF
  2. Nicholas C. Zakas所著的理解ECMAScript6
  3. Dr. Axel Rauschmayer所著的探索ECMAScript6
  4. 本文非原创:传送门
  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值