不知道大家有没有一种感觉,那就是自己写的javascript代码虽然能完全解决工作上的需要,但是,一眼望去,too simple!!!简直就是一个傻子都能看懂的水平,于是,在工作之余,我开始去收集一些几乎在日常开发中未曾用过的javascript写法/有价值的javascript知识点,借此来提高自身javascript水平。

一、函数式编程与面向对象编程

<script>/*函数式编程*/function f1(){var n=999;nAdd=function(){n+=1;};var f2 = function(){console.log(n);};return f2;}var result=f1();result(); // 999
  nAdd();result(); // 1000/*面向对象编程1之json写法*/var obj1 = {n:999,nAdd:function(){this.n += 1;},getN:function(){console.log(this.n);}};obj1.getN();//999
    obj1.nAdd();obj1.getN();//1000/*面向对象编程2之工厂模式*/var obj2 = function(){var obj = new Object;obj.n = 999;obj.nAdd = function(){this.n += 1;};obj.getN = function(){console.log(this.n);}return obj;};var objins = new obj2();objins.getN();//999
    objins.nAdd();objins.getN();//1000/*面向对象编程3之原型prototype*/function obj3(n) {this.n = n;}obj3.prototype.nAdd = function() {this.n+=1;};obj3.prototype.getN = function() {console.log(this.n);}var objins2 = new obj3(999);objins2.getN();//999
    objins2.nAdd();objins2.getN();//1000
</script>

View Code

针对上面所示的函数式编程,涉及了作用域和闭包的知识,这里简要提一下;

里面的nAdd没有用var关键字声明,所以他是全局的,后面可以全局调用,其次利用闭包访问和修改了函数作用域内的n值。

二、纯函数和非纯函数

1.此函数在相同的输入值时,总是产生相同的输出。函数的输出和当前运行环境的上下文状态无关。

2.此函数运行过程不影响运行环境,也就是无副作用(如触发事件、发起http请求、打印/log等)。

简单来说,也就是当一个函数的输出不受外部环境影响,同时也不影响外部环境时,该函数就是纯函数,也就是它只关注逻辑运算和数学运算,同一个输入总得到同一个输出。

var xs = [1,2,3,4,5];
// 纯的
xs.slice(0,3);
//=> [1,2,3]
xs.slice(0,3);
//=> [1,2,3]
xs.slice(0,3);
//=> [1,2,3]// 不纯的
xs.splice(0,3);
//=> [1,2,3]
xs.splice(0,3);
//=> [4,5]
xs.splice(0,3);
//=> []

View Code

纯函数相对于非纯函数来说,在可缓存性、可移植性、可测试性以及并行计算方面都有着巨大的优势。

三、函数的柯里化

curry 的概念很简单:将一个低阶函数转换为高阶函数的过程就叫柯里化。

函数柯里化是一种“预加载”函数的能力,通过传递一到两个参数调用函数,就能得到一个记住了这些参数的新函数。从某种意义上来讲,这是一种对参数的缓存,是一种非常高效的编写函数的方法:

                /*一般写法:两数相加*/var add = function(x,y){return x + y;}/*2+1和2+10*/add(2,1);//3add(2,10);//12/*柯里化写法*///es5var add = function(x) {return function(y) {return x + y;};};//es6var add = x => (y => x + y);//定义+1和+10函数var increment = add(1);//柯里化后得到的+1函数var addTen = add(10);//柯里化后得到的+10函数increment(2);  // 3addTen(2);  // 12

View Code

四、Array.reduce/Array.reduceRight(数组迭代)

先不看标题,来个题目:如何求数组[1,2,3,4,5]的各项累加的和?

大多数人恐怕会立即说出for循环、while循环,的确,for循环和while循环是可以解决上述问题,但是,这个答案显然脱离了此篇博客的主题:逼格!!!

并且,实验表明,将上述求和方法循环1W次,用for循环和while循环耗时大概在50~55ms,但是,用Array.reduce/Array.reduceRight仅仅耗时0.4ms!!!

关于该方法的详解,请猛戳→https://www.w3cplus.com/javascript/array-part-8.html;这里给个demo:

