2018-07-13 简化函数(顺便玩一玩回调函数)

其实说起来不让写工作总结,但是实际上这还是一篇工作总结。。。。

ok!切入正题,我们来讨论一下如何简化代码,其实这也都是最近在实际开发时的体会,而且本身我不是很擅长这一点。但是最近因为写的代码逻辑略微繁复,而且本身需要兼容的情况比较多,加上繁复的现实条件(比如编译环境,比如设备性能,比如运行平台等等)的干扰,导致很多时候展示出来效果不是很好,所以就在本来逻辑较为复杂的代码上又添加了许多判断状态的代码,这就让代码的可读性,可维护性,健壮性都下降了很多,代码的耦合度直线上升,当具体的逻辑和实际的需求有任何一点点的变化,就会产生多米诺骨牌效果,不但改的时候很难理清添加了多层嵌套与判断的代码,在修改之后还可能牵连另外的功能产生意想不到的变化。所以,为了不让同志们屌我,我还是对代码进行了一定程度上的改造。

其实感觉上面还是在说废话。。。。当然啦,简单阐述一下博客的灵感来源嘛!~

其实很久以前看过类似的文章,专门介绍了很多提高代码可读性以及运行速度的方法,具体的文章题目与链接我忘记了,应该可以搜索“如何简化代码”找到。文章中的主要思想大致就是分离,合并:将该分离的一些变量,不需要强行的使用一个变量将内容统一,该添加变量的时候就添加新的变量;而合并就是将能统一判断的内容提升到高层,而不需要逐个写在每一个判断体或者循环体中,这样既能简化函数,又可以提升运行速度。

我也是以这样的思想为核心进行重构代码的,结合实际情况,主要有以下几点想法吧:

1. if判断体不要写的太长。if写多长其实本身并不影响逻辑,但是却很影响可读性。if本身是添加嵌套的,当写的很长了之后,会出现很现实的问题--------找不到else if与else的对应。当在if内部再嵌套了if之后,写的时候或许还比较清楚,但是当写完之后需要读或者改的时候,在看到一长串的if之后突然出来一个else,当然会产生这个else究竟对应谁的疑问吧!

2. 不要怕繁琐,多声明函数。上面说了,if不能写太长,那么如果if的逻辑真的很多那么该怎么办呢?

      首先,你应该确定,if的逻辑真的很多,很多的逻辑其实是可以提升到判断体之外去做的,比如在不同的判断内容后,都需要将某一个计数器+1,那么这个计数器当然就可以放在判断的外面整体去做,而不是放在内部一个一个去做。这一步检查需要仔细一些,因为很多内容可能在编码的过程中写在了判断体的中间部位,而实际上有一些声明或者值的改变完全是可以放在开头和结尾的,这些都可以从判断体中提出。

    其次就是要抽离函数了,这一步最简单粗暴的方法就是将函数体的内容复制粘贴,放到声明的另一个额外的函数之中。这一步在初学者看来可能有一些多此一举,但是在实际开发过程中,基于工程化,模块化的要求,这样写代码可以很直观的了解到哪一部分功能是什么,也提升了代码的可读性,在修改代码的时候也可以很明确的根据bug的表现定位到具体相关的位置。

    最后一步,我们要再次确定,这些冗长的逻辑真的是必须的。这一部分是什么意思呢?因为在两个不同的判断体之中,我们往往判断的只是一个或者两个不同的条件,而需要调整的变量,对象,属性等等一般都是同一种或者同一类,在整理逻辑之后我们经常可以发现,调整的内容完全可以通过传入一些变量进行改变,这样就可以把一些类似的逻辑又抽成一个额外的函数,达到了简化代码的目的。

3.既然说到了函数那么就想聊聊回调函数了。为什么想聊一聊这个内容呢?因为这周自己在工作过程中写到了一个回调函数,虽然的确很难懂,但是这种函数式的操作真的很cooool~,而且功能极其强大。

    首先,我们需要简单了解一下回调函数是什么。

百度百科:回调函数就是一个通过函数指针调用的函数。 如果你把函数的指针(地址)作为参数传递给另一个函数,当这个指针被用来调用其所指向的函数时,我们就说这是回调函数。 回调函数不是由该函数的实现方直接调用,而是在特定的事件或条件发生时由另外的一方调用的,用于对该事件或条件进行响应。

  很多语言都有回调函数,其在语言的底层实现的方式虽然不同,但是其功能都是类似的,而且从方式上来看,都是将函数作为参数传入到另一个函数之中。

