SQL 语句就是声明式的,你无需关心 Select 语句是如何实现的,不同的数据库会去实现它自己的方法并且优化。
所谓惰性执行指的是函数只在需要的时候执行,即不产生无意义的中间变量 函数式编程跟命令式编程最大的区别就在于几乎没有中间变量,它从头到尾都在写函数,只有在最后的时候才通过调用 convertName 产生实际的结果。
这是函数式编程的核心概念:
数据不可变: 它要求你所有的数据都是不可变的,这意味着如果你想修改一个对象,那你应该创建一个新的对象用来修改,而不是修改已有的对象。
无状态: 主要是强调对于一个函数,不管你何时运行,它都应该像第一次运行一样,给定相同的输入,给出相同的输出,完全不依赖外部状态的变化。
const curUser = {
name: "Peter",
};
const saySth = (user, str) => user.name + ": " + str; // 不依赖外部变量
const changeName = (user, name) => ({ ...user, name }); // 未修改外部变量
const newUser = changeName(curUser, "Jay"); // { name: 'Jay' }
saySth(curUser, "hello!"); // Peter: hello!
柯里化的意思是将一个多元函数,转换成一个依次调用的单元函数。
部分函数应用强调的是固定一定的参数,返回一个更小元的函数。
柯里化强调的是生成单元函数,部分函数应用的强调的固定任意元参数,而我们平时生活中常用的其实是部分函数应用,这样的好处是可以固定参数,降低函数通用性,提高函数的适合用性.
把要操作的数据放最后面
函数组合的 debug 可以用 trace
new 让人误以为是创建了 Class 的实例,但其实根本不存在所谓的实例化,只是简单的属性委托机制(对象组合的一种),而 this 则引入了执行上下文和词法作用域的问题,而我只是想创建一个简单的对象而已!
map 知道如何在上下文中映射函数值。它首先会打开该容器,然后把值通过函数映射为另外一个值,最后把结果值再次包裹到一个新的同类型的容器中。而这种变换容器内的值的方法(map)称为 Functor(函子)。
map 是把函数执行的结果重新包装到 Box 中后然返回一个新的 Box 类型,而 forEach 则是直接把函数执行的结果 return 出来,就结束了!
什么是 functor
上面我们定义了一个简单的 Box,其实也就是拥有 map 和 fold 方法的类型。让我们把脚步放慢一点,再仔细观察和思考一下我们的 map:Box(a) -> Box(b) ,本质上就是通过一个函数 a -> b 把一个 Box(a) 映射为 Box(b)。这和中学代数中的函数知识何其类似,不妨再回顾一下代数课本中函数的定义
假设 A 和 B 是两个集合,若按照某种对应法则,使得 A 的任一元素在 B 中都有唯一的元素和它对应,则称这种对应为从集合 A 到集合 B 的函数。
常见的 functor
Promise 的 then 和 catch 方法(Promise 也是一种 Functor? Yes!)。
Rxjs Observable 的 map 和 filter (异步函数的组合?Relax!)。
const componse = (...fn) => x => (fn.reduceRight(x,v) => x + v)
先对比下功能强大的 box 理念, 也就是最基本的 functor,
js 改变原数组和不改变原数组的方法
unshift 在数组的开头添加一个或更多元素,并返回新的长度
copyWithin 从数组的指定位置拷贝元素到数组的另一个指定位置中
map: 只有当 arr 为基本数据类型时,map 方法才不会改变原始数组,arr 为引用类型时,还是会改变原数组
join 将数组(或一个类数组对象)的所有元素连接成一个字符串并返回这个字符串
reduce 对数组中的每个元素执行一个由您提供的“reducer”函数(升序执行),将其结果汇总为单个返回值
every 对数组中的每一项运行给定函数,如果该函数对每一项都返回 true,则返回 true
some 对数组中的每一项运行给定函数,如果该函数对任一项返回 true,则返回 true
find 返回数组中满足提供的测试函数的第一个元素的值。否则返回 undefined
findIndex 返回数组中满足提供的测试函数的第一个元素的索引。否则返回 -1