看iOS的 Node.js 进阶之路 之 ECMAScript(ES6) 篇
@author Jou Email Weibo or Github
又有点时间,聊聊天。先丢出来几篇有意思的文章。
About Objc.
- Clang Attributes 黑魔法小记
About Swift.
- Protocol-Oriented Views in Swift
About Tools.
- Core animator 帮助你制作关键帧动画。
从 React Native 到 JSPatch, 我真真切切的感觉到 JS 是一门足够全栈的语言。
Node.JS 不单单可以帮助我们在鄙视链或技能树上走的更远, 也可以帮助我们写出更好的 RN 和 JSPatch 代码, 开拓新的心里安全区。 而且 Node.JS 它真的是足够简单,简单到可以分分钟上手。
相比其他发展,移动端还足够稚嫩,以至于我们常常需要借鉴不同的知识帮助我们完成最佳实践的过度。
这些最佳实践的参考包括从 Haskell 到 Swift, 抑或 从前后端 gem pip maven npm 三方依赖解耦到 Cocoapods or 分布式的 Carthage。
或者如果你还不知道eTag, 那么这些方面的探究就更加必要。
ECMAScript vs. Javascript
Javascript实际上是ECMAScript-262标准的实现和扩展。
Javascript 通行版本,包括这三部分
- ECMAScript
- DOM (Document Object Model)
- BOM (Browser Object Model)
DOM & BOM
一张图看懂,DOM 与 BOM
ECMAScript
ECMAScript History, ECMAScript 的黑历史。
.1998.Y ECMAScript 2.0 发布。 1999.Y ECMAScript 3.0 版本发布,继而成为JavaScript的通行标准。
而后,.2007.Y 由于 ECMAScript 4.0 版本改动过于激进 or 过于前瞻,引发分歧.
时间到了 .2008.Y 3.0 吸纳了小部分改善,成为了日后的 ECMAScript 3.1, 后更名成 ECMAScript 5.0。 原 4.0 开始使用代号 "Harmony".
.1999.Y ECMAScript 5.0版正式发布. Harmony项目则一分为二,一些较为可行的设想定名为
JavaScript.next继续演变,成为了现在的 ECMAScript 6.
.2000. ECMAScript 6发布正式版本,即 令人激动人心的ECMAScript 2015.
Brendan Eich (inventor of JavaScript) 主要方向和兴趣是函数式编程, 所以,ECMAScript 在很多方面,都像在帮助这门语言,更好的支持函数式编程。
查看 node 版本对Hamony的支持情况,可以通过命令:
node --v8-options | grep harmony
或者通过更符合人类能读懂的方式,通过 npm 安装 es-checker,查看本机 node 对Hamony的支持。
输出结果是基于 node v6.2.0
$ npm install -g es-checker
$ es-checker
=========================================
Passes 36 feature Dectations
Your runtime supports 83% of ECMAScript 6
=========================================
如何用 node 暂时不支持的 ES 6 特性呢?!
可以使用 (Babel)[https://babeljs.io/]。帮助我们做 es 6 到 es 5 语法的转换。
同时,npm run 也有很多有趣的玩法, 有关 Babel or npm run很可能会放到下一篇。
ECMAScript 6
打算系统研讨ECMAScript 6的小伙伴可以参考(ECMAScript 6)[http://es6.ruanyifeng.com/#README], 作者是便是无处不在的 阮一峰。
在了解 ES 6 之前, 先解释下 ES 5 的标记 'use strict'
'use strict'
很多情况下, 第一行都有标记'use strict', 在初学的过程中,由于学习曲线陡峭,我们很有可能忽略他。
'use strict', 会要求JS的解释更严格,帮助我们,开发更符合预期的,更合理、更安全、更严谨的代码,消除很多不可预期的行为。
例如代码
PS 在 ES6 中,默认便是 'use strict', 这也便是为什么 react-native init 出来的项目工程,在index.js里没有这行代码。
i = 1; // error,i未声明
窥视 ECMAScript 6 新特性
如果你像我一样在使用Atom, 强烈建议安装package 'es6-javascript'。
Code 片段,我都尽量保证了核心特性的同时又不显得冗余。打算深入研究的,再次推荐ECMAScript 6这篇文章。
0x0. 新增 let, const, let 但不同于 swift
身为 iOS 专业搬砖员, 我们都知道 swift 引入了 let,用于声明不可变的变量。
ES 6 中 let 同样是变量, 但增加了块内有效的限制,所以在 ES 6 中,在全局, 函数的基础上,新增了块作用域。
const 就尤为明显了, 用于常量声明。
{
let a = 10;
var b = 1;
}
a // ReferenceError: a is not defined.
b // 1
const PI = 3.1415;
PI = 3; // 常规模式时,重新赋值无效,但不报错
PI // 3.1415
0x1. 全局变量
node.js 中全局变量
global.num = 1;
0x2. 数组的模式匹配赋值
//普通模式匹配
let [head,tail] = [1, 2, 3, 4];
//head 1 tail 2
//复杂一点的模式匹配
let [head, ...tail] = [1, 2, 3, 4];
//head 1
//tail [2,3,4] ...将按数组模式匹配
//再复杂一点的模式匹配
let [head,[mid], ...tail] = [1,[2, 3], 4];
//head 1
//mid 2
//tail [4]
0x3. 对象的模式匹配赋值
let { bar:foo } = { foo: "aaa", bar: "bbb" };
所以此刻 bar,foo 是什么呢?!
log:
foo 'bbb'
bar //not define
你们感受下。
0x4. 新增字符串索引方法
includes(), startsWith(), endsWith().
含义很清晰,所以很好理解,顺手与 iOS 中的消息做下对比。
- includes -> rangof:
- startsWith -> hasPrefix:
- endsWith - > hasSuffix:
let rlt = 'apple'.includes('a')
0x5. 模板字符串
注意这里模板字符串这里是反引号(`)。
let count = 1;
let money = 100;
let content =
`
There are ${count} items
in your basket, ${money}
are on sale!
`
0x6. 声明对象更简洁
let gender = 'male';
let cat = {
name: '雪球',
gender,
//等同于 ES5 gender: gender
desc() { return `我有个宠物叫, ${this.name}`; }
// 等同于 ES5 desc: function ()...
};
0x7. Class 语法糖
- ES5 对象声明
let cat = {
name: '雪球',
gender: 'male'
}
简单直接, 但问题有:
- 缺少结构化特性,声明多个比较困难
- 缺少类型判断
演进: 构造函数声明:
function Cat(name,color){
this.name = name;
this.color = color;
this.type = "猫科动物";
this.eat = function(){alert("吃老鼠");};
}
- ES6
class Cat {
constructor(name,gender) {
this.name = name;
this.gender = gender;
}
}
0x8. 元编程
元编程,即对编程语言进行编程。ES6 中 Proxy,可以帮助我们切入编程语言的某些环节,做拦截处理。
var animal = new Proxy({}, {
set: function (target, key, value, receiver) {
console.log(`setting ${key}!`);
return Reflect.set(target, key, value, receiver);
}
});
animal.name = 'animal';
// setting name!
所以我们可以使用这种方式,切入很多环节。
0x9. Promise
其实CommonJS规范就包括Promise规范,Promise完全改变了js异步编程的写法,让异步编程变得十
分的易于理解。然后 ES6 令人激动的加入了 Promise
So what is Promise ?
其实 Promise 解决的问题并不局限于 JS 语言,Promise 解决了一种长久以来诟病很多的异步处理方式,并提出了优秀的解决方案,
在异步处理中, 我们常会使用回调函数(匿名函数,抑或,闭包), 形成一种金字塔似的代码, 比如:
Parse.User.logIn("user","pass", {
success:function(user) {
query.find({
success:function(results) {
results[0].save({ key: value }, {
success:function(result) {
// the object was saved.
}
});
}
});
}
});
使用 Promise 解决方案 后的 样子:
Parse.User.logIn("user","pass").then(function(user) {
return query.find(); // find user
}).then(function(results) {
return results[0].save({ key: value }); // save object
}).then(function(result) {
// the object was saved.
});
使用函数编程,链式调用后的异步处理流程,变得异常清晰。扁平化后的金子塔结构瞬间清爽了。
其实 Promise 使用上非常简单,
首先, Promise 有三种状态:
- Pending(进行中)
- Resolved(已完成)
- Rejected(已失败)
then 方法返回一个新的 promise 实例,所以可以链式调用。
let promise = new Promise(function(resolve, reject) {
let cat = new Cat('雪球','male');
console.log('Promise');
resolve(cat);
});
promise.then(function(cat) {
console.log('Resolved.'+ cat.name);
return cat.name;
}).then(function(name) {
console.log(name);
});
Promise.resolve() 帮助我们普通实例 到 promise 实例的转换。
PS objc, swift 有相关 Promise 实现。 感兴趣,可以探索相关实践。
后言
希望多多反馈,多多交流。
还在酝酿中的下一篇 : Node.js Rock Rock 进阶之路 之 RESTFul API 搭建 Express 篇