成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專欄INFORMATION COLUMN

1625行,解開 underscore.js 的面紗 - 第六章

v1 / 2311人閱讀

摘要:用來構成和兩個函數(shù),主要針對的是為了將函數(shù)調(diào)用模式更改為構造器調(diào)用和方法調(diào)用。通過函數(shù)設定時間為毫秒后執(zhí)行函數(shù)的回調(diào)函數(shù),用以達到在規(guī)定時間毫秒時執(zhí)行函數(shù)的目的,并且規(guī)定時間內(nèi)只執(zhí)行一次函數(shù)。

北京的雨已經(jīng)斷斷續(xù)續(xù)下了好久,昏昏欲睡的躲在家里不愿意出門,火影忍者快要結束了,一拳超人第二季據(jù)說還要等好多年,勇者大冒險貌似斷更了,我又是在不喜歡海賊王的畫風,所以,我該看什么好呢。

  var executeBound = function(sourceFunc, boundFunc, context, callingContext, args) {
    if (!(callingContext instanceof boundFunc)) return sourceFunc.apply(context, args);
    var self = baseCreate(sourceFunc.prototype);
    var result = sourceFunc.apply(self, args);
    if (_.isObject(result)) return result;
    return self;
  };

executeBound 用來構成 _.bind_.partial 兩個函數(shù),主要針對的是為了將函數(shù)調(diào)用模式更改為構造器調(diào)用和方法調(diào)用。

  _.bind = restArgs(function(func, context, args) {
    if (!_.isFunction(func)) throw new TypeError("Bind must be called on a function");
    var bound = restArgs(function(callArgs) {
      return executeBound(func, bound, context, this, args.concat(callArgs));
    });
    return bound;
  });

也許我們可以參考下 Function.prototype.bind(),_.bind 函數(shù)這個需要仔細講一下了,先化簡:

    _.bind = function(func, context, args) {
        var length = arguments.length - 2;
        args = Array(length);
        for (var index = 0; index < length; index++) {
            args[index] = arguments[index + startIndex];
        }
        if (!_.isFunction(func)) throw new TypeError("Bind must be called on a function");
        var bound = function(args_2){
            args_2 = Array(arguments.length);
            for (var index = 0; index < arguments.length; index++) {
                args_2[index] = arguments[index];
            }
            (function(sourceFunc, boundFunc, context, callingContext, args) {
                if (!(callingContext instanceof boundFunc)) return sourceFunc.apply(context, args);
                var self = baseCreate(sourceFunc.prototype);
                var result = sourceFunc.apply(self, args);
                if (_.isObject(result)) return result;
                return self;
          })(func, bound, context, this, args.concat(args_2));
        };
        return bound;
    };

這樣看上去是不是直白很多,官網(wǎng)給它的定義是:綁定函數(shù) function 到對象 object 上, 也就是無論何時調(diào)用函數(shù), 函數(shù)里的 this 都指向這個 object.任意可選參數(shù) arguments 可以傳遞給函數(shù) function , 可以填充函數(shù)所需要的參數(shù),這也被稱為 partial application。對于沒有結合上下文的partial application綁定,請使用partial。,怎么聽怎么別扭,我們可以這樣理解:_.bind 函數(shù)是為其傳參中的 function 的 this 上綁定相應對象屬性,并且同時進行 function 的參數(shù)傳入,而其中最關鍵的就是在執(zhí)行這一系列動作的同時將傳入?yún)?shù) context 綁定到了指向它的 Function 對象本身的 this 身上(可參考函數(shù)調(diào)用模式與方法調(diào)用模式的區(qū)別)。官網(wǎng)有個栗子:

   var func = function(greeting){ return greeting + ": " + this.name };
   func = _.bind(func, {name: "moe"}, "hi");
   func();
   {"hi: moe"}

實際上呢它等同于:

   var func = _.bind(function(greeting){
           return greeting + ": " + this.name;
       },
       {name: "moe"},
       "hi"
   );
   func();
   {"hi: moe"}