function fn(arg1, arg2, callback){

    var num = Math.ceil(Math.random() * (arg1 - arg2) + arg2);

    callback(num);  //传递结果

}

fn(10, 20, function(num){

  console.log("Callback called! Num: " + num);

});    //结果为10和20之间的随机数

  我们上网去搜回调函数,给出的最简单的示例一般就是这样,看到这样的示例我一般会先通读一下代码,理解它的涵义。这个示例并不难理解,fn是一个声明的函数,callback是一个函数类型的参数,它将在函数中被调用,但是它的实现会在它调用的时候才会确定。但是理解之后我就随之冒出一个问题,这样写是多此一举把?我为什么不直接在函数fn中写一个console就好了,而用这样复杂的回调函数形式写出这么冗杂难读的代码呢?

    这里就得思考一下回调函数的意义了,有人曾解释过回调函数,说之所以使用回调函数,是因为再声明回调的时候,使用者自己都不知道回调函数要干什么。我觉得这种解释有一定道理,但是不够准确。如果,我完全不知道某个函数要干嘛,那我为什么要这个函数写在这里呢?所以说,这个概念本身很模糊,以至于我写了多少年也没有手动原生写过一个回调函数。直到上周我在实际开发中突然灵光一闪使用到了这个久违的功能,才大致明白了回调函数存在的意义,以下基本是我想到的可以使用回调的情形。(emmmm,这些情形不是示例中那样强行回调,而是你在这些情况使用回调会觉得,这里使用回调真的是太酷炫,太省事啦)

     1.定时器。这个是函数内部已经实现的功能,我们在使用setTimeout和setInterval的时候其实就是传入了一个回调函数。不过扩展一下,其实,这种情形是符合那种完全不知道函数该干什么的情况,但是至少我们知道这个函数是要多少时间后执行,这样的情况我认为一般只会出现像定时器一样这种比较底层的设计之中,在具体使用回调的时候,这样的情况太难把控了。这可以总结为第一种情况,只知道模糊的回调前提,基本对回调函数没有什么多余的限制,全部交给回调函数的编写者,比较难以把控。

     2.修改指向性变量(我不知道要改什么)。这一个是我这一周遇到的情况,我有一个需要改变的对象数组panelsData,panelsData的每一项(暂时写作panelData,我在代码中也是这么写的)panelData都有很多的属性,而且这个对象是要传入到微信小程序的wxml之中的,也就意味着我如果需要修改panelsData中的某一项,那么必须先要创建一个克隆对象,在修改之后再进行一次setData。

    现在解释到这里,我们已经有了大致的函数流程

比较麻烦的就是修改对象中的某一项的某个属性,因为这个会根据实际情形出现不同的情况,我一开始是想通过传入参数改变的,但是感觉传入进去,会产生多种麻烦(当然现在想来,有对象字面量的话,似乎是我考虑不周)。这时就轮到回调函数登场了,这里只需要一个callback,callback的具体功能就是修改panelsData中的某一个panelData的某一个属性,好了,剩下的留到实际使用的时候决定吧,毕竟那时候可以确定是哪一项哪一个属性,直接选取赋值就好了。

    3.数组遍历类型(类似underscore,我不知道要怎么改)。最后一种与上一种其实是反过来的,我们知道要改动的对象是什么,但是我们不知道要如何改动,就像underscore.js中的内容,我们不知道使用者要对这个数组做什么,所以留下一个供使用者发挥自己功能的函数,除了对这个数组进行遍历,使用者还可以对他们进行额外的操作。

_.map([1, 2, 3], function(num){ return num * 3; });

=> [3, 6, 9]

_.map({one: 1, two: 2, three: 3}, function(num, key){ return num * 3; });

=> [3, 6, 9]

_.map([[1, 2], [3, 4]], _.first);

=> [1, 3]


4.最后是一些比较表层的简化方式,这里先不细说了,不过也很重要:添加注释,统一命名!!

结语:简化函数的路真的是茫茫无边,因为代码的优化是无止尽的嘛。这一周还是没用markdown,下周写一个markdown初步学习把!!~~

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 212,332评论 6 493
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,508评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 157,812评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,607评论 1 284
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,728评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,919评论 1 290
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,071评论 3 410
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,802评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,256评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,576评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,712评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,389评论 4 332
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,032评论 3 316
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,798评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,026评论 1 266
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,473评论 2 360
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,606评论 2 350

推荐阅读更多精彩内容