闭包

应闭包用

  1. 如果在一个大函数中有一些代码块能够独立出来, 我们常常把这些代码块封装在独立的小函数里面。独立出来的小函数有助于代码复用,如果这些 小函数有一个良好的命名,它们本身也起到了注释的作用。如果这些小函数不需要在程序的其他地方使用,最好是把它们用闭包封闭起来。

命令模式

把请求封装成对象,从而分离请求的发起者和请求的接收者之间的耦合关系。在命令执行前,在命令对象中植入命令的接收者。

将所有可执行的命令封装到一个对象中

  1. var Dog={
  2. bark:()=>{
  3. console.log('汪')
  4. },
  5. eat:()=>{
  6. console.log('咬')
  7. }
  8. }

然后抽象出一个控制器

  1. var createCommand=function(receiver){
  2. return {
  3. bark:receiver.bark,
  4. eat:receiver.eat,
  5. }
  6. }
  7. for(var i=0,type;type=['a','b','c'][i++];){
  8. (function(type){
  9. Type['is'+type]=function(obj){
  10. return Object.prototype.toString.call(obj)==='[object '+type+']'
  11. })(type)
  12. }

这个例子还没搞太明白。。。

AOP

面向切面编程,抽象出一些和核心业务逻辑模块无关的功能。这些功能会以“动态织入”的方式掺入业务逻辑模块中。
如,可以通过增加原型方法来装饰一个现有的函数。

高阶函数的应用

柯里化

又称部分求值,利用闭包将求到的部分结果保存起来

  1. var currying=function(fn){
  2. var args=[]
  3. return function(){
  4. if(arguments.length==0){
  5. return fn.apply(this,args)
  6. }else{
  7. [].push.apply(args,arguments)
  8. return arguments.callee // es5后严格模式已禁用
  9. }
  10. }
  11. }

去柯里化

提取出this,可以使一些原生的方法变成泛化的方法

  1. Function.prototype.uncurrying=function(){
  2. var self = this
  3. return function(){
  4. var obj=Array.prototype.shift.call(arguments) // 拿到泛化的this
  5. return self.apply(obj, arguments)
  6. }
  7. }

节流函数

分批执行函数

相当于是手动异步,将一个可能会阻塞很长时间的程序分成几个异步来执行,当然前提是行为是重复性的。

  1. var timeChunk=function(ary,fn,count){
  2. var obj, t
  3. var len=ary.length //所有数据
  4. var start=function(){ // 执行函数,每次只处理一定长度的数据
  5. for(var i=0;i<Math.min(count||1,ary.length);i++){
  6. var obj=ary.shift() //每次取出一个数据
  7. fn(obj) // 并执行
  8. }
  9. }
  10. return function(){
  11. t=setInterval(function(){
  12. if(ary.length===0){ // 数据已被处理完
  13. return clearInterval(t)
  14. }
  15. start()
  16. },200)
  17. }
  18. }

惰性载入

一个相当神奇的写法,需要执行该逻辑的时候才会执行

  1. // 该函数执行一次后,addEvent的指向才被确定
  2. var addEvent = function (elem, type, handler) {
  3. if (window.addEventListener) {
  4. addEvent = function (elem, type, handler) {
  5. elem.addEventListener(type, handler, false)
  6. }
  7. } else if (window.attachEvent) {
  8. addEvent = function (elem, type, handler) {
  9. elem.attachEvent(`on${ type}`, handler)
  10. }
  11. }
  12. addEvent(elem, type, handler)
  13. }