Skip to content

Instantly share code, notes, and snippets.

@teabyii
Created July 9, 2015 03:25
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save teabyii/bd36bfcbf63a871a7c46 to your computer and use it in GitHub Desktop.
Save teabyii/bd36bfcbf63a871a7c46 to your computer and use it in GitHub Desktop.

ES6 带来了什么

未来已来,突然好喜欢这句话,哈哈。

ES6 已经离我们越来越近了,不久前发布了 ES6 标准文档,而 babel 社区如火如荼,对于 ES6 究竟给 js 开发者们带来了什么东西,我们来简单地了解一下。

这个文章并不会深入讲解某一部分的内容,只是帮助你快速地浏览一下 ES6 相关的东西究竟有哪一些,毕竟,其中每一部分的内容深入探讨都足够是一篇新的文章。

新增语法

函数的简写

let foo = {
  x: 1,
  y() {
    return (x) => this.x + x + arguments[0]
  }
}

let add = foo.y(1)
add(1) // 3

箭头声明的函数有以下特征:

  1. 词法 this 绑定
  2. this 无法使用 call 或者 apply 进行修改
  3. 词法 arguments 绑定

函数默认参数值

传入参数为 undefined 或者不传入参数时使用默认值,默认值可以引用前边的参数值

function foo(a = 1, b = 2, c = b, d = 4) {
  return a === 1 && b === 3 && c === 3 && d === 4
}

foo(undefined, 3) // true

// 默认值为一个 function
function bar(a = (x) => { return x }) {
  return a(1) === 1
}

bar() // true

多参数的简化

使用 ... 来声明剩下参数部分为一个数组

function foo(a, ...b) {
  return a === 1 && b[0] === 2 && b[1] === 3
}

foo.length // 1
foo(1, 2, 3) // true

... 操作符

可以使用 ... 来对数组或者字符串进行展开操作,使其变成 item1, item2 .. 的格式

let a = [1, 2, 3]

function foo(a, b, c) {
  return a === 1 && b === 2 && c === 3
}

foo(...a) // true

[0, ...a, 4][1] === 1 // true
[0, ...'hello'][1] === 'h' // true

对象字面量的语法增强

  • 属性名可以是一个表达式
  • 属性名可以直接沿用变量名
  • 函数的简写
let x = 'y'
let a = {
  [x]: 1,
  x,
  hello() {
    return 1
  },
  'hello world'() {
    return 2
  },
  [1 + x]() {
    return 3
  }
}
a.x === 'y' // true
a.y === 1 // true
a.hello() === 1 // true
a['hello world']() === 2 // true
a['1y']() === 3 // true

for..of 循环

使用 for..of 对实现了迭代接口的对象进行循环

let arr = [1, 2, 3]
let str = 'hello'
for (let item of arr) {
  console.log(item)
}

for(let char of str) {
  console.log(char)
}

八进制和二进制字面量

let a = 0o12
a === 10

let b = 0b10
b === 2

let c = Number('0b11')
c === 3

字符串模板

let a = 'hel', b = 'WORLD'
let temp = `${a + 'lo'}, ${b.toLowerCase()}`
console.log(temp) // hello, world

数组推导

可以从一个现有数组来推导出一个新的数组

var a1 = [1, 2, 3, 4]
var a2 = [for (i of a1) i * 2] // [2, 4, 6, 8]
a2[1] === 4 // true

解构赋值

数组

let [a, , [b], c] = [1, null, [2], 3]
a === 1 // true
b === 2 // true
c === 3 // true

字符串

let [a, b, c] = 'ab'
a === 'a' // true
b === 'b' // true
c === undefined // true

对象

let {x, a: y, z} = {
  x: 1,
  a: 2
}
x === 1 // true
y === 2 // true
z === undefined // true

可以使用解构来获取一些对象的方法

let {toFixed} = 2
let {slice} = ''

toFixed === Number.prototype.toFixed // true
slice === String.prototype.slice // true

和多个语法糖结合起来后还有很多应用场景

// for-of
for (let [key, value] of [[1, 2], [2, 3]]) {
  console.log(key, value)
}

// rest
let [a, ...b] = [1, 2, 3]
a === 1 // true
b[1] === 3 // true

// function params
function move({x = 1, y = 2} = {}) {
  return [x, y]
}

move()
move({x: 3, y: 8}) // [3, 8]

变量绑定

letconst

  • 定义块级作用域的变量
  • 定义常量
const a = 1
a === 1 // true

{
  let b = 2
  b === 2
}
// b is not defined

原有内置对象的扩展

对原有的扩展很多,这里只是讲了感觉可能比较有用的一部分

Object

  • is

    用于判断是否两个值是否相同

    Object.is(0, -0) // false
    Object.is([], []) // false
    Object.is(window, window) // false
  • assign

    用于扩展对象的属性,类似 jQuery.extend 方法

    let o1 = { a: 1 };
    let o2 = { b: 2 };
    let o3 = { c: 3 };
    
    let obj = Object.assign(o1, o2, o3); // { a: 1, b: 2, c: 3 }
    obj === o1 // true

