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

不知道大家有没有一种感觉,那就是自己写的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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/395294.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

印度评论九章量子计算机,张礼立:中国 “九章”量子计算机到底厉害在哪?...

【背景信息】12月4日&#xff0c;《科学》杂志公布了中国“九章”的重大突破。 这台由中国科学技术大学潘建伟、陆朝阳等学者研制的76个光子的量子计算原型机&#xff0c;推动全球量子计算的前沿研究达到一个新高度。尽管距离实际应用仍有漫漫长路&#xff0c;但成功实现了“量…

手机web网页制作的认识(有关meta标签)

近日以来一直在看JQuery Mobile 一个手机开发框架&#xff0c;说实话真的很头疼的~~~~ 因为里面有很多的属性、方法和事件~~~ 下面是手机网页的一些认识&#xff1a; 一、<meta name"viewport" id"viewport" content"widthdevice-width, initial-s…

包打包和解析过程 unity_Unity学习—资源管理概览

本文介绍了 Unity 常用四种默认路径&#xff0c;以及 AssetDataBase、Resources、AssetBundle 和目前最新的 Addressable 四种资源管理方式文中所有 API 均以版本 2019.3 为准本文原地址&#xff1a;Unity学习—资源管理概览资源路径Application.dataPath官方文档只读&#xff…

graphql tools_声明式GraphQL:编写更少的代码,并使用graphql-tools完成更多工作

graphql toolsI’ve been working with GraphQL for a few months now, but only recently began using Apollo’s graphql-tools library. After learning a few idioms, I am able to mock up a functional API quickly. This is largely due to its low-code, declarative a…

用idea搭建SSM项目,原来这么简单

目录 前言软件环境创建项目数据库文件配置文件pom.xmllog4j.propertiesjdbc.propertiesapplicationContext.xmlspring-mvc.xmlweb.xml运行项目编写代码前言 前阵子突发奇想&#xff0c;想学习下SpringMVC的源码&#xff0c;于是打算用idea搭建一个简易的maven版SSM案例&#xf…

浙江理工大学计算机组成原理试卷,浙江理工大学计算机组成原理设计试题.doc...

计算机组成原理课程设计报告2013/2014第二学期指导教师&#xff1a;许建龙 张芳班级&#xff1a;12计科2班姓名&#xff1a;学号&#xff1a; 计算机组成原理大型实验任务书(计算机12级1、2、3班和实验班)实验目的&#xff1a;深入了解计算机各种指令的执行过程&#xff0c;以及…

mac vagrant 虚拟机nfs挂载点

需求&#xff1a;在mac 上安装了虚拟机&#xff0c;虚拟机系统为centos6.5&#xff0c;现在希望讲虚拟机上点目录通过nfs共享给mac使用 下面主要描述通过nfs共享目录给mac调用的过程 过程参考网址&#xff1a; http://www.moqifei.com/archives/1534 &#xff08;我主要参考的这…

nodejs中require的路径是一个文件夹时发生了什么

node中使用require的时候如果路径是一个文件夹时&#xff0c;或者特殊的情况require(..);require(.); 这是node实战这本书里说的情况&#xff0c;但是我在node6.9版本中发现不完全是这样&#xff0c;可能是后来做了修改。下面说说在6.9下require路径的过程。 这里以require(.)说…

python调用ctypes中windll中的方法超时处理_python中使用ctypes调用MinGW生成的动态链接库(dll)...

关于gcc编译dll的我就不说了&#xff0c;网上举例一大堆&#xff0c;下面以g为例。假设有一个test.cpp文件如下&#xff1a;extern "C" {__declspec(dllexport) double add(double x,double y);}double add(double x,double y){return xy;}在MinGW中使用g编译&#x…

惯用过程模型_惯用的Ruby:编写漂亮的代码