結合前面簡化的 _.bind 代碼示例可知這個函數(shù)的核心思想就是先通過 _.bind 初始化的時候優(yōu)化第3+個參數(shù) args,為什么叫 3+ 呢,因為從第三個參數(shù)開始,可能是不限定的參數(shù)數(shù)量,所以從第三個開始到最后一個參數(shù)同一處理為一個數(shù)組 args。
緊接著就是執(zhí)行剛才初始化過后的函數(shù)了,當 func(); 的時候也就是開始執(zhí)行 _.bind 中的 bound 函數(shù)。bound 允許傳遞參數(shù)并且其參數(shù)會被 push 到 args 中,具體實現(xiàn)參看上面的簡化代碼 args.concat(args_2)。這里我們有幾個需要注意的點,其一是 callingContext instanceof boundFunc,之前我們講過 instanceof 的神奇用法,在這里它用與判斷 bound 中的 this 的指向是否繼承于 bound。我們一定知道 this 指向的四個情況,如下:

var obj = {};
var func = function (){console.log(this);};
func();
new func();
obj.func = func;
obj.func();
func.apply(["this is parameter"]);
func.call(["this is parameter"]);

輸出結果為:

Window {external: Object, chrome: Object, document: document, alogObjectConfig: Object, alogObjectName: "alog"…}
func {}
Object {}
["this is parameter"]
["this is parameter"]

分別代表四種情況:

函數(shù)調(diào)用模式:指向 Global,瀏覽器客戶端即 window;

方法調(diào)用模式:指向?qū)ο蟊旧恚?/p>

構造器調(diào)用模式:指向為新構造的對象,繼承自原 Function 對象;

apply 或 call 調(diào)用模式:指向傳入的參數(shù)。

這里還有一些非常好的資料:this、Understanding JavaScript Function Invocation and "this",在這里我要說一下我在推庫上看到一篇關于 this 的介紹文章說:“比較系統(tǒng)的分類是《JavaScript語言精粹》中的,分為函數(shù)調(diào)用模式(this綁定全局對象window)和方法調(diào)用模式(this綁定調(diào)用方法的主體)”,我把《JavaScript語言精粹》這本書從頭到尾翻看了好幾遍,實際上它原文是這樣說的:“在 JAVASCRIPT 中一共有4種調(diào)用模式:方法調(diào)用模式、函數(shù)調(diào)用模式、構造器調(diào)用模式和 apply 調(diào)用模式?!?/b>,具體敘述在原書的P27~P30頁,感興趣的朋友可以看下,在給大家看一個彩蛋,嚴格模式下的 this。緊接上文,當 bound 中的 this 的指向是否繼承于 bound 函數(shù)的時候說明是使用了 new 關鍵字的構造器調(diào)用模式調(diào)用了 _.bind 函數(shù),則繼續(xù)執(zhí)行 executeBound 函數(shù)中的 baseCreate 創(chuàng)建基本函數(shù)然后進行一系列的操作,其實說到底 baseCreate 的目的就是為了保證傳入?yún)?shù) Function 的 this 的干凈。
另外一個需要注意的地方是官網(wǎng)示例的暗示(特蛋疼的暗示),我擴展了一下:

   var func = function(){ return JSON.stringify(arguments) + ": " + this.name };
   func = _.bind(func, {name: "moe"}, "hi");
   func();
   func = _.bind(func, {name: "moe2"}, "hi2");
   func();

輸出結果:

   "{"0":"hi"}: moe"
   "{"0":"hi","1":"hi2"}: moe"