Array

  • from

    用来从一个实现了迭代接口的对象来生成一个数组

    let m = new Set()
    m.add(1)
    m.add(2)
    let arr = Array.from(m, (item) => item + 1)
    console.log(arr)
  • of

    以传入的参数为元素返回一个数组,主要是为了弥补 Array 构造器的不足

Array.prototype

  • find

    用来从目标数组中找出符合条件的第一个元素,类似 lodash 中的 _.find(array, [identity], [thisArg])

    let arr = [1, 2, 3, 4]
    arr.find((x) => x >= 2) == 2 // true
  • findIndex

    类似 find 方法,差别就是这个是返回索引

    let arr = [1, 2, 3, 4]
    arr.findIndex((x) => x >= 2) == 1 // true
  • fill

    用于填充数组内容,类似 lodash 中的 _.fill(array, value, [start=0], [end=array.length])

    let arr = Array(3)
    arr.fill(1) // [1, 1, 1]
    arr[2] === 1
  • entries

    获取可以遍历数组的迭代器,常和 for...of 配合使用

    let arr = [1, 2, 3]
    for (let [index, item] of arr.entries()) {
      console.log(index, item)
    }

String.prototype

  • repeat

    重复字符串 n 次,类似 lodash 中的 _.repeat([string=''], [n=0])

    '*'.repeat(3) // '***'
  • startsWith

    判断字符串是否以某个字符串开头,类似 lodash 中的 _.startsWith([string=''], [target], [position=0])

    'hello world'.startsWith('world', 6) // true
  • endsWith

    判断字符串是否以某个字符串结束,类似 lodash 中的 _.endsWith([string=''], [target], [position=string.length])

  • includes

    判断字符串是否包括某个字符串,类似 lodash 中的 _.includes(collection, target, [fromIndex=0])

    'hello world'.includes('wor') // true

Number

这一部分主要用于进行数组的类型判断,方法名一看就懂,这里不做详细阐述。

  • isFinite
  • isNaN
  • isInteger

新增内置对象

Type Arrays

这个主要是提供了任意字节为基础的多种数据接口来更好地支持网络协议实现,加密算法,文件格式操作等,前端涉及的可能会少一点,这个不在这里做探讨(需要的话再另外深入了解下)。

Set & Map

两种方便操作的数据格式,Set 是元素不重复的集合,Map 是 key 不重复的集合,举两个简单的例子,这里也不做深入探讨:

Set 的简单使用:

let s = new Set()
let count = 0
s.add(1)
s.add(1)
s.add(2)
s.forEach((item) => {
  count++
  console.log(item)
})

count === 2 // true
s.has(1) // true

Map 的简单使用:

let m = new Map()
m.set('hello', 1)
m.set('world', 2)
m.get('hello') // 1

for (let [key, value] of m.entries()) {
  console.log(key, value)
}

Proxy

这个是极其强大的功能,可以创建代理对象,把相关对象的操作代理到自己设置的方法中,例如:

let tar = { foo: 'hello' }
let proxy = new Proxy(tar, {
  get (receiver, name) {
    return 'world'
  }
})
proxy.foo // 'world'
proxy.bar // 'world'

这是运行时级别对于对象的元编程操作,不过现有的类似 babel,traceur 都是没法支持的,这个需要从浏览器基础上去支持,所以离真正能够用上还有一段时间。

Promise

这个已经在广泛使用了,被认为是一个很好的实践方式,ES6 才将其纳入实现标准中。这里不再阐述 Promise 相关内容,如果有需要,再起文章来说明好了。

Symbol

一种新的原始数据类型,用于代表独一无二的 id,来防止对象属性或者方法名称的使用冲突。简单的使用:

let s = Symbol('symbol')
s === Symbol('symbol') // false
let obj = {
  [s]: 'hello world'
}
obj[s] === 'hello world' // true

Symbol.for 的话会从全局搜索标识,有则返回,没有才生成一个新的,而不是每次都是产生一个新的,和 Symbol 不一样。

Symbol.�keyFor 可以获取一个 symbol 变量的 key 标识。

let s = Symbol.for('symbol')
s === Symbol.for('symbol') // true
'symbol' === Symbol.keyFor(s) // true

注意,symbol 变量是无法和其他类型的值进行运算的,会抛出错误。

ES6 相关的内容很多,接纳了 js 发展历程中社区的很多实践和贡献,吸收了很多语言的优秀特性,随着 js 应用场景的扩展也添加了很多适应的特性,主要都是为了让 js 更好地成为一个企业级别的开发语言。

虽然说现在 ES6 没法直接投入到浏览器端的生产环境中,但是已经有 babel 等方案让我们可以更早地使用 ES6 的特性来进行开发,所以让我们现在就开始拥抱 ES6,拥抱 js 的美好未来。

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment