es6中文手册

  • 5

(回到目录)

Modules


ES6之前,浏览器端的模块化代码,我们使用像Browserify这样的库,

Node.js 中,我们则使用 require

在ES6中,我们现在可以直接使用AMD 和 CommonJS这些模块了。

Exporting in CommonJS

module.exports = 1; module.exports = { foo: 'bar' }; module.exports = ['foo', 'bar']; module.exports = function bar () {};

  • 1

  • 2

  • 3

  • 4

Exporting in ES6

在ES6中,提供了多种设置模块出口的方式,比如我们要导出一个变量,那么使用 变量名

export let name = 'David'; export let age = 25;​​

  • 1

  • 2

还可以为对象 导出一个列表

function sumTwo(a, b) { return a + b; } function sumThree(a, b, c) { return a + b + c; } export { sumTwo, sumThree };

  • 1

  • 2

  • 3

  • 4

  • 5

  • 6

  • 7

  • 8

  • 9

我们也可以使用简单的一个 export 关键字来导出一个结果值:

export function sumTwo(a, b) { return a + b; } export function sumThree(a, b, c) { return a + b + c; }

  • 1

  • 2

  • 3

  • 4

  • 5

  • 6

  • 7

最后,我们可以 导出一个默认出口

function sumTwo(a, b) { return a + b; } function sumThree(a, b, c) { return a + b + c; } let api = { sumTwo, sumThree }; export default api;

  • 1

  • 2

  • 3

  • 4

  • 5

  • 6

  • 7

  • 8

  • 9

  • 10

  • 11

  • 12

  • 13

  • 14

最佳实践:总是在模块的 最后 使用 export default 方法。

它让模块的出口更清晰明了,节省了阅读整个模块来寻找出口的时间。

更多的是,在大量CommonJS模块中,通用的习惯是设置一个出口值或者出口对象。

最受这个规则,可以让我们的代码更易读,且更方便的联合使用CommonJS和ES6模块。

Importing in ES6

ES6提供了好几种模块的导入方式。我们可以单独引入一个文件:

import 'underscore';

  • 1

这里需要注意的是, 整个文件的引入方式会执行该文件内的最上层代码

就像Python一样,我们还可以命名引用:

import { sumTwo, sumThree } from 'math/addition';

  • 1

我们甚至可以使用 as 给这些模块重命名:

import { sumTwo as addTwoNumbers, sumThree as sumThreeNumbers } from 'math/addition';

  • 1

  • 2

  • 3

  • 4

另外,我们能 引入所有的东西(原文:import all the things) (也称为命名空间引入)

import * as util from 'math/addition';

  • 1

最后,我们能可以从一个模块的众多值中引入一个列表:

import * as additionUtil from 'math/addtion'; const { sumTwo, sumThree } = additionUtil;

  • 1

  • 2

像这样引用默认对象:

import api from 'math/addition'; // Same as: import { default as api } from 'math/addition';

  • 1

  • 2

我们建议一个模块导出的值应该越简洁越好,不过有时候有必要的话命名引用和默认引用可以混着用。如果一个模块是这样导出的:

// foos.js export { foo as default, foo1, foo2 };

  • 1

  • 2

那我们可以如此导入这个模块的值:

import foo, { foo1, foo2 } from 'foos';

  • 1

我们还可以导入commonjs模块,例如React:

import React from 'react'; const { Component, PropTypes } = React;

  • 1

  • 2

更简化版本:

import React, { Component, PropTypes } from 'react';

  • 1

注意:被导出的值是被 绑定的(原文:bingdings),而不是引用。

所以,改变一个模块中的值的话,会影响其他引用本模块的代码,一定要避免此种改动发生。

(回到目录)

Parameters


在ES5中,许多种方法来处理函数的 参数默认值(default values)参数数量(indefinite arguments)参数命名(named parameters)

ES6中,我们可以使用非常简洁的语法来处理上面提到的集中情况。

Default Parameters

function addTwoNumbers(x, y) { x = x || 0; y = y || 0; return x + y; }

  • 1

  • 2

  • 3

  • 4

  • 5

ES6中,我们可以简单为函数参数启用默认值:

function addTwoNumbers(x=0, y=0) { return x + y; }

  • 1

  • 2

  • 3

addTwoNumbers(2, 4); // 6 addTwoNumbers(2); // 2 addTwoNumbers(); // 0

  • 1

  • 2

  • 3

