无所事事的样子开始了摸鱼的一天
IO函子
// IO函子中的_value是一个函数,这里把函数当作值来处理
// 将不纯的操作交给调用者处理
// IO函子把这个不纯的操作存到_value里,把这个不纯洁的东西包起来,它就是纯洁的小白花了
const fp = require('lodash/fp')
class IO {
constructor(fn) {
this.value = fn
}
static of(value) {
return new IO(function () {
return value
})
}
map(fn) {
return new IO(fp.flowRight(fn, this.value))
}
}
let r = IO.of(process) // process是node中的一个属性
.map((p) => {
return p.execPath
})
// r是IO返回的函子
函数式编程的工具库有不少的亚子 lodash、folktale/core/lambda、lodash/fp
task函子
//
const {task} = require('folktale/concurrency/task')
const fs = require('fs')
const {split,find} = require('lodash/fp')
function readFile(fileName) {
return task(resolver => {
fs.readFile(fileName, 'utf-8', (err, data) => {
if (err) {
resolver.reject(err)
} else {
resolver.resolve(data)
}
})
})
}
readFile('../../../package.json')
.map(split('\n'))
.map(find(x=>x.includes('version')))
.run()
.listen({
onRejected: (err) => {
console.log(err)
},
onResolved: value => {
console.log(value)
}
})
Monad函子
// 为了解决函子出现嵌套的解决方案
// 函子中具有join和of两个方法兵遵守一些定律就是Monad函子
join(){
return this._value();
}
flatMap(fn){ // 需要取到值的时候用flatMap替代Map
return this.map(fn).join()
}
函数式编程
- 是一种编程的思想(对照面相对象的编程,都是思想)
-
把运算过程抽象成函数
-
- 高阶函数
-
把函数作为参数或返回值
-
柯里化和函数组合是基于这个高阶函数
-
闭包是无处不在的
-
- 纯函数
-
相同输入总会有相同的输出
-
多元函数转换为一元函数
-
- 函子
- 在盒子内封装一个值,不对外公布,处理这个值需要调用Map方法,传递处理这个值的函数
- 盒子内也可以封装一个函数
函数的活动对象
- 执行上下文
- 全局执行上下文
- 函数级执行上下文
- eval执行上下文
- 函数执行阶段
- 函数建立阶段
当调用函数时,还没有执行函数的内部代码
- 创建执行上下文对象
fn.EC = { variableObject://函数中的arguments、参数、局部员 scopeChains: //当前函数所在的父级作用域中的活动象 this:{} // 当前函数内部的 this指向 } - 函数执行阶段
// 把变量对象转换为活动对象 fn.EC = { activationObject: // 函数中的arguments、参数、局部员 scopeChains: // 当前函数所在的父级作用域中的活动象 this:{} // 当前函数内部的 this指向 }
- 函数建立阶段
[[Scopes]]作用域链,函数在创建时就会生成该性,js引擎才可以访问。这个属性中存储的是所父级中的变量对象
闭包
function fn(name){
return function (){
console.log(name);
}
}
// 当调用一个函数的时候,这个函数的作用域其实就是闭包,当函数外部有引用的时候函数的作用域就不会释放
- fn 外部对内部有引用
- 在另一个作用域访问到 fn 作用域中的局部成员
原型/原型链
const Person = function(){};
const p = new Person();
// 当new构造函数的时候,会创建一个对象,所有的对象都有一个属性__proto__
// 所有的函数都有一个prototype 原型
// 对象的__proto__和构造函数的prototype原型,都指向同一个对象,prototype上有一个属性是constructor
// constructor指向了构造函数本身,让对象可以通过 constructor 找到创建它的构造函数
// Person.prototype这个原型对象也是个对象
// 它是new Object()创建的,创建的Person.prototype,它也是个对象,它的__proto__属性指向了Object.prototype上
// Object.prototype也是个对象,它的__proto__就是null
// 构造函数 Object也是一个对象 是通过new Function()创建的 它是个对象
// 它就有个__proto__属性 ,它指向了 Function.prototype属性上
// 构造函数Function也是一个对象,它既是构造函数也是一个对象
// 所以它的__proto__属性也指向了Function.prototype属性上
// Function.prototype的__proto__它指向了Object.prototype属性上
这关系,啧啧,贵圈真乱,构造函数 new 出来个p对象,它俩就被隔离了,凄凄惨惨戚戚,p对象只能通过身上的DNA __proto__ 属性,找到那个中间商(?)Person.prototype,让它通过它的能力constructor找到那个构造函数,而构造函数也只能通过prototype属性找到中间商(?)Person.prototype而已,构造函数真是工具人啊,只有new的时候造出了 p对象,之后只能 p对象来找它了Person.prototype还能通过能力constructor找它,真就是工具人不当人了呗。
为了完善这个原型链系统,可谓是渣到极点啊,Person.prototype其实也只是个孩子,它是Object new出来的对象,自然它也能通过__proto__去寻找Object.prototype,Object.prototype就比较惨了,它的__proto__竟然指向的null,果然世界的最顶层是孤独的么。
来了来了,乱的来了,构造函数Object也是由构造函数Function new出来的,不过它应该比较顶层了,它竟然有__proto__属性,与它的prototype属性一样都指向了Function.prototype,不过原本的构造函数Object的__proto__属性也指向了它,Function.prototype可谓是顶级中间商了,而且它还有__proto__属性,指向的Object.prototype,果然它才是真的上流。
—————————————————————————————————————————————————————— 我这废柴