var arr = [1,2,3,4,5];/*ES6写法*/var reducer = (prevalue,curvalue)=>prevalue + curvalue;console.log(arr.reduce(reducer));//15/*ES5写法*/var reducer = function(prevalue,curvalue){return prevalue + curvalue;};console.log(arr.reduce(reducer));//15/*解析*/数组的reduce方法有两个参数:callback,prevalue;对于第一个参数callback,里面有4个参数prevalue、curvalue、index、array;index是当前迭代时的curvalue的索引(数组中的索引),array当然是操作的数组了;着重看另外两个参数,prevalue和curvalue(上一个值和当前值);如果reduce方法没有第二个参数的话,那么callback回调将数组第一个值作为prevalue,第二个值作为curvalue;如果reduce方法有第二个参数,那么将第二个参数值作为prevalue,将数组第一个值作为curvalue;每一次的操作结果将变为下一次操作的prevalue,而curvalue的值教上一次往后推一位;/*实例解析*/针对上述数组相加;没有第二个参数,只有一个回调callback,那么他的过程是这样的;第一次运算:prevalue为1,curvalue为2,运算结果为1+2=3,并将结果作为下次运算的prevalue;第二次运算:prevalue为3(上一次运算的结果),curvalue为3,运算结果为3+3=4,以此类推;如果有第二个参数,假设为5,arr.reduce(reducer,5),那么将是这么计算的;第一次运算:prevalue为5(第二个参数),curvalue为1,运算结果为5+1=6,并将结果作为下次运算的prevalue;第二次运算:prevalue为6(上一次运算的结果),curvalue为2,运算结果为6+2=8,以此类推;reduceRight和reduce类似,只不过他是从右边开始迭代的。

View Code

 五、函数组合(reduce高级用法)

假想一下,要将字符串“my name is echo”进行如下操作,你会怎么做?转大写、然后末尾加一个感叹号;

我想你大概会定义一个函数operate,对于形参str,先toUpperCase(),然后+ '!',ok这样做没错,但是现在我需求改了,我不要求转大写了,你是不是得删除那行代码?

可能你会说了,我定义两个函数一个是转大写,一个是加叹号,需要哪个用哪个,其实无论你用几个函数来写,还是直接用prototype或者链式调用的方法去写,都只是大众化的写法,且不易维护,so,请看下面的写法:

        var compose = (...args) => x => args.reduceRight((prevalue, curvalue) => curvalue(prevalue), x);var toUpperCase = x => x.toUpperCase();var exclaim = x => x + '!';var shout = compose(exclaim, toUpperCase);console.log(shout("my name is echo"));

View Code

一眼望去,是不是两眼懵逼?!!不怕,我们用ES5还原一下,请看:

        var compose = function (...args){return function (x){return args.reduceRight(function(prevalue, curvalue){return curvalue(prevalue);},x)}};var toUpperCase = function(x){return x.toUpperCase();};var exclaim = function(x){return x + '!';};var shout = compose(exclaim, toUpperCase);console.log(shout("my name is echo"));

View Code

结合上述第四例所讲到的reduce,我希望此时你已经看懂了,没看懂也没关系,接着往下看,继续解析:

        var shout == compose(exclaim, toUpperCase)== function (x) {return [exclaim, toUpperCase].reduceRight(function(prevalue, curvalue){return curvalue(prevalue);},x)};shout("my name is echo") == [exclaim, toUpperCase].reduceRight(function(prevalue, curvalue){return curvalue(prevalue);},"my name is echo");/*前面说过,如果reduce/reduceRight传了第二个参数,那么该第二个参数将作为prevalue给callback调用。*//*运算过程如下(reduceRight从右往左)curvalue(prevalue):*/1.toUpperCase("my name is echo");并将结果作为prevalue供下次调用;2.exclaim(toUpperCase("my name is echo"));如此实现了先转大写再加感叹号。

View Code

转载于:https://www.cnblogs.com/eco-just/p/10328522.html

