Functional-Light-JS 摘录笔记(1)
function foo(...args) {
console.log( args[3] );
} var arr = [ 1, 2, 3, 4, 5 ]; foo( ...arr ); //
Think of ...
in this symmetric sense: in a value-list position, it spreads. In an assignment position -- like a parameter list, because arguments get assigned to parameters -- it gathers.
...在函数定义的时候作为数组聚合,作为变量使用的时候将分散。
Whichever behavior you invoke, ...
makes working with arrays of arguments much easier. Gone are the days of slice(..)
, concat(..)
and apply(..)
to wrangle our argument value arrays.
用了这种新技巧后,不再需要时候slice/concat 去处理变量数组了。
But now we start to uncover the first bits of a principle that we'll come back to many more times in this text: declarative code often communicates more cleanly than imperative code.
声明式代码比指令式代码更清晰
Declarative code, like destructuring in the earlier snippet, focuses on what the outcome of a piece of code should be. Imperative code, like the manual assignments just shown, focuses more on how to get the outcome. If you later read the code, you have to mentally execute it to understand the desired outcome. The outcome is coded there, but it's not as clear.
声明式代码关注代码的结果,指令式代码关注结果的实现,阅读指令式代码的时候,还要在脑海中运行一下,蛋疼。
解构对象参数
function foo( {x,y} = {} ) {
console.log( x, y );
} foo( {
y: 3
} );
这种写法的好处在于,不必在意参数的顺序了,如果按以前的常见写法十分蛋疼:
function foo(x,y,z){ } foo(null,null,1);//即使只想要参数z,前面参数仍需要占个坑
In FP, we'll want our functions to be unary whenever possible, and sometimes we'll even use a variety of functional tricks to transform a function of higher arity to a unary form.
函数式编程中,总是希望函数尽可能是一元的。
另外,根据参数类型不同,在函数里做不同处理,虽然方便,但是从长远来看,会有麻烦。
FP 精神之一,函数永远有显式返回值 ,而且通常不是undefined
除了在参数上面解构,还可以在表达式中解构数组或对象值。
function foo() {
var retValue1 = 11;
var retValue2 = 31;
return [ retValue1, retValue2 ];
} var [ x, y ] = foo();
console.log( x + y ); //42
Early Return
作者提到一个例子,在逻辑判断中,return语句要尽可能考虑延后或者只有一个return语句。比如避免下面这种写法,
function foo(x) {
if (x > 10) return x + 1; var y = x / 2; if (y > 3) {
if (x % 2 == 0) return x;
} if (y > 1) return y; return x;
}
写代码的时候还有一种常见的情况,即函数隐式地对全局参数做处理,并没有返回值。
var y; function foo(x) {
y = (2 * Math.pow( x, 2 )) + 3;
} foo( 2 ); y; //
那么它和下面这种写法,有什么区别呢?
function foo(x) {
return (2 * Math.pow( x, 2 )) + 3;
} var y = foo( 2 ); y;
首先,用返回值的方式赋值说明这是显式的,前者隐式。developers prefer explicit patterns over implicit ones.
另外一个更隐晦的例子:
function sum(list) {
var total = 0;
for (let i = 0; i < list.length; i++) {
if (!list[i]) list[i] = 0; total = total + list[i];
} return total;
} var nums = [ 1, 3, 9, 27, , 84 ]; sum( nums ); //
显然,返回值是124,这没有什么问题,但是外部变量 nums呢? 在控制台输出的时候会发现nums数组变成了
[ 1, 3, 9, 27, 0, 84 ]
外部变量被隐式改变了!! 这涉及到 Javascript 引用的问题:JS uses references and reference-copies for arrays, objects, and functions
参考 http://www.cnblogs.com/linhp/p/6085826.html
这种问题在函数式编程的世界里有一个专有名词:side effects,而一个没有副作用的函数则是纯函数。如果可能,纯函数最高 = =。
高阶函数的定义:
Functions can receive and return values of any type. A function that receives or returns one or more other function values has the special name: higher-order function.
This technique of specifying inputs in successive function calls is very common in FP, and comes in two forms: partial application and currying. We'll dive into them more thoroughly later in the text.
也就是说,下面这种函数体内的函数使用了输入值的形式在函数式编程中很常见。
function makeAdder(x) {
return function sum(y){
return x + y;
};
}
What I'm getting at is there's multiple reasons why named functions are always more preferable to anonymous functions.As a matter of fact, I'd go so far as to say that there's basically never a case where an anonymous function is more preferable. They just don't really have any advantage over their named counterparts.
基本上,匿名函数没什么好处,尽量避免。
Name every single function. And if you sit there stumped, unable to come up with a good name for some function you've written, I'd strongly suggest you don't fully understand that function's purpose yet -- or it's just too broad or abstract. You need to go back and re-design the function until this is more clear. And by that point, a name will become more apparent.
方法名称如果想不出好的,说明这个函数方法多少都有点问题,需要重新设计。
From my perspective, the problem is not with using objects to organize behavior. It's that we're trying to use implicit input instead of being explicit about it. When I'm wearing my FP hat, I want to leave this
stuff on the shelf.
函数式编程 say no to this.
Functional-Light-JS 摘录笔记(1)的更多相关文章
- WebGL three.js学习笔记 法向量网格材质MeshNormalMaterial的介绍和创建360度全景天空盒的方法
WebGL学习----Three.js学习笔记(5) 点击查看demo演示 Demo地址:https://nsytsqdtn.github.io/demo/360/360 简单网格材质 MeshNor ...
- WebGL three.js学习笔记 创建three.js代码的基本框架
WebGL学习----Three.js学习笔记(1) webgl介绍 WebGL是一种3D绘图协议,它把JavaScript和OpenGL ES 2.0结合在一起,通过增加OpenGL ES 2.0的 ...
- vue.js 学习笔记3——TypeScript
目录 vue.js 学习笔记3--TypeScript 工具 基础类型 数组 元组 枚举 字面量 接口 类类型 类类型要素 函数 函数参数 this对象和类型 重载 迭代器 Symbol.iterat ...
- WebGL three.js学习笔记 6种类型的纹理介绍及应用
WebGL three.js学习笔记 6种类型的纹理介绍及应用 本文所使用到的demo演示: 高光贴图Demo演示 反光效果Demo演示(因为是加载的模型,所以速度会慢) (一)普通纹理 计算机图形学 ...
- js学习笔记:webpack基础入门(一)
之前听说过webpack,今天想正式的接触一下,先跟着webpack的官方用户指南走: 在这里有: 如何安装webpack 如何使用webpack 如何使用loader 如何使用webpack的开发者 ...
- Vue.js学习笔记(2)vue-router
vue中vue-router的使用:
- js读书笔记
js读书笔记 基本类型的基本函数总结 1. Boolean() 数据类型 转换为true的值 转换为false的值 Boolean true false String 任何非空字符串 "&q ...
- React.js入门笔记
# React.js入门笔记 核心提示 这是本人学习react.js的第一篇入门笔记,估计也会是该系列涵盖内容最多的笔记,主要内容来自英文官方文档的快速上手部分和阮一峰博客教程.当然,还有我自己尝试的 ...
- JS 学习笔记--9---变量-作用域-内存相关
JS 中变量和其它语言中变量最大的区别就是,JS 是松散型语言,决定了它只是在某一个特定时间保存某一特定的值的一个名字而已.由于在定义变量的时候不需要显示规定必须保存某种类型的值,故变量的值以及保存的 ...
- node.js系列笔记之node.js初识《一》
node.js系列笔记之node.js初识<一> 一:环境说明 1.1 Linux系统CentOS 5.8 1.2 nodejs v0.10.15 1.3 nodejs源码下载地址 htt ...
随机推荐
- javascript 对象的创建与继承模式
针对JS高级程序设计这本书,主要是理解概念,大部分要点源自书内.写这个主要是当个笔记加总结 存在的问题请大家多多指正! 6.1理解对象 创建对象的两个方法(暂时) //第一种,通过创建一个Object ...
- oracle OCCI编程
1. 创建OCCI环境变量 Environment *env = Environment::createEnvironment(); Environment对象的建立必须放在第一位,而且也必须是最后一 ...
- 高性能TcpServer(Java) - Netty
源码下载 -> 提取码 QQ:505645074 Netty 是一个高性能.异步事件驱动的 NIO 框架,它提供了对 TCP.UDP 和文件传输的支持,作为一个异步 NIO 框架,Netty ...
- Asp.Net SignalR 使用记录 技术回炉重造-总纲 动态类型dynamic转换为特定类型T的方案 通过对象方法获取委托_C#反射获取委托_ .net core入门-跨域访问配置
Asp.Net SignalR 使用记录 工作上遇到一个推送消息的功能的实现.本着面向百度编程的思想.网上百度了一大堆.主要的实现方式是原生的WebSocket,和SignalR,再次写一个关于A ...
- LINUX中ORACLE 11.2.0.1 升级到11.2.0.4
11.2.0.4补丁号13390677,共7个文件,分别是 其中1&2是db,3是grid,4是client,5是gateways,6是example,7是deinstall 上传安装介质并解 ...
- 找出所有文件最小可resize尺寸
--找出所有文件最小可resize尺寸 SELECT a.file_id, CEIL( ( NVL( hwm,1 ) * blksize ) / 1024 / 1024 ) smallest_M, C ...
- 给大家推荐一个nginx.conf文件格式生成的网站
特别好用: 根据选择自定义nginx.conf的配置: https://nginxconfig.io/?0.php=false&0.python&php_server=%2Fvar%2 ...
- SpringBoot 自定义线程池,多线程
原文:https://www.jianshu.com/p/832f2b162450 我们都知道spring只是为我们简单的处理线程池,每次用到线程总会new 一个新的线程,效率不高,所以我们需要自定义 ...
- AXIOS 的请求
AXIOS 本质上等同于json 传值 1.引用 //引入axios import Axios from 'axios' //将axios挂载到 Vue原型上 Vue.prototype.$https ...
- Kibana 的 docker 镜像使用
1.dockhub镜像网址:https://hub.docker.com/_/kibana 2.下载镜像: docker pull kibana:7.4.0 3.创建容器(Kibana 默认的端口为5 ...