• Tags , ,
  •         
  • www.breakyizhan.com
  •    

    什么是钩子机制?使用钩子机制有什么好处?

    钩子机制也叫hook机制,或者你可以把它理解成一种匹配机制,就是我们在代码中设置一些钩子,然后程序执行时自动去匹配这些钩子;这样做的好处就是提高了程序的执行效率,减少了if else 的使用同事优化代码结构。由于js是单线程的编程语言,所以程序的运行效率在前端开发是比较重要的,在开发中我们秉承如果能用switch case 的地方就不要用if else 可以用hook实现的尽量使用hook机制去实现。
    hook机制也就是钩子机制,由表驱动实现,常用来处理多种特殊情况的处理。我们预定义了一些钩子,在常用的代码逻辑中去适配一些特殊的事件,这样可以让我们少些很多if else语句。

    JS中的钩子(hook)机制与实现

    JS中的钩子(hook)的例子

    JS中的钩子(hook)的例子1:
    例如我们在向后台进行ajax请求的时候,后台经常会返回我们一些常见的错误码,如:001代表用户不存在,002代表用户密码输入错误。003代表用户被锁定。这个时候我们要将错误友好的提示给用户。这个时候我们该怎样实现呢?
    一般的写法可能是:

    $.ajax(option,function(result){
        var errCode = result.errCode ;//错误码
        if(errCode){
              if(errCode =='001'){
                   alert("用户不存在")
                }else if(errCode =='002'){
                   alert("密码输入错误")
                }else if(errCode =='003'){
                  alert("用户被锁定")
                }
        }else{
               //登录成功
       }
    },function(err){
    
    })
    

    这样写其实是比较low低,稍微有点经验的可能会使用switch case来实现,但是这个两种写法都无法避免一个问题就是如果我的错误码特别多,那得写多少个if else和case 啊?但是如果使用hook写法的话就会简单好多,
    首先我们先声明一个错误码钩子列表

    var codeList  = {
       "001":"用户不存在",
       "002":"密码输入错误",
       "003":"用户被锁定"
    }
    $.ajax(option,function(result){
        var errCode = result.errCode ;//错误码
          if(!errCode){
              alert(codeList[errCode]);
          }else{
              //登录成功
          }
    },function(err){
    
    })
    

    这样写的话代码结构更加清楚明了。这个例子是最简单的应用了的了。

    JS中的钩子(hook)的例子2:

    举个高考加分的例子,比如获得过全国一等奖加20分,二等奖加10分,三等奖加5分。使用if else的话:

    function student(name,score,praise){
        return {
            name:name,
            score:score,
            praise:praise
        }
    }
    function praiseAdd(students){
        var results={};
        for (var i in students){
            var curStudent=students[i];
            var ret=curStudent.score;
            if(curStudent.praise==1){
                ret+=20;
            }else if(curStudent.praise==2){
                ret+=10;
            }else if(curStudent.praise==3){
                ret+=5;
            }
            results[curStudent.name]=ret;
        } 
        return results;
    
    }
    var liming= student("liming",70,1);
    var liyi= student("liyi",90,2);
    var liuwei= student("liuwei",80,3);
    var ertuzi= student("ertuzi",85,3);
    
    var result=praiseAdd([liming,liyi,liuwei,ertuzi]);
    for(var i in result){
        console.log("name:"+i+",score:"+result[i]);
    }
    
    

    如果是用钩子机制呢

    function student(name,score,praise){
        return {
            name:name,
            score:score,
            praise:praise
        }
    }
    var  praiseList={
        1:20,
        2:10,
        3:5
    } 
    function praiseAdd(students){
        var results={};
        for (var i in students){
            var curStudent=students[i];
            var ret=curStudent.score;
            if(praiseList[curStudent.praise])
            ret+=praiseList[curStudent.praise];
            results[curStudent.name] = ret;
        } 
        return results;
    
    }
    var liming= student("liming",70,1);
    var liyi= student("liyi",90,2);
    var liuwei= student("liuwei",80,3);
    var ertuzi= student("ertuzi",85,3);
    
    var result=praiseAdd([liming,liyi,liuwei,ertuzi]);
    for(var i in result){
        console.log("name:"+i+",score:"+result[i]);
    }
    
    

    所以简单的说,其实钩子机制就是利用一张表去匹配,而不是一次次的if条件判断。

    Jquery 中使用hook机制的例子

    Jquery 中使用hook机制的例子1:

    在Jquery 中hook机制被大量的使用,这里我们就Jquery中判断变量类型的type方法来具体看一下
    通常我们在js中判断一个变量的数据类型?首先会想到type of 和 instanceof
    如果是基本类型我们可以直接使用typeof,但是这种方式只能判断基本数据类型,如果是对象,它返回结果都市Object,如果变量是null它返回的也是Object。这个时候我们要准确的判断一般的写法可能会是:

      function type(obj){
          var type = "";
          if(obj==null){
              type = null;
          }else{
             type = obj.a.constructor.toString().split("(")[0].split(" ")[1]
          }
          return type;
      }
    
    

    在jquery中的实现是:

    var class2type={};
    var toString = Object.prototype.toString;
    jQuery.each("Boolean Number String Function Array Date RegExp Object Error Symbol",function(index,name){
      class2type["Object"+" name"]==name.toLowerCase();
    })
    type:function(obj){
       if(obj==null){
          return obj+""; 
       }
       return typeof obj =="Object"||typeof obj ==="function"?class2type[toString.call(obj)]|||"object":typeof obj
    }
    
    

    上面代码中
    class2type = { ‘[object Boolean]’: ‘boolean’, ‘[object Number]’: ‘number’, ‘[object String]’: ‘string’, ‘[object Function]’: ‘function’, ‘[object Undefined]’: ‘undefined’, ‘[object Null]’: ‘null’, ‘[object Array]’: ‘array’, ‘[object Date]’: ‘date’, ‘[object RegExp]’: ‘regexp’, ‘[object Object]’: ‘object’, ‘[object Error]’: ‘error’};
    设置一个类型钩子对象
    toString.call(obj)就是Object.prototype.toString.call(arg)来细致判断obj的类型。在这里则转换成对象对应索引是否在class2type 中存在相应value,若存在则返回value判断,若不存在则返回object类型。
    这样就实现了类型的判断。

    Jquery 中使用hook机制的例子2:

    jQuery中大量的使用了钩子机制去做一些兼容。拿$.type方法为例:

    (function(window, undefined) {
        var
            // 用于预存储一张类型表用于 hook
            class2type = {};
     
        // 原生的 typeof 方法并不能区分出一个变量它是 Array 、RegExp 等 object 类型,jQuery 为了扩展 typeof 的表达力,因此有了 $.type 方法
        // 针对一些特殊的对象(例如 null,Array,RegExp)也进行精准的类型判断
        // 运用了钩子机制,判断类型前,将常见类型打表,先存于一个 Hash 表 class2type 里边
        jQuery.each("Boolean Number String Function Array Date RegExp Object Error".split(" "), function(i, name) {
            class2type["[object " + name + "]"] = name.toLowerCase();
        });
     
        jQuery.extend({
            // 确定JavaScript 对象的类型
            // 这个方法的关键之处在于 class2type[core_toString.call(obj)]
            // 可以使得 typeof obj 为 "object" 类型的得到更进一步的精确判断
            type: function(obj) {
     
                if (obj == null) {
                    return String(obj);
                }
                // 利用事先存好的 hash 表 class2type 作精准判断
                // 这里因为 hook 的存在,省去了大量的 else if 判断
                return typeof obj === "object" || typeof obj === "function" ?
                    class2type[core_toString.call(obj)] || "object" :
                    typeof obj;
                  
            }
        })
    })(window);
    
    

    core_toString是定义了一个空对象,然后保存toString()方法。

    var core={};
    var core_toString=core.toString;
    

    这样后边就可以直接调用Object.prototype.toString()方法,而不用每次都再去原型链上去找,节约了很多开销,jQuery中做了很多这样的变量保存。

     
    转载请保留页面地址:https://www.breakyizhan.com/js/6513.html