谈谈ES6在实战中的使用技巧

2018-07-14 admin

前言

最近重构了公司vue全家桶的一个项目,在其中引入了大量es6的特性和用法,最大的感受是es6让js这门语言变得更加严谨,并提供了一些语法糖让开发变得更加方便。 本文对部分常用的es6语法进行说明,并对比es5之前的做法,谈谈运用es6在项目中带来的实际好处。

let 和 var

他们二者的核心区别是什么?简单说,就是其声明的变量所在的作用域不一样。 当然说到var,就不得不提js的变量提升,就是说,使用var关键字声明的变量,无论其实际声明位置在何处,都会被视为声明于所在函数的顶 部(如果声明不在函数内,则视为在全局作用域的顶部)。先来看一个例子:

function getValue(condition) {
  if (condition) {
    var value = 'red'
    return value
  } else {
    // value 在这里可以访问,值为undefined
    return null
  }
  // value 在这里可以访问,值为undefined
}

在上面代码中,不管condition是否为true,变量都是存在的,相当于如下定义:

function getValue (condition) {
  var value
  if (condition) {
    value = 'red'
    return value
  } else {
    return null
  }
}

这种特有行为,如果你不理解,就可能导致bug。所以,ES6引入了块级作用域,让变量的生命周期更加可控。 什么是块级作用域?块级作用域在如下情况被创建:

  1. 在一个函数内部
  2. 在一个代码块(由一对花括号包裹)内部

再来看看用let声明的代码:

function getValue (condition) {
  if (condition) {
    let value = "blue"
    return value
  } else {
    // value 在这里不可以访问
    return null
  }
  // value 在这里不可以访问
}

由于变量value声明使用的是let,所以就没有被提升到函数定义的顶部,变量value在if代码块外部是无法访问的;并且在condition的值为false 时,该变量不会被声明并初始化。 再来看一个循环的例子:

for (var i = 0; i < 6; i++) {
  console.log(i)
}

// i 在这里依旧可以访问
console.log(i)  // 6

想象一下,如果在for循环之外也定义了一个i变量,那么这种情况会让代码变得油腻起来,甚至会导致难以追踪的bug。所以,当我们需要让for循环中的变量i在循环之后失效,let声明就派上用场了

for (let i = 0; i < 6; i++) {
  console.log(i)
}

// i 在这里不可以访问
console.log(i)

模板字面量

在es6之前,在js中拼接字符串,可以这样:

let name = 'es6'
let str = 'Hello, ' + name + '.'

