大家都觉得 ES6 带来这么多新功能,让人很兴奋。
同样让人兴奋的是,在 ES6 之后,JS 将保持一年一次的迭代频率,这使得 JS 能紧跟时代,保持充沛的生命力。
JS 的迭代方式是“提案制”,即谁都可向 Ecma TC39 提出迭代方案,方案过了初审后,便要走 stage0 ~ stage4 的流程,stage4 表示提案确定被采纳,但提案走到 stage2 基本就确定会被采纳。如开发中常用的 stage3 的 import() ,stage2 的 Decorator 等等。
下面介绍几个虽处于 stage1,但很棒的提案。
PS: 其实这些功能,原生JS 和 Lodash 都能实现...
那么,既然都能实现了,为啥新版本还有加入这些功能?
嗯,这是个好问题...
先说实现了 函数式编程 中 柯里化 和 compose 的两个功能:
1. partial-application - 柯里化,亦可叫 偏函数
例如,我们分别用 原生JS,Lodash 和 partial-application 实现将 add(a, b) 柯里化为 addTen(n):
function add(a, b) {
return a + b;
}
// 原生JS:
const addTen = add.bind(null, 10);
// Ladash:
const addTen = _.curry(add)(10);
// partial-application:
const addTen = add(10, ?);
// 或者
const addTen = add(?, 10);
上面三者,都实现了柯里化的效果,但细微之处还是有区别:
- 原生JS通过 bind() ,但这与 bind 的主要用途不符,降低了代码的可读性。
- Lodash 用 _.curry() 有不错的可读性,但也需要对闭包有一定的了解才能熟练地使用。
- partial-application 极大简洁了实现的代码,并且并不止于柯里化中必须将参数从左至右一个个“reduce”的形式,甚至开发者都不需懂得柯里化的概念,便能很好地使用该功能。
2. pipeline-operator - compose,亦 node 中的 Stream
开发中,我们经常会遇到,某一数据,要将其依次经几个函数处理。
如我们要将 "hello" 经下面三个函数处理后,输出 "Hello, hello!":
function doubleSay (str) {
return str + ", " + str;
}
function capitalize (str) {
return str[0].toUpperCase() + str.substring(1);
}
function exclaim (str) {
return str + '!';
}
我们分别用 原生JS,Lodash 和 pipeline-operator 实现看看:
// 原生JS:
exclaim(capitalize(doubleSay("hello"))); //"Hello, hello!"
// Lodash:
_.flow([
doubleSay
capitalize
exclaim
])("hello"); //"Hello, hello!"
// pipeline-operator:
const result = "hello"
|> doubleSay
|> capitalize
|> exclaim;
console.log(result); // "Hello, hello!"
如上,三者都能实现 compose 的效果,而三者的表现形式还是如上面实现 柯里化 很接近:
- 原生JS 都写法,可读性差。
- Lodash 用 _.flow() 有不错的可读性,也还是运用了闭包。
- pipeline-operator 最大程度简洁了代码。
3. optional-chaining - 链式引用
当我们深层引用一对象都属性时,往往每层都引用都需做 undefined 判断,以防止 undefined.xxx 报错。 特别是在使用 ajax 传来的 json 时,更是要小心翼翼,因为 ajax 的数据会有各种不确定性。
所以,在 原生JS 中,我们经常会这样写:
var house = user.address && user.address.street && user.address.street.house;
使用了 lodash 的 _.get() 我们可以这样写:
var house = _.get(user, 'address.street.house')
而有了 optional-chaining 我们可以这样写:
var house = user.address?.street?.house;
以上,就是 stage1 中很酷的几个提案。
从中可以看出,除了扩展 JS 的能力,JS 还在朝使用更简单、可读性更好、增强函数式编程的能力、引入更多的设计模式等方向发展。
回到最开始的问题,既然用 hack 或 Lodash 能实现的功能,为啥 JS 还要加入这些功能?
我觉得让 JS 更简单易用的目的不言自明。
更重要的是 hack 技巧或 Lodash 很多开发人员并不会掌握的很好,而这些功能又是这么的有价值。
将这些功能集成进 JS 后,能更好的推广这些有价值的功能,进而提升 JS 世界的整体能力。
从宏观角度看,这种价值是巨大的。
网友评论