可能有些不明就里的同學會問這是為什么啊,怎么 this.name 的值沒有變化呢。實際上我們第一個 _.bind 是正常的函數(shù)綁定,而第二個 func = _.bind(func, {name: "moe2"}, "hi2"); 是將上一個 _.bind 作為了 Function 參數(shù)傳入到了新的 _.bind 中,而本來的函數(shù) func 作為第一個 _.bind 的 func 參數(shù)一直傳遞到第二個 _.bind 中,但是中間的 this.name 卻被綁定到了第一個 _.bind 上面而不是第一個 _.bind 中的 func 上。有一點繞口。用個代碼介紹下,第二個 _.bind 的情況是這樣子的:

 func = _.bind(function(
       function(greeting){
           return greeting + ": " + this.name;
      },
       context,
       args
   ) {
        var length = arguments.length - 2;
        args = Array(length);
        for (var index = 0; index < length; index++) {
            args[index] = arguments[index + startIndex];
        }
        if (!_.isFunction(func)) throw new TypeError("Bind must be called on a function");
        var bound = function(args_2){
            args_2 = Array(arguments.length);
            for (var index = 0; index < arguments.length; index++) {
                args_2[index] = arguments[index];
            }
            (function(sourceFunc, boundFunc, context, callingContext, args) {
                if (!(callingContext instanceof boundFunc)) return sourceFunc.apply(context, args);
                var self = baseCreate(sourceFunc.prototype);
                var result = sourceFunc.apply(self, args);
                if (_.isObject(result)) return result;
                return self;
          })(func, bound, context, this, args.concat(args_2));
        };
        return bound;
    },
       {name: "moe2"},
       "hi2"
   );

所以 _.bind 一定要遵循正確的用法,不然真的出錯了可能調(diào)試都不好發(fā)現(xiàn)問題,多層回調(diào)嵌套的時候一層套一層,很麻煩。

  _.partial = restArgs(function(func, boundArgs) {
    var placeholder = _.partial.placeholder;
    var bound = function() {
      var position = 0, length = boundArgs.length;
      var args = Array(length);
      for (var i = 0; i < length; i++) {
        args[i] = boundArgs[i] === placeholder ? arguments[position++] : boundArgs[i];
      }
      while (position < arguments.length) args.push(arguments[position++]);
      return executeBound(func, bound, this, this, args);
    };
    return bound;
  });

_.partial 函數(shù)的核心思想與 _.bind 相同,都是為了解決 this 指向的問題,區(qū)別在于 _.partial 不需要對 this 上的值做什么處理。用法上我覺得 _.partial 看上去更怪異一些,也許用來做一些特定的計算可能更合適些。

  _.partial.placeholder = _;

設置 _.partial.placeholder_。

  _.bindAll = restArgs(function(obj, keys) {
    keys = flatten(keys, false, false);
    var index = keys.length;
    if (index < 1) throw new Error("bindAll must be passed function names");
    while (index--) {
      var key = keys[index];
      obj[key] = _.bind(obj[key], obj);
    }
  });

這里我們看到 _.bindAll 函數(shù)官網(wǎng)的示例就有點糊涂了:

   var buttonView = {
     label  : "underscore",
     onClick: function(){ console.log("clicked: " + this.label); },
     onHover: function(){ console.log("hovering: " + this.label); }
   };
   _.bindAll(buttonView, "onClick", "onHover");
   buttonView.onClick();
   clicked: underscore

我們當然知道結果是 clicked: underscore,那么執(zhí)行 _.bindAll(buttonView, "onClick", "onHover"); 的意義在哪呢,所以說這又是官網(wǎng)坑人的地方了,_.bindAll 的本意是將其傳入的第二個及以后的參數(shù)放到一個共同的上下文環(huán)境里面執(zhí)行,從而達到 this 指向其第一個參數(shù)的本身的目的,而官網(wǎng)的示例為方法調(diào)用模式,this 指向已經(jīng)是 Object 本身了所以看不到變化,但是我們在瀏覽器控制臺查看的話應該能知道 this 上多了 [[TargetFunction]]: function ()、[[BoundThis]]: Object[[BoundArgs]]: Array[0] 三個參數(shù)并且 [[BoundThis]] 恰好是 Object。閑來無事這好看到有人也寫了這個問題并舉證了一個示例,詳見 Understanding bind and bindAll in Backbone.js。我 cope 一下:

   function Developer(skill) {
     this.skill = skill;
     this.says = function(){
       console.log(this.skill + " rocks!");
     }
   }
   var john = new Developer("Ruby");
   _.bindAll(john, "says");
   var func = john.says;
   func(); //Ruby rocks!

