闭包
应闭包用
如果在一个大函数中有一些代码块能够独立出来, 我们常常把这些代码块封装在独立的小函数里面。独立出来的小函数有助于代码复用,如果这些 小函数有一个良好的命名,它们本身也起到了注释的作用。如果这些小函数不需要在程序的其他地方使用,最好是把它们用闭包封闭起来。
命令模式
把请求封装成对象,从而分离请求的发起者和请求的接收者之间的耦合关系。在命令执行前,在命令对象中植入命令的接收者。
将所有可执行的命令封装到一个对象中
var Dog={bark:()=>{console.log('汪')},eat:()=>{console.log('咬')}}
然后抽象出一个控制器
var createCommand=function(receiver){return {bark:receiver.bark,eat:receiver.eat,}}for(var i=0,type;type=['a','b','c'][i++];){(function(type){Type['is'+type]=function(obj){return Object.prototype.toString.call(obj)==='[object '+type+']'})(type)}
AOP
面向切面编程,抽象出一些和核心业务逻辑模块无关的功能。这些功能会以“动态织入”的方式掺入业务逻辑模块中。
如,可以通过增加原型方法来装饰一个现有的函数。
高阶函数的应用
柯里化
又称部分求值,利用闭包将求到的部分结果保存起来
var currying=function(fn){var args=[]return function(){if(arguments.length==0){return fn.apply(this,args)}else{[].push.apply(args,arguments)return arguments.callee // es5后严格模式已禁用}}}
去柯里化
提取出this,可以使一些原生的方法变成泛化的方法
Function.prototype.uncurrying=function(){var self = thisreturn function(){var obj=Array.prototype.shift.call(arguments) // 拿到泛化的thisreturn self.apply(obj, arguments)}}
节流函数
分批执行函数
相当于是手动异步,将一个可能会阻塞很长时间的程序分成几个异步来执行,当然前提是行为是重复性的。
var timeChunk=function(ary,fn,count){var obj, tvar len=ary.length //所有数据var start=function(){ // 执行函数,每次只处理一定长度的数据for(var i=0;i<Math.min(count||1,ary.length);i++){var obj=ary.shift() //每次取出一个数据fn(obj) // 并执行}}return function(){t=setInterval(function(){if(ary.length===0){ // 数据已被处理完return clearInterval(t)}start()},200)}}
惰性载入
一个相当神奇的写法,需要执行该逻辑的时候才会执行
// 该函数执行一次后,addEvent的指向才被确定var addEvent = function (elem, type, handler) {if (window.addEventListener) {addEvent = function (elem, type, handler) {elem.addEventListener(type, handler, false)}} else if (window.attachEvent) {addEvent = function (elem, type, handler) {elem.attachEvent(`on${ type}`, handler)}}addEvent(elem, type, handler)}