而在es6中,可以用使用反引号(`)来包裹普通字符串,如下:

let name = 'es6'
let str = `Hello, ${name}.`

用来拼接变量时还是很方便的。

includes() 方法

在数组和字符串中,经常会遇到这样一个问题:判断该数组或字符串中是否存在某个值。 在ES6之前,可以这样做:

let str = 'abcdef'
console.log(str.indexOf('b') > -1)

这当然没有问题,但是语义上显得不够直观,indexOf()方法是获得指定值的索引位置。通过该方法获得位置后还得比较一次才能判断是否存在。 我们再来看看ES6的作法:

let str = 'abcdef'
console.log(str.includes('b'))

显得更加清晰明了。但是,如果判断某个值是否在数组或字符串中存在,那么includes方法是非常方便的,但如果要获得某个值的索引位置,还是indexOf方法更合适。includes方法并不是indexOf方法的替代。 注意:和indexOf()一样,includes()在数组和字符串中都可以使用。

扩展运算符

求最值

求最值是很常见的一个操作,我们先看看在ES6之前是怎么做的:

let arr = [25, 50, 999, 100]
console.log(Math.max.apply(Math, arr))

该方法是可行的,但使用 apply() 让人觉得有一丝困惑,这里使用的额外语法混淆了代码的真实意图。 再看看ES6的写法:

// Math.max() 不允许传入数组
// 所以我们用扩展运算符把数组中的值展开成多个独立的值,再传入
console.log(Math.max(...arr))

这样的代码是不是看起来清晰多了?并且扩展运算符还可以与其他参数混用,比如:

console.log(Math.max(...arr, 1000, 888))

数组去重

这是一个很高频的面试问题,ES6之前,可以这样:

function unique(arr) {
  let temp = []
  for (let i = 0; i < arr.length; i++) {
    if (temp.includes(arr[i]) === false) {
      temp.push(arr[i])
    }
  }
  return temp
}

let numbers = [2, 2, 3, 6, 2, 3, 5]
console.log(unique(numbers))

当然数组去重有多种写法,我这里只列举一个,供大家参考。 再来看看es6的写法:

let arr = [2, 2, 3, 6, 2, 3, 5]
arr = [...new Set(arr)]
console.log(arr)

使用数组来初始化一个Set,Set构造器能确保不重复地使用这些值。很明显,es6的写法更简洁明了。

Vuex中的使用

export default {
  computed: {
    // 使用对象展开运算符将 getter 混入 computed 对象中
    ...mapGetters([
      'doneTodosCount',
      'anotherGetter'
    ])
  }
}

用过vuex的应该熟悉这样一段代码,这里运用扩展运算符配合mapGetters 辅助函数,会将上面代码解析成如下形式:

export default {
  computed: {
    doneTodosCount () {},
    anotherGetter () {}
  }
}

对象的简写

现有一个对象构造函数,其返回一个对象,对象中包含属性和值,在es6之前,写法如下:

function createPerson (name, age) {
  return {
    name: name,
    age: age
  }
}

es6提供了简写方式,当对象的一个属性名称与本地变量名相同时,你可以简单书写名称而省略冒号与值。可以这样:

function createPerson (name, age) {
  return {
    name,
    age
  }
}

这个特性在vue单文件组件中会常常遇到,比如:

components: {
  otherComponent
}

方法的简写

现有一个对象,对象中有一个方法,在es6之前,方法可以这样写:

var person = {
  name: 'foo',
  sayName: function () {
    console.log(this.name)
  }
}

es6提供了简写方法的写法,通过省略冒号与function关键字,你可以这样:

var person = {
  name: 'foo',
  sayName () {
    console.log(this.name)
  }
}

延伸阅读

本文只列出了部分es6语法,对于有些特性,如promise,箭头函数,await等,在我的项目中也会频繁使用,但网上有很好的文章,就不细说了。下面提供链接,供有兴趣的朋友参考。 大白话讲解Promise ECMAScript 6 入门 理解 JavaScript 的 async/await

参考资料

ECMAScript 6 入门 Understanding ECMAScript 6

小结

ES6让js这门语言变得更加精细,更加强大。虽然不是非得掌握es6才能编程,但是掌握部分特性能提高开发效率。何乐而不为呢?这些都是我在项目中的使用心得,本文就当抛砖了。

原文链接:https://segmentfault.com/a/1190000015634369

本站文章除注明转载外,均为本站原创或编译。欢迎任何形式的转载,但请务必注明出处。

转载请注明:文章转载自 JavaScript中文网 [https://www.javascriptcn.com]

本文地址:https://www.javascriptcn.com/read-35973.html

文章标题:谈谈ES6在实战中的使用技巧

相关文章
IO.js 1.0.0 正式发布,支持 ES6 语言特性!
IO.js 是为 V8 引擎编写的基于事件 IO 的实现。Node.js中一群不满Joyent公司控制的信徒发起了另外一个项目io.js,即另外一个支持服务器端JavaScript的变种,称为io.js或iojs 。 IO.js 1.0.0...
2015-11-12
在 Microsoft Azure 中使用 MEAN 堆栈基于开放数据协议
网络开发人员通常构建伟大的应用程序在客户端使用JavaScript和ASP(c#或Visual Basic . NET)在服务器端。 但是如果你能使用一个共同的语言来构建应用程序的所有层堆栈,从浏览器和服务器端业务处理服务层,甚至在数据库查...
2015-11-12
jQuery的一些技巧大放送
1、关于页面元素的引用 通过jquery的$()引用元素包括通过id、class、元素名以及元素的层级关系及dom或者xpath条件等方法,且返回的对象为jquery对象(集合对象),不能直接调用dom定义的方法。 2、jQuery对象与d...
2015-11-11
2015年2月国内操作系统市场份额概况,xp占46.29%,
规则调整:2012年6月1日开始,Mac操作系统中不再包含ipad、iphone市场份额。 ...
2015-11-12
AngularJS:何时应该使用Directive、Controller、Servic
AngularJS是一款非常强大的前端MVC框架。同时,它也引入了相当多的概念,这些概念我们可能不是太熟悉。(译者注:老外真谦虚,我大天朝的码农对这些概念那是相当熟悉啊!)这些概念有: Directive(指令) Controller(控制...
2015-11-11
Bootstrap BootstrapDialog使用详解
这里有两种展现方式 写在前面:首先你要引入的库有 css : bootstrap.min.css bootstrap-dialog.css js : jquery-1.11.1.min.js bootstrap.min.js bootstr...
2017-03-16
使用 Protocol Buffers 代替 JSON 的五个原因
在 Ruby 和 Rails 开发者中,面向服务 (Service-Oriented) 架构有一个当之无愧的名声,它是一个缓解程序规模恶性增长的一个强有力的途径,可在大量应用程序中提取关注点。这些新生小巧的服务通常继续使用 Rails 或 ...
2016-01-13
vue使用watch 观察路由变化,重新获取内容
问题背景: 点击用户头像 =&gt; 进入用户个人中心,在用户个人中心里点击其他用户的头像,我希望显示被点击用户的个人中心,但只看到了路由参数在发生变化,页面内容并没有更新。如图: 页面代码如下: &lt;script&gt; exp...
2017-03-13
Node.js v0.11.16 开发版发布
Node.js v0.11.16 开发版发布了,改进记录包括: openssl: Upgrade to 1.0.1l npm: Upgrade to 2.3.0 url: revert support of path for url.fo...
2015-11-12
javascript中的switch语句
switch语句:该语句对表达求值结果和case的值进行比较。如果找到匹配,则程序执行的与该case关联的语句。break为可选参数,通常使用break阻止代码向下一个case执行。switch语句如下: switch (expressio...
2015-11-12
回到顶部