這個函數(shù)調(diào)用模式的示例正好答疑了 this 指向已經(jīng)被改變的這個問題。

  _.memoize = function(func, hasher) {
    var memoize = function(key) {
      var cache = memoize.cache;
      var address = "" + (hasher ? hasher.apply(this, arguments) : key);
      if (!_.has(cache, address)) cache[address] = func.apply(this, arguments);
      return cache[address];
    };
    memoize.cache = {};
    return memoize;
  };

_.memoize 函數(shù)更像是一個可以緩存第一次執(zhí)行結果的遞歸函數(shù),我們從源碼中可以看到 memoize.cache = {}; 就是用來存儲計算結果的容器,這里面比較有意思的是 hasher 這個參數(shù),官網(wǎng)釋義: hashFunction,實際上就是通過 hashFunction 對傳入的 key 值進行處理然后放到 memoize.cache = {}; 中,至于怎么處理 hash 也好、md5 也好、或者什么其他的計算加密真值判斷增加對象等等都可以通過 hasher 這個傳入的回調(diào)進行擴展。

————————— 疲憊的分割線 ———————————
這幾天北京總在下雨,身體特別的疲憊,狀態(tài)也不怎么好,所以今天才開始繼續(xù)更新。
————————— END ———————————

  _.delay = restArgs(function(func, wait, args) {
    return setTimeout(function() {
      return func.apply(null, args);
    }, wait);
  });

_.delay 函數(shù)用于處理定時器相關函數(shù),原理是通過 setTimeout 進行二次封裝,比較關鍵的就是 args 參數(shù)通過 restArgs 函數(shù)處理為一個數(shù)組,方便了下一步的 func.apply(null, args); 傳值。

  _.defer = _.partial(_.delay, _, 1);

_.defer 這個函數(shù)我們首先可以看到內(nèi)部應用了 _.partial 并且中間傳入?yún)?shù) _,這意味著當 _.defer 執(zhí)行的時候傳入的參數(shù)會被補全到 _.partial 內(nèi)部 bound 中的 args[0] 位置,而此時 args 的值為 [func, 1]并將它傳給 _.delay 函數(shù),即 _.delay.apply(null, args);,用著這種方式曲線的設置 setTimeout 函數(shù)的 wait = 1,目的就是處理代碼復用問題,不然的話完全可以改裝一下 _.delay 函數(shù)可以更簡單的實現(xiàn)這一功能。

  _.throttle = function(func, wait, options) {
    var timeout, context, args, result;
    var previous = 0;
    if (!options) options = {};
    var later = function() {
      previous = options.leading === false ? 0 : _.now();
      timeout = null;
      result = func.apply(context, args);
      if (!timeout) context = args = null;
    };
    var throttled = function() {
      var now = _.now();
      if (!previous && options.leading === false) previous = now;
      var remaining = wait - (now - previous);
      context = this;
      args = arguments;
      if (remaining <= 0 || remaining > wait) {
        if (timeout) {
          clearTimeout(timeout);
          timeout = null;
        }
        previous = now;
        result = func.apply(context, args);
        if (!timeout) context = args = null;
      } else if (!timeout && options.trailing !== false) {
        timeout = setTimeout(later, remaining);
      }
      return result;
    };
    throttled.cancel = function() {
      clearTimeout(timeout);
      previous = 0;
      timeout = context = args = null;
    };
    return throttled;
  };