提高你的javascript代码逼格系列之函数与数组相关推荐

  1. 如何提升你的javascript代码逼格之简写篇

    三元运算符 当你想用一行代码来写if...else语句的时候,使用三元操作符是非常好的选择,例如: const x = 20; let answer; if (x > 10) {answer = ...

  2. 几维安全Javascript代码混淆(js加密)在线使用说明

    2019独角兽企业重金招聘Python工程师标准>>> 几维安全Javascript代码混淆是一项在线加密服务,用户只需将JS文件打包成zip包,提交到加密平台,即可完成代码混淆.字 ...

  3. JavaScript学习(七)——对象与数组、内部对象(1)

    目录 javascript对象与数组 javascript内部对象 object对象 1.创建object对象 2.object对象的属性 3.object对象的方法 String对象 1.创建Str ...

  4. 深入理解JavaScript系列(1):编写高质量JavaScript代码的基本要点

    才华横溢的Stoyan Stefanov,在他写的由O'Reilly初版的新书<JavaScript Patterns>(JavaScript模式)中,我想要是为我们的读者贡献其摘要,那会 ...

  5. 深入理解JavaScript系列(1):编写高质量JavaScript代码的基本要点(转)

    才华横溢的Stoyan Stefanov,在他写的由O'Reilly初版的新书<JavaScript Patterns>(JavaScript模式)中,我想要是为我们的读者贡献其摘要,那会 ...

  6. javascript 代码_如何使您JavaScript代码保持简单并提高其可读性

    javascript 代码 by Leonardo Lima 莱昂纳多·利马(Leonardo Lima) 如何使您JavaScript代码保持简单并提高其可读性 (How to keep your ...

  7. 优化javaScript代码,提高执行效率

    今天看完书,总结了一下可以如何优化 JavaScript . 1.合并js文件 为优化性能,可以把多个js文件(css文件也可以)合并成极少数大文件.跟十个5k的js文件相比,合并成一个50k的文件更 ...

  8. js 延迟几秒执行ifarme_延时加载JavaScript代码提高速度_javascript技巧 -

    ...值: none 0 e1. 利用animation属性实现循环间的延时执行实例教程简介:先来介绍一下animation定义和用法,animation 属性是一个简写属性,用于设置六个动画属性:2 ...

  9. php延迟加载js,延时加载JavaScript代码提高速度

    延时加载js代码提高速度,具体内容如下所示: 如果网页中存在大量的javascript代码会极大的影响网页的访问速度,下面就简单介绍一下如何处理此问题. 一.延时加载js文件: 可以使用定时器函数se ...

最新文章

  1. 【Linux】一步一步学Linux——head命令(41)
  2. 数据挖掘方法案例介绍
  3. python模拟鼠标拖动滑块_如何通过拖动滑块来控制Kivy滚动视图?
  4. 浅谈python中的一般方法、静态方法(staticmethod)和类方法(classmethod)
  5. Mybatis源码分析之(一)搭建一个mybatis框架(写一个mybatis的Demo)
  6. 没有bug队——加贝——Python 练习实例 15,16
  7. node中操作MySQL
  8. 移动项目工作笔记0001---使用uni-app开发移动端应用
  9. 【机器学习】Cross-Validation(交叉验证)详解
  10. qq传输文件腾讯服务器保存在哪里,电脑接收的QQ文件在哪里?在哪个文件夹可以找到QQ接收的文件...
  11. 深圳摇号验证码一输完就变的解决办法
  12. luogu 1757 分组背包
  13. Jekyll基本用法
  14. 用python画哆啦a梦的头_用 Python 画个哆啦A梦
  15. 今天是我在csdn的1265天
  16. 机械图样解读——尺寸线及尺寸界线,尺寸标注
  17. 玄魂工作室--咪噜妹
  18. 长USB线 CH340N 硬件调试——无法识别USB设备
  19. IPFS Java实现
  20. 视频教程-Ajax从入门到进阶视频课程(通俗易懂)-JavaScript

热门文章

  1. 深入理解ES6 pdf
  2. camera驱动框架分析(上)
  3. 基于JavaConfig配置的Spring MVC的构建
  4. [转]可伸缩系统的架构经验
  5. 东方文学网新进作品【2】
  6. 网站架构探索(1)---序言
  7. Jenkins发布spring boot到hub.Docker 方法
  8. K8S仪表板Service unavailable故障的解决办法
  9. mybatis动态更新xml文件后热部署,不重启应用的方法
  10. Java多线程同步机制