资讯专栏INFORMATION COLUMN

一些小技巧让JS代码更优雅

王岩威 / 2410人阅读

摘要:近期看了好多函数式编程以及设计模式的书和文章,于是想分享一些让代码更优雅的小技巧。事实上,不仅是数学运算,任何函数式的方法都有可缓存性,这是函数式编程的一个明显的优点解构嵌套数组这个方法和结合十分有用处。

今天翻了翻一年多前写的代码,感觉当年年轻的自己写下的代码真是图样啊(然而现在也没好到哪里去 /w)。近期看了好多函数式编程以及设计模式的书和文章,于是想分享一些让JS代码更优雅的小技巧。

一、善用函数式编程

假设我们有这样的需求,需要先把数组foo中的对象结构更改,然后从中挑选出一些符合条件的对象,并且把这些对象放进新数组result里。

var foo = [{
    name: "Stark",
    age: 21
},{
    name: "Jarvis",
    age: 20
},{
    name: "Pepper",
    age: 16
}]

//我们希望得到结构稍微不同,age大于16的对象:
var result = [{
    person: {
        name: "Stark",
        age: 21
    },
    friends: []
},{
    person: {
        name: "Jarvis",
        age: 20
    },
    friends: []
}]

从直觉上我们很容易写出这样的代码:

var result = [];

//有时甚至是普通的for循环
foo.forEach(function(person){
    if(person.age > 16){
        var newItem = {
            person: person,
            friends: [];
        };
        result.push(newItem);
    }
})

然而用函数式的写法,代码可以优雅得多:

var result = foo
    .filter(person => person.age > 16)
    .map(person => ({
        person: person,
        friends: []
    }))

还有比如在各种文章里说烂了的数组求和:

var foo = [1, 2, 3, 4, 5];

//不优雅
function sum(arr){
    var x = 0;
    for(var i = 0; i < arr.length; i++){
        x += arr[i];
    }
    return x;
}
sum(foo) //15

//优雅
foo.reduce((a, b) => a + b) //15

这些只是很简单的例子,更多关于函数式编程的知识,可以参考这里:

JS函数式编程指南 - GitBook

二、lodash里一些很好用的东西

lodash是一个著名的JS工具库,里面存在众多函数式的方法和接口,在项目中引入可以简化很多冗余的逻辑。

lodash中文文档

1、_.flow解决函数嵌套过深
//很难看的嵌套
a(b(c(d(...args))));

//可以这样改善
_.flowRight(a,b,c,d)(...args)

//或者
_.flow(d,c,b,a)(...args)
2、_.memoize加速数学计算

在写一些Canvas游戏或者其他WebGL应用的时候,经常有大量的数学运算,例如:

Math.sin(1)

Math.sin()的性能比较差,如果我们对精度要求不是太高,我们可以使用_.memoize做一层缓存

var Sin = _.memoize(function(x){
    return Math.sin(x);
})
Sin(1) //第一次使用速度比较慢
Sin(1) //第二次使用有了cache,速度极快

注意此处传入的x最好是整数或者较短的小数,否则memoize会极其占用内存。

事实上,不仅是数学运算,任何函数式的方法都有可缓存性,这是函数式编程的一个明显的优点

3、_.flatten解构嵌套数组
_.flatten([1, 2], [3, 4]); // => [1, 2, 3, 4]

这个方法和Promise.all结合十分有用处。

假设我们爬虫程序有个getFansList方法,它可以根据传入的值x,异步从粉丝列表中获取第 x*20 到 (x+1)*20 个粉丝,现在我们希望获得前1000个粉丝:

var works = [];
for (var i = 0; i < 50; i++) {
    works.push(getFansList(i))
}
Promise.all(works)
    .then(ArrayOfFansList=> _.flatten(ArrayOfFansList))
    .then(result => console.log(result))

前段时间写的知乎关系网爬虫中就能看到类似的写法

4、_.once配合单例模式

有些函数会产生一个弹出框/遮罩层,或者负责app的初始化,因此这个函数是执行且只执行一次的。这就是所谓的单例模式,_.once大大简化了我们的工作量

var initialize = _.once(createApplication);
initialize();
initialize();
// 这里实际上只执行了一次 initialize
// 不使用 once 的话需要自己手写一个闭包
三、Generator + Promise改善异步流程

有时我们遇到这样的情况:

getSomethingAsync()
    .then( a => method1(a) )
    .then( b => method2(b) )
    .then( c => method3(a,b,c) ) //a和b在这里是undefined!!!