_.throttle 函數(shù)可以限制和控制其參數(shù) func 的執(zhí)行次數(shù)和執(zhí)行時間,思想就是通過 wait、now、previous 和 remaining 進行判斷然后分別執(zhí)行相應的策略。

wait:使用 _.throttle 函數(shù)時傳入的時間標識,在每個 wait 毫秒時間段內(nèi)最多且一定調(diào)用一次該函數(shù)。

now:使用 _.now() 函數(shù)獲取當前時間戳。

previous:用來緩存函數(shù)執(zhí)行時的時間戳,用于后面與下一次執(zhí)行時的時間戳進行相關判斷。

remaining:緩存 wait - (now - previous) 的差值。

我們在看官網(wǎng)介紹可以知道 _.throttle 傳遞的 options 分四種情況(默認是 {leading:false,trailing:false}):

{leading:true,trailing:true}:從實例化 _.throttle 的時間開始到執(zhí)行實例化的函數(shù)的時間為止,中間的差值定義為 now - previous,進而得出設定的時間 wait 與 now - previous 的差值 remaining,從而決定怎么執(zhí)行函數(shù)。參考 世紀之光 的很有趣的說法,就是第一次可以立即執(zhí)行,第二次開始將在每 wait 時間內(nèi)只允許執(zhí)行一次,為什么會第一次立即執(zhí)行呢,因為大家設置的 wait 一般都不會太大,所以頁面加載過程中一般已經(jīng)執(zhí)行了 _.throttle 的實例化,也就是說其 remaining <= 0,而后面如果一直執(zhí)行函數(shù),那么就開始 0 < remaining <= wait 模式了,

{leading:false,trailing:false}:這種情況下比較有意思的是 previous 這個參數(shù),在實例化 _.throttle 的時候,previous = 0,利用了 !0 === true 的特性使 _.throttle 內(nèi)部并沒有執(zhí)行回調(diào)函數(shù) func,所以第一次函數(shù)調(diào)用失敗,在第二次開始 previous = now (now 為第一次調(diào)用的時間戳),所以它也分為兩種情況:

{leading:true,trailing:false}:這種情況下是沒有 setTimeout 函數(shù)的,因為 leading:true,所以 previous 初始化為 0,意味著第一次執(zhí)行函數(shù)會立即執(zhí)行,兒后面就要遵循 remaining <= 0 || remaining > wait 才能執(zhí)行,也就是說只有第一執(zhí)行完畢后的時間超過了 wait 才能繼續(xù)調(diào)用函數(shù)才能執(zhí)行(調(diào)用是重點),以此類推。

{leading:false,trailing:true}:這種情況由于 leading:false,所以每次 previous 都等于當前調(diào)用函數(shù)時的時間戳,所以完美的不存在 remaining <= 0 || remaining > wait 的情況,由此只能通過 setTimeout 執(zhí)行回調(diào),所以遵循通過 setTimeout 函數(shù)設定時間為 remaining 毫秒后執(zhí)行 _.throttle 函數(shù)的回調(diào)函數(shù) func,用以達到在規(guī)定時間 wait 毫秒時執(zhí)行函數(shù)的目的,并且規(guī)定 wait 時間內(nèi)只執(zhí)行一次函數(shù)。

其實總結一下就是大概一下兩種都存在或者只存在其一的情況:

remaining <= 0:立即執(zhí)行 _.throttle 函數(shù)的回調(diào)函數(shù) func。

0 < remaining <= wait:通過 setTimeout 函數(shù)設定時間為 remaining 毫秒后執(zhí)行 _.throttle 函數(shù)的回調(diào)函數(shù) func,用以達到在規(guī)定時間 wait 毫秒時執(zhí)行函數(shù)的目的,并且規(guī)定 wait 時間內(nèi)只執(zhí)行一次函數(shù)。

 _.debounce = function(func, wait, immediate) {
   var timeout, result;
   var later = function(context, args) {
     timeout = null;
     if (args) result = func.apply(context, args);
   };
   var debounced = restArgs(function(args) {
     if (timeout) clearTimeout(timeout);
     if (immediate) {
       var callNow = !timeout;
       timeout = setTimeout(later, wait);
       if (callNow) result = func.apply(this, args);
     } else {
       timeout = _.delay(later, wait, this, args);
     }
     return result;
   });
   debounced.cancel = function() {
     clearTimeout(timeout);
     timeout = null;
   };
   return debounced;
 };