Rest Parameters

ES5中,遇到参数数量不确定时,我们只能如此处理:

function logArguments() { for (var i=0; i < arguments.length; i++) { console.log(arguments[i]); } }

  • 1

  • 2

  • 3

  • 4

  • 5

使用 rest 操作符,我们可以给函数传入一个不确定数量的参数列表:

function logArguments(...args) { for (let arg of args) { console.log(arg); } }

  • 1

  • 2

  • 3

  • 4

  • 5

Named Parameters

命名函数

ES5中,当我们要处理多个 命名参数 时,通常会传入一个 选项对象 的方式,这种方式被jQuery采用。

function initializeCanvas(options) { var height = options.height || 600; var width = options.width || 400; var lineStroke = options.lineStroke || 'black'; }

  • 1

  • 2

  • 3

  • 4

  • 5

我们可以利用上面提到的新特性 解构 ,来完成与上面同样功能的函数:

We can achieve the same functionality using destructuring as a formal parameter

to a function:

function initializeCanvas( { height=600, width=400, lineStroke='black'}) { // ... } // Use variables height, width, lineStroke here

  • 1

  • 2

  • 3

  • 4

  • 5

如果我们需要把这个参数变为可选的,那么只要把该参数解构为一个空对象就好了:

function initializeCanvas( { height=600, width=400, lineStroke='black'} = {}) { // ... }

  • 1

  • 2

  • 3

  • 4

Spread Operator

我们可以利用展开操作符(Spread Operator)来把一组数组的值,当作参数传入:

Math.max(...[-1, 100, 9001, -32]); // 9001

  • 1

(回到目录)

Classes


在ES6以前,我们实现一个类的功能的话,需要首先创建一个构造函数,然后扩展这个函数的原型方法,就像这样:

function Person(name, age, gender) { this.name = name; this.age = age; this.gender = gender; } Person.prototype.incrementAge = function () { return this.age += 1; };

  • 1

  • 2

  • 3

  • 4

  • 5

  • 6

  • 7

  • 8

  • 9

继承父类的子类需要这样:

function Personal(name, age, gender, occupation, hobby) { Person.call(this, name, age, gender); this.occupation = occupation; this.hobby = hobby; } Personal.prototype = Object.create(Person.prototype); Personal.prototype.constructor = Personal; Personal.prototype.incrementAge = function () { return Person.prototype.incrementAge.call(this) += 20; };

  • 1

  • 2

  • 3

  • 4

  • 5

  • 6

  • 7

  • 8

  • 9

  • 10

  • 11

ES6提供了一些语法糖来实现上面的功能,我们可以直接创建一个类:

class Person { constructor(name, age, gender) { this.name = name; this.age = age; this.gender = gender; } incrementAge() { this.age += 1; } }

  • 1

  • 2

  • 3

  • 4

  • 5

  • 6

  • 7

  • 8

  • 9

  • 10

  • 11

继承父类的子类只要简单的使用 extends 关键字就可以了:

class Personal extends Person { constructor(name, age, gender, occupation, hobby) { super(name, age, gender); this.occupation = occupation; this.hobby = hobby; } incrementAge() { super.incrementAge(); this.age += 20; console.log(this.age); } }

  • 1

  • 2

  • 3

  • 4

  • 5

  • 6

  • 7

  • 8

  • 9

  • 10

  • 11

  • 12

  • 13

最佳实践:ES6新的类语法把我们从晦涩难懂的实现和原型操作中解救出来,这是个非常适合初学者的功能,而且能让我们写出更干净整洁的代码。

(回到目录)

Symbols


符号(Symbols)在ES6版本之前就已经存在了,但现在我们拥有一个公共的接口来直接使用它们。

Symbols对象是一旦创建就不可以被更改的(immutable)而且能被用做hash数据类型中的键。

Symbol( )

调用 Symbol() 或者 Symbol(描述文本) 会创建一个唯一的、在全局中不可以访问的符号对象。

一个 Symbol() 的应用场景是:在自己的项目中使用第三方代码库,且你需要给他们的对象或者命名空间打补丁代码,又不想改动或升级第三方原有代码的时候。

举个例子,如果你想给 React.Component 这个类添加一个 refreshComponent 方法,但又确定不了这个方法会不会在下个版本中加入,你可以这么做:

const refreshComponent = Symbol(); React.Component.prototype[refreshComponent] = () => { // do something }

  • 1

  • 2

  • 3

  • 4

  • 5

Symbol.for(key)

使用 Symbol.for(key) 也是会创建一个不可改变的Symbol对象,但区别于上面的创建方法,这个对象是在全局中可以被访问到的。

调用两次 Symbol.for(key) 会返回相同的Symbol实例。

提示:这并不同于 Symbol(description)

Symbol('foo') === Symbol('foo') // false Symbol.for('foo') === Symbol('foo') // false Symbol.for('foo') === Symbol.for('foo') // true

  • 1

  • 2

  • 3

一个Symbols常用的使用场景,是需要使用特别 Symbol.for(key) 方法来实现代码间的协作。

这能让你在你的代码中,查找包含已知的接口的第三方代码中Symbol成员。(译者:这句话好难翻。。。原文:This can be

achieved by having your code look for a Symbol member on object arguments from third parties that contain some known interface. )举个例子:

function reader(obj) { const specialRead = Symbol.for('specialRead'); if (obj[specialRead]) { const reader = obj[specialRead](); // do something with reader } else { throw new TypeError('object cannot be read'); } }

  • 1

  • 2

  • 3

  • 4

  • 5

  • 6

  • 7

  • 8

  • 9

之后在另一个库中:

const specialRead = Symbol.for('specialRead'); class SomeReadableType { [specialRead]() { const reader = createSomeReaderFrom(this); return reader; } }

  • 1

  • 2

  • 3

  • 4

  • 5

  • 6

  • 7

  • 8

注意Symbol.iterable 在ES6中像其他可枚举的对象,如数组,字符串,generators一样,当这个方法被调用时会激活一个枚举器并返回一个对象。

(回到目录)

Maps


Maps 是一个Javascript中很重要(迫切需要)的数据结构。

在ES6之前,我们创建一个 hash 通常是使用一个对象:

var map = new Object(); map[key1] = 'value1'; map[key2] = 'value2';

  • 1

  • 2

  • 3

但是,这样的代码无法避免函数被特别的属性名覆盖的意外情况:

> getOwnProperty({ hasOwnProperty: 'Hah, overwritten'}, 'Pwned'); > TypeError: Property 'hasOwnProperty' is not a function

  • 1

  • 2

Maps 让我们使用 setgetsearch 操作数据。

let map = new Map(); > map.set('name', 'david'); > map.get('name'); // david > map.has('name'); // true

  • 1

  • 2

  • 3

  • 4

Maps最强大的地方在于我们不必只能使用字符串来做key了,现在可以使用任何类型来当作key,而且key不会被强制类型转换为字符串。

let map = new Map([ ['name', 'david'], [true, 'false'], [1, 'one'], [{}, 'object'], [function () {}, 'function'] ]); for (let key of map.keys()) { console.log(typeof key); // > string, boolean, number, object, function }

  • 1

  • 2

  • 3

  • 4

  • 5

  • 6

  • 7

  • 8

  • 9

  • 10

  • 11

  • 12

提示:当使用 map.get() 判断值是否相等时,非基础类型比如一个函数或者对象,将不会正常工作。

有鉴于此,还是建议使用字符串,布尔和数字类型的数据类型。

我们还可以使用 .entries() 方法来遍历整个map对象:

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

  • 1

  • 2

  • 3

(回到目录)

WeakMaps


在ES5之前的版本,我们为了存储私有数据,有好几种方法。像使用这种下划线命名约定:

class Person { constructor(age) { this._age = age; } _incrementAge() { this._age += 1; } }

  • 1

  • 2

  • 3

  • 4

  • 5

  • 6

  • 7

  • 8

  • 9

在一个开源项目中,命名规则很难维持得一直很好,这样经常会造成一些困扰。

此时,我们可以选择使用WeakMaps来替代Maps来存储我们的数据:

let _age = new WeakMap(); class Person { constructor(age) { _age.set(this, age); } incrementAge() { let age = _age.get(this) + 1; _age.set(this, age); if (age > 50) { console.log('Midlife crisis'); } } }

  • 1

  • 2

  • 3

  • 4

  • 5

  • 6

  • 7

  • 8

  • 9

  • 10

  • 11

  • 12

  • 13

  • 14

使用WeakMaps来保存我们私有数据的理由之一是不会暴露出属性名,就像下面的例子中的 Reflect.ownKeys()

> const person = new Person(50); > person.incrementAge(); // 'Midlife crisis' > Reflect.ownKeys(person); // []

  • 1

  • 2

  • 3

一个使用WeakMaps存储数据更实际的例子,就是有关于一个DOM元素和对该DOM元素(有污染)地操作:

let map = new WeakMap(); let el = document.getElementById('someElement'); // Store a weak reference to the element with a key map.set(el, 'reference'); // Access the value of the element let value = map.get(el); // 'reference' // Remove the reference el.parentNode.removeChild(el); el = null; value = map.get(el); // undefined

  • 1

  • 2

  • 3

  • 4

  • 5

  • 6

  • 7

  • 8

  • 9

  • 10

  • 11

  • 12

  • 13

  • 14

上面的例子中,一个对象被垃圾回收期给销毁了,WeakMaps会自动的把自己内部所对应的键值对数据同时销毁。

提示:结合这个例子,再考虑下jQuery是如何实现缓存带有引用的DOM元素这个功能的,使用了WeakMaps的话,当被缓存的DOM元素被移除的时,jQuery可以自动释放相应元素的内存。

通常情况下,在涉及DOM元素存储和缓存的情况下,使用WeakMaps是非常适合的。

(回到目录)

Promises


Promises让我们让我们多缩进难看的代码(回调地狱):

func1(function (value1) { func2(value1, function (value2) { func3(value2, function (value3) { func4(value3, function (value4) { func5(value4, function (value5) { // Do something with value 5 }); }); }); }); });

  • 1

  • 2

  • 3

  • 4

  • 5

  • 6

  • 7

  • 8

  • 9

  • 10

  • 11

写成这样:

func1(value1) .then(func2) .then(func3) .then(func4) .then(func5, value5 => { // Do something with value 5 });

  • 1

  • 2

  • 3

  • 4

  • 5

  • 6

  • 7

在ES6之前,我们使用bluebird 或者

Q。现在我们有了原生版本的 Promises:

new Promise((resolve, reject) => reject(new Error('Failed to fulfill Promise'))) .catch(reason => console.log(reason));

  • 1

  • 2

  • 3

这里有两个处理函数,resolve(当Promise执行成功完毕时调用的回调函数) 和 reject (当Promise执行不接受时调用的回调函数)

Promises的好处:大量嵌套错误回调函数会使代码变得难以阅读理解。

使用了Promises,我们可以让我们代码变得更易读,组织起来更合理。

此外,Promise处理后的值,无论是解决还是拒绝的结果值,都是不可改变的。

下面是一些使用Promises的实际例子:

var fetchJSON = function(url) { return new Promise((resolve, reject) => { $.getJSON(url) .done((json) => resolve(json)) .fail((xhr, status, err) => reject(status + err.message)); }); };

  • 1

  • 2

  • 3

  • 4

  • 5

  • 6

  • 7

我们还可以使用 Promise.all() 来异步的 并行 处理一个数组的数据。

var urls = [ 'http://www.api.com/items/1234', 'http://www.api.com/items/4567' ]; var urlPromises = urls.map(fetchJSON); Promise.all(urlPromises) .then(function (results) { results.forEach(function (data) { }); }) .catch(function (err) { console.log('Failed: ', err); });

  • 1

  • 2

  • 3

  • 4

  • 5

  • 6

  • 7

  • 8

  • 9

  • 10

  • 11

  • 12

  • 13

  • 14

  • 15

(回到目录)

Generators


就像Promises如何让我们避免回调地狱一样,Generators也可以使我们的代码扁平化,同时给予我们开发者像开发同步代码一样的感觉来写异步代码。Generators本质上是一种支持的函数,随后返回表达式的值。

Generators实际上是支持暂停运行,随后根据上一步的返回值再继续运行的一种函数。

下面代码是一个使用generators函数的简单例子:

function* sillyGenerator() { yield 1; yield 2; yield 3; yield 4; } var generator = sillyGenerator(); > console.log(generator.next()); // { value: 1, done: false } > console.log(generator.next()); // { value: 2, done: false } > console.log(generator.next()); // { value: 3, done: false } > console.log(generator.next()); // { value: 4, done: false }

  • 1

  • 2

  • 3

  • 4

  • 5

  • 6

  • 7

  • 8

  • 9

  • 10

  • 11

  • 12

就像上面的例子,当next运行时,它会把我们的generator向前“推动”,同时执行新的表达式。

我们能利用Generators来像书写同步代码一样书写异步代码。

// Hiding asynchronousity with Generators function request(url) { getJSON(url, function(response) { generator.next(response); }); }

  • 1

  • 2

  • 3

  • 4

  • 5

  • 6

  • 7

这里我们写个generator函数将要返回我们的数据:

function* getData() { var entry1 = yield request('http://some_api/item1'); var data1 = JSON.parse(entry1); var entry2 = yield request('http://some_api/item2'); var data2 = JSON.parse(entry2); }

  • 1

  • 2

  • 3

  • 4

  • 5

  • 6

借助于 yield,我们可以保证 entry1 确实拿到数据并转换后再赋值给 data1

当我们使用generators来像书写同步代码一样书写我们的异步代码逻辑时,没有一种清晰简单的方式来处理期间可能会产生的错误或者异常。在这种情况下,我们可以在我们的generator中引入Promises来处理,就像下面这样:

function request(url) { return new Promise((resolve, reject) => { getJSON(url, resolve); }); }

  • 1

  • 2

  • 3

  • 4

  • 5

我们再写一个函数,其中使用 next 来步进我们的generator的同事,再利用我们上面的 request 方法来产生(yield)一个Promise。

function iterateGenerator(gen) { var generator = gen(); var ret; (function iterate(val) { ret = generator.next(); if(!ret.done) { ret.value.then(iterate); } })(); }

  • 1

  • 2

  • 3

  • 4

  • 5

  • 6

  • 7

  • 8

  • 9

  • 10

在Generator中引入了Promises后,我们就可以通过Promise的 .catchreject 来捕捉和处理错误了。

使用了我们新版的Generator后,新版的调用就像老版本一样简单可读(译者注:有微调):

iterateGenerator(function* getData() { var entry1 = yield request('http://some_api/item1'); var data1 = JSON.parse(entry1); var entry2 = yield request('http://some_api/item2'); var data2 = JSON.parse(entry2); });

  • 1

  • 2

  • 3

  • 4

  • 5

  • 6

自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。

深知大多数初中级Android工程师,想要提升技能,往往是自己摸索成长或者是报班学习,但对于培训机构动则近万的学费,着实压力不小。自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!

因此收集整理了一份《2024年Android移动开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。

img

img

img

img

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Android开发知识点,真正体系化!

由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且会持续更新!

如果你觉得这些内容对你有帮助,可以扫码获取!!(备注:Android)

最后

给大家分享一份移动架构大纲,包含了移动架构师需要掌握的所有的技术体系,大家可以对比一下自己不足或者欠缺的地方有方向的去学习提升;

《互联网大厂面试真题解析、进阶开发核心学习笔记、全套讲解视频、实战项目源码讲义》点击传送门即可获取!

  • 1

  • 2

  • 3

  • 4

  • 5

我们再写一个函数,其中使用 next 来步进我们的generator的同事,再利用我们上面的 request 方法来产生(yield)一个Promise。

function iterateGenerator(gen) { var generator = gen(); var ret; (function iterate(val) { ret = generator.next(); if(!ret.done) { ret.value.then(iterate); } })(); }

  • 1

  • 2

  • 3

  • 4

  • 5

  • 6

  • 7

  • 8

  • 9

  • 10

在Generator中引入了Promises后,我们就可以通过Promise的 .catchreject 来捕捉和处理错误了。

使用了我们新版的Generator后,新版的调用就像老版本一样简单可读(译者注:有微调):

iterateGenerator(function* getData() { var entry1 = yield request('http://some_api/item1'); var data1 = JSON.parse(entry1); var entry2 = yield request('http://some_api/item2'); var data2 = JSON.parse(entry2); });

  • 1

  • 2

  • 3

  • 4

  • 5

  • 6

自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。

深知大多数初中级Android工程师,想要提升技能,往往是自己摸索成长或者是报班学习,但对于培训机构动则近万的学费,着实压力不小。自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!

因此收集整理了一份《2024年Android移动开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。

[外链图片转存中…(img-2KrWFq2h-1712613552242)]

[外链图片转存中…(img-q6y7YKlR-1712613552242)]

[外链图片转存中…(img-b26xNcMU-1712613552243)]

[外链图片转存中…(img-j1Lismi4-1712613552243)]

[外链图片转存中…(img-jxKetudQ-1712613552243)]

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Android开发知识点,真正体系化!

由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且会持续更新!

如果你觉得这些内容对你有帮助,可以扫码获取!!(备注:Android)

最后

给大家分享一份移动架构大纲,包含了移动架构师需要掌握的所有的技术体系,大家可以对比一下自己不足或者欠缺的地方有方向的去学习提升;

[外链图片转存中…(img-KbXCLjz1-1712613552244)]

《互联网大厂面试真题解析、进阶开发核心学习笔记、全套讲解视频、实战项目源码讲义》点击传送门即可获取!

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
曾经听许多前端从业者说:“前端发展太快了。”这里的快,十有八九是说层出不穷的新概念,余下的一二,大抵只是抒发一下心中的苦闷罢——前两日刚习得的新技术转眼就“落后”——仔细品味这苦闷,除却不得不持续奔跑的无奈,更多的是一口气,一口卯足了劲儿也要把新知识全数揽入囊中的不服气。作为刚入行的新人,对这点体会颇深。就像是蓦地从某个时间点切入,半数时间向前走,半数时间向后看,瞻前顾后,回味揣摩这十年间的岁月精魄,还得翘首盼着花花新世界,不时再问自己一句,这样走下去真的会好么?是的,其实答案人尽皆知,同时也无人知晓,因为没人能预言未来,顶多只能预测未来,但有一件事情永不会错,当你笃定地沿着一条路走下去,结果通常不会太糟糕,但凡能在浮躁的社会冷静下来潜心磨砺,多少总会有收获。幸而我有意弱化了对新信息的执念,开始做一些事情,《深入浅出ES6》就是其中一件。 纵观整个系列,亦即纵观ECMAScript 2015的整个体系,吸取了诸多成功经验:借鉴自CoffeeScript的箭头函数;始于C++项目Xanadu,接着被E语言采用,后来分别于Python和JavaScript框架Dojo中以Deferred对象的面貌出现的Promise规范(详见Async JavaScript一书3.1章);借鉴了C++、Java、C#以及Python等语言的for-of循环语句;部分借鉴Mustache、Nunjucks的模板字符串。 当然,新的语言体系也在之前的基础上查漏补缺:弥补块级作用域变量缺失的let和const关键字;弥补面向大型项目缺失的模块方案;标准委员会甚至为JavaScript增加了类特性,有关这一方面的特性褒贬不一,Douglas Crockford曾在2014年的Nordic.js大会发表了题为《The Better Parts》的演讲,重新阐述了他个人对于ECMAScript 6的看法,他认为Class特性是所有新标准中最糟糕的创新(我个人也略赞同这一说法,类的加入虽然有助于其它语言的使用者开始使用JavaScript,但是却无法发挥出JavaScript原型继承的巨大优势);以及为了保持非侵入式弥补其它新特性而诞生的Symbols。 其它的新特性也相当诱人,熟练掌握可以大幅度提升开发效率:迭代器Iterator、生成器Generators、不定参数Rest、默认参数Default、解构Destructuring、生成器Generator、代理Proxy,以及几种新类型:Set、Map、WeakSet、WeakMap、集合Collection。 以上提及的新特性只是其中的一部分,更多的新特性等待着大家进一步挖掘。整个系列的翻译历时150余天,坚持专栏翻译的日子艰苦也快乐,编辑徐川细心地帮我审校每一篇文章,编辑丁晓昀赠予钱歌川先生详解翻译之著作让我大开眼界,与李松峰老师的交流也让我深刻理解了“阅读、转换、表达”的奥义所在,最感谢我的母亲,在我遇到困难需要力量的时候永远支持着我。选择ES6作为前端生涯的切入点实之我幸,恰遇这样的机会让我可以一心一意地向前走,向未来走。我很敬佩在“洪荒”和“战乱”年代沉淀无数经 验的前辈们,你们在各种不确定的因素中左右互搏,为终端用户提供统一的用户体验,直到如今你们依然孜孜不倦地吸取业内新鲜的经验。技术在进步,也为前端人 提供着无限的可能性,我们有责任也有义务去推动新标准的发展和普及,诚然在商业的大环境下我们不愿放弃每一寸用户的土壤,但携众人之力定将能推动用户终端 的革新。ES7标准的提案纷纷提上日程,用不了多久也将登上前端大舞台。也感谢午川同学友情提供译文《深入浅出ES6(十):集合 Collection》,让我在困难时期得以顺利过渡。最后祝愿国内前端社区向着更光明美好的未来蓬勃生长!
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值