只用 Promise 的话,解决方法只有把 a、b 一层层 return 下去,或者声明外部变量,把a、b放到 Promise 链的外部。但无论如何,代码都会变得很难看。

用 Generator 可以大大改善这种情况(这里使用了Generator的执行器co):

import co from "co";

function* foo(){
    var a = yield getSomethingAsync();
    var b = yield method1(a);
    var c = yield method2(b);
    var result = yield method3(a,b,c);
    console.log(result);
}

co(foo());

当然,Generate 的用处远不止如此,在异步递归中它能发挥更大的用处。比如我们现在需要搜索一颗二叉树中value为100的节点,而这颗二叉树的取值方法是异步的(比如它在某个数据库中)

import co from "co";

function* searchBinaryTree(node, value){
    var nowValue = yield node.value();
    if(nowValue == value){
        return node;
    }else if(nowValue < value){
        var rightNode = yield node.getRightNode()
        return searchBinaryTree(rightNode, value);
    }else if(nowValue > value){
        var leftNode = yield node.getLeftNode()
        return searchBinaryTree(leftNode, value);
    }
}

co(searchBinaryTree(rootNode, 100))

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/79122.html

相关文章

  • CSS 黑魔法技巧你少写不必要的JS代码优雅

    摘要:利用用和来做表单即时校验需求让表单检验变得简单优雅,不需要写冗长的代码来校验设置样式丰富了表单元素,提供了类似等表单元素属性。不知细叶谁裁出,二月春风似剪刀。首先,你需要先了解一下渐变的使用技巧。 之前不久,由于自己平时涉猎还算广泛,总结了一篇博客:这些JavaScript编程黑科技,装逼指南,高逼格代码,让你惊叹不已,没想到受到了大家的欢迎,有人希望能博主还能整理个 CSS 的一些黑...

    Berwin 评论0 收藏0
  • CSS 黑魔法技巧你少写不必要的JS代码优雅

    摘要:利用用和来做表单即时校验需求让表单检验变得简单优雅,不需要写冗长的代码来校验设置样式丰富了表单元素,提供了类似等表单元素属性。不知细叶谁裁出,二月春风似剪刀。首先,你需要先了解一下渐变的使用技巧。 之前不久,由于自己平时涉猎还算广泛,总结了一篇博客:这些JavaScript编程黑科技,装逼指南,高逼格代码,让你惊叹不已,没想到受到了大家的欢迎,有人希望能博主还能整理个 CSS 的一些黑...

    MASAILA 评论0 收藏0
  • CSS 黑魔法技巧你少写不必要的JS代码优雅

    摘要:利用用和来做表单即时校验需求让表单检验变得简单优雅,不需要写冗长的代码来校验设置样式丰富了表单元素,提供了类似等表单元素属性。不知细叶谁裁出,二月春风似剪刀。首先,你需要先了解一下渐变的使用技巧。 之前不久,由于自己平时涉猎还算广泛,总结了一篇博客:这些JavaScript编程黑科技,装逼指南,高逼格代码,让你惊叹不已,没想到受到了大家的欢迎,有人希望能博主还能整理个 CSS 的一些黑...

    Zoom 评论0 收藏0
  • CSS 黑魔法技巧你少写不必要的JS代码优雅

    摘要:利用用和来做表单即时校验需求让表单检验变得简单优雅,不需要写冗长的代码来校验设置样式丰富了表单元素,提供了类似等表单元素属性。不知细叶谁裁出,二月春风似剪刀。首先,你需要先了解一下渐变的使用技巧。 之前不久,由于自己平时涉猎还算广泛,总结了一篇博客:这些JavaScript编程黑科技,装逼指南,高逼格代码,让你惊叹不已,没想到受到了大家的欢迎,有人希望能博主还能整理个 CSS 的一些黑...

    qqlcbb 评论0 收藏0
  • JS实用技巧】优化动态创建元素的方式,代码优雅且利于维护

    摘要:更好的方案模板分离原则模板分离原则将定义模板的那一部分,与的代码逻辑分离开来,让代码更加优雅且利于维护。 showImg(https://segmentfault.com/img/bVJ73t?w=800&h=316); 引言 在前端开发中,经常需要动态添加一些元素到页面上。那么如何通过一些技巧,优化动态创建页面元素的方式,使得代码更加优雅,并且更易于维护呢?接下来我们通过研究一些实例...

    JeOam 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<