_.debounce 更像是 _.delay 的方言版,當 immediate = true 的時候通過 var callNow = !timeout = false 達到立即執(zhí)行回調(diào)函數(shù) func 的目的,并用 later 函數(shù)限制 規(guī)定 wait 時間內(nèi)不允許在調(diào)用函數(shù)(later 函數(shù)內(nèi)部 context = args = underfind,其實我們知道 var later = function(context, args) 這個條件是為 _.delay(later, wait, this, args) 準備的)。

  _.wrap = function(func, wrapper) {
    return _.partial(wrapper, func);
  };

_.wrap 的兩個參數(shù)理論上都要求是 Function,我們已經(jīng)知道 _.partial 是用來在 this 上下功夫的,雖然這里和 this 也沒什么太大關系,之所以這里應用了 _.partial 是為了讓 func 作為 wrapper 的第一個參數(shù)執(zhí)行,并且通過 executeBound 函數(shù)對函數(shù)調(diào)用模式方法調(diào)用模式做處理。

  _.negate = function(predicate) {
    return function() {
      return !predicate.apply(this, arguments);
    };
  };

_.negate 用來做真值判斷。

  _.compose = function() {
    var args = arguments;
    var start = args.length - 1;
    return function() {
      var i = start;
      var result = args[start].apply(this, arguments);
      while (i--) result = args[i].call(this, result);
      return result;
    };
  };

_.compose 用于將函數(shù)執(zhí)行結果進行傳遞,需要注意的是 var args = arguments; 中的 arguments 和 args[start].apply(this, arguments); 中的 arguments 并不相同就可以了。這個涉及到函數(shù)的執(zhí)行,當每一個函數(shù)執(zhí)行的時候都會形成一個內(nèi)部的上下文執(zhí)行環(huán)境(傳說叫 ExecutionContext,這個我還沒有考證過),在構建環(huán)境的同時生成 arguments 變量和作用域鏈表等等,這里不像敘述了。

  _.after = function(times, func) {
    return function() {
      if (--times < 1) {
        return func.apply(this, arguments);
      }
    };
  };

_.after 接受兩個參數(shù),Number 參數(shù)用來限定 _.after 實例化函數(shù)的執(zhí)行次數(shù),說白了就是只有當?shù)?Number 次執(zhí)行實例化函數(shù)的時候才會繼續(xù)執(zhí)行 func 回調(diào),這個用來處理遍歷 _.each 時某些情況很有用。

  _.before = function(times, func) {
    var memo;
    return function() {
      if (--times > 0) {
        memo = func.apply(this, arguments);
      }
      if (times <= 1) func = null;
      return memo;
    };
  };

_.before,與 _.after 相反,只在規(guī)定 Number 參數(shù)的次數(shù)內(nèi)以此執(zhí)行 _.before,超過之后結束。

  _.once = _.partial(_.before, 2);

_.once 創(chuàng)建一個只能調(diào)用一次的函數(shù)。到這里關于函數(shù)相關的源碼就結束了,說心里話很多地方看得懂不一定說的懂,說的懂也不一定用的懂,就拿這個 _.once 來講,它只用了 _.partial_.before 來做文章,用 _.before 限定只能執(zhí)行一次還好理解,那么為什么一定要用 _.partial 坐下處理呢,其目的真的只是為了讓 2 作為 _.before 的第一個參數(shù)進行傳遞過去并將 _.once 的傳參作為 arguments[1+] 傳入么,更深一層考慮,_.partial 函數(shù)是不是有處理過 _.once 傳遞過來的函數(shù)的作用域鏈和 this 相關的情況呢。

  _.restArgs = restArgs;