惯用过程模型Ruby is a beautiful programming language.Ruby是一种美丽的编程语言。 According to Ruby’s official web page, Ruby is a:根据Ruby的官方网页&#xff0c;Ruby是&#xff1a; “dynamic, open source programming language with a focus on simplicity and …

采用晶体管为基本元件的计算机发展阶段是,计算机应用基础知识点

第一章 计算机基础知识1、计算机发展阶段第一代&#xff1a;电子管计算机采用电子管为基本元件&#xff0c;设计使用机器语言或汇编语言。要用于科学和工程计算 第二代&#xff1a;晶体管计算机采用晶体管为基本元件&#xff0c;程序设计采用高级语言&#xff0c;出现了操作系统…

springcloud系列三 搭建服务模块

搭建服务模块为了模拟正式开发环境,只是少写了service层直接在controller里面直接引用,直接上图和代码:更为方便: 创建完成之后加入配置: pom.xml文件: <?xml version"1.0" encoding"UTF-8"?> <project xmlns"http://maven.apache.org/POM…

P1801 黑匣子_NOI导刊2010提高(06)

题目描述 Black Box是一种原始的数据库。它可以储存一个整数数组&#xff0c;还有一个特别的变量i。最开始的时候Black Box是空的&#xff0e;而i等于0。这个Black Box要处理一串命令。 命令只有两种&#xff1a; ADD(x):把x元素放进BlackBox; GET:i加1&#xff0c;然后输出Bla…

MySql模糊查询

常规like的使用限制&#xff1a; 1. like %keyword &#xff1a;索引失效&#xff0c;使用全表扫描。但可以通过翻转函数like前模糊查询建立翻转函数索引走翻转函数索引&#xff0c;不走全表扫描。 2. like keyword% &#xff1a;索引有效。 3. like %keyword% &#xff1a;索引…

python psycopg2使用_python 操作数据库:psycopg2的使用

1 conn psycopg2.connect(database"testdb", user"postgres",password"cohondob", host"127.0.0.1", port"5432")这个API打开一个连接到PostgreSQL数据库。如果成功打开数据库时&#xff0c;它返回一个连接对象。2cursor c…

软件测试人员棘手的问题,Èí¼þ²âÊԵļ¬ÊÖÎÊÌ⣺ÈçºÎ±ÜÃâÖØ¸´ÌύȱÏÝ...

¡¡¡¡£££©£¡££¡££££©©£¡¡¡¡¡BUG£££¢¡£££¡££¡£¡£——£…

机器学习实用指南_机器学习方法:实用指南

机器学习实用指南by Karlijn Willems通过Karlijn Willems 机器学习方法&#xff1a;实用指南 (How Machines Learn: A Practical Guide) You may have heard about machine learning from interesting applications like spam filtering, optical character recognition, and …

本地仓库settings.xml中使用阿里的仓库

背景 当前使用eclipse自带的maven碰到两个蛋疼的问题&#xff1a; maven在国内使用如果不进行FQ则会痛苦不堪如便秘。maven下载大量jar包导致某盘不够用&#xff0c;需要换大的分区。因此为了解决这个问题就介绍两个eclipse配置&#xff1a;maven本地路径配置和maven外部路径配…

day6_python之md5加密

#md5是不可逆的&#xff0c;就是没有办法解密的 Python内置哈希库对字符串进行MD5加密的方法-hashlibimport hashlib def my_md5(s,salt): #用函数&#xff0c;为了提高代码的复用率s ssalt #1.必须是字符串news str(s).encode() #2.字符串需要encode编码后&#xff0…

异步服务_微服务全链路异步化实践

1. 背景随着公司业务的发展&#xff0c;核心服务流量越来越大&#xff0c;使用到的资源也越来越多。在微服务架构体系中&#xff0c;大部分的业务是基于Java 语言实现的&#xff0c;受限于Java 的线程实现&#xff0c;一个Java 线程映射到一个kernel 线程&#xff0c;造成了高并…