做网站网页,广州天河区房价多少钱一平方,博物馆网站建设说明,东营做网站排名函数式编程 柯里化currycurrycompose示例#xff1a;简化版展开写#xff1a; debug示例一#xff1a;示例二#xff1a; 模板字符串css in js方案 箭头函数问题 生成器 generator应用场景 反射 Reflect 柯里化curry
compose是curry的应用 在 lodash/fp underscore ramba … 函数式编程 柯里化currycurrycompose示例简化版展开写 debug示例一示例二 模板字符串css in js方案 箭头函数问题 生成器 generator应用场景 反射 Reflect 柯里化curry
compose是curry的应用 在 lodash/fp underscore ramba
curry
function curry(fn){// 统计传入函数的参数个数const lenfn.length// 函数命名为的后面重复调用return function curried(...args){// 当传入的参数个数大于等于函数需要的参数个数的时候则执行函数if(args.lengthlen){return fn.apply(this,args)}else{// 否则返回函数并且接收后面传入的参数return function(...args2){// 执行回调curried函数将参数合并传入下一次回调中return curried.apply(this,args.concat(args2))}}}
}compose
两个函数组合
function compose(f,g){return function(x){return f(g(x))}
}不确定个数函数组合
// 传入多个函数
function compose(...fns){// 当个数if(fns.length0){// console.log(-----等于0----);// compose不传参数的时候返回的是一个函数这个函数传的参数都返回return (args)args}if(fns.length1){// console.log(----等于1-----);// compose传入一个参数的话就返回这个函数return fns[0]}// compose传入两个及两个以上函数的时候使用reduce将作为参数的函数从右往左执行return fns.reduce((pre,cur)(...args)pre(cur(...args)))
}示例
简化版
var compose(f,g)(x)f(g(x))
const curryrequire(lodash).curryvar toUpperCasecurry(function(str){return str.toUpperCase()
})var headcurry(function(x){return x[0]
})
var initialsfunction(name){return name.split( ).map(compose(toUpperCase,head)).join(. )
}
console.log(initials(hunter stockton thompson))展开写
function curry(fn){// 统计传入函数的参数个数const lenfn.length// 函数命名为的后面重复调用return function curried(...args){// 当传入的参数个数大于等于函数需要的参数个数的时候则执行函数if(args.lengthlen){return fn.apply(this,args)}else{// 否则返回函数并且接收后面传入的参数return function(...args2){// 执行回调curried函数将参数合并传入下一次回调中return curried.apply(this,args.concat(args2))}}}
}
// 传入多个函数
function compose(...fns){// 当个数if(fns.length0){// console.log(-----等于0----);// compose不传参数的时候返回的是一个函数这个函数传的参数都返回return (args)args}if(fns.length1){// console.log(----等于1-----);// compose传入一个参数的话就返回这个函数return fns[0]}// compose传入两个及两个以上函数的时候使用reduce将作为参数的函数从右往左执行return fns.reduce((pre,cur)(...args)pre(cur(...args)))
}var headcurry(function(x){return x[0]
})
var splitcurry(function(rules,str){return str.split(rules)
})
var toUpperCasecurry(function(str){return str.toUpperCase()
})
var mapcurry(function(f,arr){return arr.map(f)
})
var joincurry(function(f,arr){return arr.join(f)
})
var initialscompose(join(. ),map(compose(toUpperCase,head)),split( ))console.log(initials(hunter stockton thompson))debug
示例一
const curryrequire(lodash).curryvar reversecurry(function(arr){return arr.reverse()
})
var mapcurry(function(f,arr){return arr.map(f)
})
var angrycurry(function(str){return str.toUpperCase()!
})const composefunction(...fns){if(fns.length0) return (args)argsif(fns.length1) return fns[0]return fns.reduce((pre,cur)(...args)pre(cur(...args)))
}// var latincompose(map,angry,reverse) //错误执行angry接收的是一个字符串// 但是reverse执行完后的结果是数组传给angry会报错所以应该把angry当做参数传给map用作map的规则才对
var latincompose(map(angry),reverse)
console.log(latin([frog,eyes]))示例二
const curryrequire(lodash).curryfunction compose(...fns){if(fns.length0) return (args)argsif(fns.length1) return fns[0]return fns.reduce((pre,cur)(...args)pre(cur(...args)))
}var replacecurry(function(what,replacement,str){return str.replace(what,replacement)
})var splitcurry(function(f,str){return str.split(f)
})var toLowercurry(function(x){return x.toLowerCase()
})
var joincurry(function(f,arr){return arr.join(f)
})
var mapcurry(function(f,arr){return arr.map(f)
})// var dasherizecompose(join(-,toLower,split( ),replace(/\s{2,}/ig, )))
// 报错由于toLower接收的是字符串而不是数组所以应该先用map调用一下他
var dasherizecompose(join(-),map(toLower),split( ),replace(/\s{2,}/ig, ))console.log(dasherize(The world is a vampire));模板字符串
css in js方案
题外话 建议大家往react方向学react技术点很多选择很多 比如 样式体系
less,scss,其实目前看有点过时了
现在主流的样式体系方案
module css中规中矩的css in js运行时的开销性能稍差tailwind css,极致性能
如果要做 SSR 服务端渲染, 一方面css in js 相对不好处理但是有对应的方案 而且比较符合正常开发者定义组件维护对应的内容 另一方面官方推荐的是 module css,tailwind css
// 用在 css in js 的方案里const styled {div: function (strings) {const divDom document.createElement(div); //nodejs不能执行strings.forEach((str) {const s str.split(;);for (const kv of s) {const [key, value] kv.split(:);divDom.style[key] value; //nodejs不能执行console.log( ~ styled.key:, key, value);}});// return react component //React中返回return divDom;},h1: function (...args) {console.log( ~ styled.args:, args);},
};
const Div styled.divcolor: red;font-size: 20px;
;
如果要了解某个代码在编译器中处理完后得到什么内容的话可以使用babel去看 链接: link 看具体原理内部具体是怎么做的 箭头函数
问题
不能定义构造器不能newthis指向的是外部的作用域没有argumentsthis不能绑定(apply,bind,call)
生成器 generator
应用场景
大家对于异步的处理是不是都基于 async、await来做的
// async await的实现就是借助 promise generator
const getData async (){const resPromise.resolve(1)return res
}async function test(){await getData()
}反射 Reflect
Reflect.set(target, key, value, receiver); 重点看看 receiver接收者决定this指向
// 用来劫持对象的逻辑const handler {get(target, key, receiver) {console.log(get, key, receiver);// 值的获取是不是就是我们所谓的依赖收集// track()// return target[key];return Reflect.get(target, key);},set(target, key, value, receiver) {console.log(set, value);// target[key] value;Reflect.set(target, key, value, receiver);// 值的设置就是我们所谓的更新操作// trigger()},
};// Vue3.0的响应式原理const target {a: 1,get b() {return this.a;},
};// 劫持这个 target 对象的熟悉
const reactiveTarget new Proxy(target, handler);
console.log(reactiveTarget:, reactiveTarget.a, reactiveTarget.b);reactiveTarget.a 10;console.log(reactiveTarget:, reactiveTarget.a, reactiveTarget.b);console.log(Reflect.get(target, a));
console.log(Reflect.get(target, b, { b: null111, a: null222 }));o?.a是什么意思 在JavaScript中o?.a是一种新的语法称为可选链操作符Optional Chaining Operator。这个操作符用于在访问对象属性时进行安全的操作即使对象的某个属性不存在或者为null或undefined也不会导致运行时错误。 具体来说o?.a表示如果对象o存在且具有属性a则返回o.a的值如果对象o不存在或者属性a不存在则返回undefined而不会抛出错误。 这种语法的引入使得代码更加简洁并且更安全特别是在处理深层嵌套的对象属性时。