_.restArgs 將 restArgs 函數(shù)綁定到 _ 對象上。

文章版權歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請注明本文地址:http://systransis.cn/yun/79653.html

相關文章

  • 如何自制 JS 注釋文檔生成工具

    摘要:組件的選擇命令行工具首先我們需要一個命令行工具來方便的執(zhí)行命令,這里我們選擇組件,如果不喜歡使用且有能力的人完全可以通過組件自己封裝執(zhí)行命令函數(shù)。 對于一個成熟的項目而言,一定需要一個注釋文檔生成工具,我們有很多可選的開源項目,如jsdoc、yuidocjs 等等,擁有這些強大的工具我們完全可以勝任任何注釋方面的管理了么? 一個成熟的開發(fā)者都會知道不管怎么樣的項目都會在不同的開發(fā)條件下...

    Cristalven 評論0 收藏0
  • 1625,解開 underscore.js 面紗 - 第一章

    摘要:新出臺的則規(guī)定,包括六種原始類型和,還有一種,詳見數(shù)據(jù)類型和數(shù)據(jù)結構。用于返回一個由給定對象的所有可枚舉自身屬性的屬性名組成的數(shù)組,。接下來判斷數(shù)字進行相應的操作,其中有和兩個方法,詳見和。 一直想寫一篇這樣的文章,于是心動不如行動,這里選擇的是 Underscore.js 1.8.3 版本,源碼注釋加在一起1625行。 Underscore.js 1.8.3 http://unde...

    MockingBird 評論0 收藏0
  • 1625,解開 underscore.js 面紗 - 第二章

    摘要:第四個判斷如果是對象執(zhí)行返回一個斷言函數(shù),用來判定傳入對象是否匹配指定鍵值屬性。都不匹配最后執(zhí)行,返回傳入的對象的屬性。設置的值并生成函數(shù),等同于,使具有屬性且有值則返回,否則返回,這是一個判斷函數(shù)。 在第二小章節(jié)里面我按照源碼順序介紹幾個方法,源碼緊接著第一章繼續(xù): var builtinIteratee; builtinIteratee,內(nèi)置的 Iteratee (迭代器)。...

    yuxue 評論0 收藏0
  • 1625,解開 underscore.js 面紗 - 第四章

    摘要:接收三個參數(shù)分別為回調(diào)和,其中與是可選參數(shù)。官網(wǎng)釋義排序一個列表組成一個組,并且返回各組中的對象的數(shù)量的計數(shù)。類似,但是不是返回列表的值,而是返回在該組中值的數(shù)目。 繼續(xù)前面的內(nèi)容,前文我們提到了很多方法的講解,其實到這里就已經(jīng)差不多了,因為大部分代碼其實都是套路,一些基礎函數(shù)再靈活變化就可以組成很多實用的功能。 _.sortBy = function(obj, iteratee,...

    zhaochunqi 評論0 收藏0
  • 1625解開 underscore.js 面紗 - 第三章

    摘要:傳入值進行判斷以此決定函數(shù),將三個參數(shù)包括回調(diào)傳入中其中回調(diào)函數(shù)充當?shù)鬟M行真值檢測,最后。是從一個中隨機返回值,并且返回值受限于這個參數(shù),如果沒有傳入或者傳入了則執(zhí)行語句,目的是將判斷處理之后返回單一值。 今天繼續(xù)上次的內(nèi)容,之前我們講到了 reduce 的用法,其實我覺得用法倒是其次的關鍵是作者實現(xiàn) reduce 過程中所靈活用到的函數(shù)處理方法,我們只要有心稍加總覺完全可以拿來主...

    dack 評論0 收藏0

發(fā)表評論

0條評論

最新活動
閱讀需要支付1元查看
<