国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專欄INFORMATION COLUMN

JS基礎(chǔ)篇-underscore源碼解析

anyway / 2669人閱讀

摘要:總想找個(gè)機(jī)會(huì)夯實(shí)一下自己的基礎(chǔ),正好最近略有清閑,看視頻讀書擼代碼我選擇了第三者怎么感覺有點(diǎn)別扭,看視頻的話效率不高適合入門,看書的話一本你不知道的推薦給大家,選擇繼續(xù)看書的話還是算了吧,畢竟讀萬(wàn)卷書不如行萬(wàn)里路是吧。

總想找個(gè)機(jī)會(huì)夯實(shí)一下自己的JS基礎(chǔ),正好最近略有清閑,看視頻?讀書?擼代碼?我選擇了第三者(怎么感覺有點(diǎn)別扭),看視頻的話效率不高適合入門,看書的話,一本《你不知道的JavaScript》推薦給大家,選擇繼續(xù)看書的話還是算了吧,畢竟讀萬(wàn)卷書不如行萬(wàn)里路是吧。擼代碼的話,擼個(gè)項(xiàng)目?自己雜七雜八寫了不少了,都是老套路難有新的突破,想想倒不如研究研究大神的代碼,學(xué)習(xí)學(xué)習(xí)大神的結(jié)構(gòu)設(shè)計(jì),技術(shù)細(xì)節(jié)等站在大神的肩膀上是吧。在選擇是翻譯Loadsh或Underscore的時(shí)候我更偏向于前者,因?yàn)槟钇饋?lái)比較順嘴,但當(dāng)我看到Loadsh源碼的時(shí)候發(fā)現(xiàn),這個(gè)!這個(gè)!我發(fā)現(xiàn)“安得兒私購(gòu)”其實(shí)也挺順嘴的,1600多行,API豐富,結(jié)構(gòu)清晰,就你了。最后在補(bǔ)充幾句,看源碼的感覺有點(diǎn)像“春天的雨,潤(rùn)物細(xì)無(wú)聲”,沒感覺自己技術(shù)有多大提高,但當(dāng)看到其他類庫(kù)的時(shí)候已經(jīng)知其大概結(jié)構(gòu),當(dāng)要自己實(shí)現(xiàn)_.flatten或_.chain的時(shí)候已經(jīng)有了思路,也算是有所進(jìn)步吧。此分析文章會(huì)持續(xù)更新,如有錯(cuò)誤感謝提出!
原文地址

//參考文檔:http://underscorejs.org/
//參考文檔:http://www.bootcss.com/p/underscore/
/*
  建議:
      1 剛開始不要一行一行跟下來(lái)敲,先了解一下庫(kù)的整體結(jié)構(gòu)
      2 遇到不懂的打個(gè)斷點(diǎn),多跟蹤幾遍,斷點(diǎn)很重要
      3 有些內(nèi)部函數(shù)使用頻率很高(cb....),這些內(nèi)部函數(shù)了解清楚了后續(xù)看起來(lái)輕松不少
      4 有些函數(shù)內(nèi),有較多的函數(shù)引用,建議多讀幾遍

*/
(function() {
  //獲取根對(duì)象,瀏覽器是window(self),Node是global,window.window===window返回true,global亦然
  var root = typeof self == "object" && self.self === self && self ||
            typeof global == "object" && global.global === global && global ||
            this ||
            {};
  //獲取現(xiàn)有的_對(duì)象,避免沖突,具體解決沖突方法后面會(huì)說
  var previousUnderscore = root._;
  //獲取原型對(duì)象,為的是寫起來(lái)方便不用每次都xxx.proto...一大推
  var ArrayProto = Array.prototype, ObjProto = Object.prototype;
  var SymbolProto = typeof Symbol !== "undefined" ? Symbol.prototype : null;

  var push = ArrayProto.push,
      slice = ArrayProto.slice,
      toString = ObjProto.toString,
      hasOwnProperty = ObjProto.hasOwnProperty;

  var nativeIsArray = Array.isArray,
      nativeKeys = Object.keys,
      nativeCreate = Object.create;
  //中轉(zhuǎn)函數(shù),后面用到會(huì)說
  var Ctor = function(){};
  /*
  _的構(gòu)造函數(shù),
  第一步是看看obj是否是_的實(shí)例,如果是就不操作直接返回,有點(diǎn)像$($("#d1")),jq或zepto里也有相似的判斷
  第二步是判斷this是否是_的實(shí)例,不是則進(jìn)行new 調(diào)用,
  注意,在進(jìn)行new調(diào)用的時(shí)候 new會(huì)做4件事,1創(chuàng)建空對(duì)象,2空對(duì)象的__proto__指向函數(shù)的prototype,3this指向空對(duì)象(此時(shí)可能會(huì)添加屬性等),4判斷返回值,
  而此時(shí)在當(dāng)前的_里this已經(jīng)指向空對(duì)象
  第三步為當(dāng)前對(duì)象添加_wrapped屬性,這是為了后面的鏈?zhǔn)秸{(diào)用做準(zhǔn)備
  */
  var _ = function(obj) {
    if (obj instanceof _) return obj;
    if (!(this instanceof _)) return new _(obj);
    this._wrapped = obj;
  };

  //根據(jù)當(dāng)前環(huán)境添加_對(duì)象
  if (typeof exports != "undefined" && !exports.nodeType) {
    if (typeof module != "undefined" && !module.nodeType && module.exports) {
      exports = module.exports = _;
    }
    exports._ = _;
  }
   else {
    root._ = _;
  }

  // 版本號(hào)
  _.VERSION = "1.8.3";

  //下面就是一些常用的方法了,后面會(huì)一點(diǎn)一點(diǎn)分析
  // _.each=_.forEach=function(){......}
  //...
  //...
  //...


  /*
  鏈?zhǔn)胶瘮?shù)
  實(shí)例化當(dāng)前對(duì)象,設(shè)置_china為true,此為判斷鏈?zhǔn)秸{(diào)用屬性,true為鏈?zhǔn)秸{(diào)用
  */
  _.chain = function(obj) {
    var instance = _(obj);
    instance._chain = true;
    return instance;
  };

  //判斷是否繼續(xù)鏈?zhǔn)秸{(diào)用
  var chainResult = function(instance, obj) {
    return instance._chain ? _(obj).chain() : obj;
  };

  /*
  擴(kuò)展_的方法 
  第一步遍歷obj里所含方法,執(zhí)行回調(diào)
  回調(diào)內(nèi)  
      1獲取obj的function,擴(kuò)展到_里,并保存到func
      2對(duì)_的prototype進(jìn)行擴(kuò)展,擴(kuò)展函數(shù)里進(jìn)行取值添加等操作(注意this指向),最后執(zhí)行func.apply(_, args)(注意apply還有打散數(shù)組的功能)把結(jié)果和this作為參數(shù)傳遞到chainResult中,判斷是否繼續(xù)鏈?zhǔn)秸{(diào)用
  第二步 返回_
  
  最后在解釋一下為什么_.prototype[name]=function(){....},如果理解請(qǐng)?zhí)^此段
  大家一般都是_.filter({name:"Mr.zhou"},function(){.....})
  鏈?zhǔn)秸{(diào)用說白了就是將第一個(gè)方法的執(zhí)行結(jié)果作為參數(shù)傳到第二個(gè)方法里,如此依次傳遞,直到最后一個(gè)返回結(jié)果;
  想要鏈?zhǔn)秸{(diào)用常用的_.filter(...)的方法肯定是不行了,具體實(shí)現(xiàn)請(qǐng)看例子
  var stooges = [{name: "curly", age: 25}, {name: "moe", age: 21}, {name: "larry", age: 23}];
  var youngest = _.chain(stooges)
                    .sortBy(function(stooge){ return stooge.age; })
                    .value();
  1 創(chuàng)建stooges對(duì)象
  2 創(chuàng)建youngest變量
  3 詳細(xì)看一下youngest值的計(jì)算方法
    3.1 先是_.chain(stooges)這句話做了什么呢?(可以回顧一下之前的代碼)
      調(diào)用_.chain(stooges),內(nèi)部對(duì)_進(jìn)行實(shí)例化,并把stooges作為_wrapped的值,并添加了一個(gè)名為_chain值為true的屬性,
      最后得到的就是這樣一個(gè)對(duì)象{_wrapped:[{name: "curly", age: 25}...],_chain:true}
    3.2 繼續(xù)調(diào)用
      {_wrapped:[{name: "curly", age: 25}...],_chain:true}.sortBy(function(stooge){ return stooge.age; })
                                                          .value();
      等等,這樣對(duì)嗎??jī)?nèi)個(gè)什么對(duì)象調(diào)用.sortBy不報(bào)錯(cuò)嗎?它有這個(gè)方法嗎?
      是有的,你沒聽錯(cuò),那么在哪里呢?
      請(qǐng)看_.mixin的這句換_.prototype[name]=function(){....}
      這句話就是在往_的原型對(duì)象中添加方法,在這句話之前的_.mixin(_),與其內(nèi)部的_.each(_.function(obj),...)就是將_上面的所有方法的地址引用傳遞給_.prototype上,而{_wrapped:[{name: "curly", age: 25}...],_chain:true}對(duì)象又是_的實(shí)例對(duì)象,自然也就繼承了_.prototype的方法,這也就是鏈?zhǔn)秸{(diào)用的原理
    3.3 最后調(diào)用value()來(lái)返回它的_wrapped就此結(jié)束
    */
  _.mixin = function(obj) {
    _.each(_.functions(obj), function(name) {
      var func = _[name] = obj[name];
      _.prototype[name] = function() {
        var args = [this._wrapped];
        push.apply(args, arguments);
        return chainResult(this, func.apply(_, args));
      };
    });
    return _;
  };

  //自調(diào)mixin并把_傳入
  _.mixin(_);

  // 同mixin差不多添加方法
  _.each(["pop", "push", "reverse", "shift", "sort", "splice", "unshift"], function(name) {
    var method = ArrayProto[name];
    _.prototype[name] = function() {
      var obj = this._wrapped;
      method.apply(obj, arguments);
      if ((name === "shift" || name === "splice") && obj.length === 0) delete obj[0];
      return chainResult(this, obj);
    };
  });

  // 同mixin差不多添加方法
  _.each(["concat", "join", "slice"], function(name) {
    var method = ArrayProto[name];
    _.prototype[name] = function() {
      return chainResult(this, method.apply(this._wrapped, arguments));
    };
  });

  // _.chain的value方法
  _.prototype.value = function() {
    return this._wrapped;
  };

  //添加相應(yīng)方法
  _.prototype.valueOf = _.prototype.toJSON = _.prototype.value;
  //添加相應(yīng)方法
  _.prototype.toString = function() {
    return String(this._wrapped);
  };

  //對(duì)AMD的兼容
  if (typeof define == "function" && define.amd) {
    define("underscore", [], function() {
      return _;
    });
  }
}());

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

轉(zhuǎn)載請(qǐng)注明本文地址:http://specialneedsforspecialkids.com/yun/87325.html

相關(guān)文章

  • 源碼解讀這半年

    摘要:作者韓子遲不知不覺間,源碼解讀系列進(jìn)入了真正的尾聲,也請(qǐng)?jiān)试S我最后一次下項(xiàng)目的原始地址這半年以來(lái),花費(fèi)了大量的業(yè)余時(shí)間,共計(jì)寫了篇隨筆包括此文,也給的源碼加了差不多行注釋,對(duì)于當(dāng)初說的要做史上最詳細(xì)的源碼剖析,至此我也覺得問心無(wú)愧。 作者:韓子遲 What? 不知不覺間,「Underscore 源碼解讀系列」進(jìn)入了真正的尾聲,也請(qǐng)?jiān)试S我最后一次 po 下項(xiàng)目的原始地址 https://...

    zzzmh 評(píng)論0 收藏0
  • javascript知識(shí)點(diǎn)

    摘要:模塊化是隨著前端技術(shù)的發(fā)展,前端代碼爆炸式增長(zhǎng)后,工程化所采取的必然措施。目前模塊化的思想分為和。特別指出,事件不等同于異步,回調(diào)也不等同于異步。將會(huì)討論安全的類型檢測(cè)惰性載入函數(shù)凍結(jié)對(duì)象定時(shí)器等話題。 Vue.js 前后端同構(gòu)方案之準(zhǔn)備篇——代碼優(yōu)化 目前 Vue.js 的火爆不亞于當(dāng)初的 React,本人對(duì)寫代碼有潔癖,代碼也是藝術(shù)。此篇是準(zhǔn)備篇,工欲善其事,必先利其器。我們先在代...

    Karrdy 評(píng)論0 收藏0
  • 即將立秋的《課多周刊》(第2期)

    摘要:即將立秋的課多周刊第期我們的微信公眾號(hào),更多精彩內(nèi)容皆在微信公眾號(hào),歡迎關(guān)注。若有幫助,請(qǐng)把課多周刊推薦給你的朋友,你的支持是我們最大的動(dòng)力。課多周刊機(jī)器人運(yùn)營(yíng)中心是如何玩轉(zhuǎn)起來(lái)的分享課多周刊是如何運(yùn)營(yíng)并堅(jiān)持下來(lái)的。 即將立秋的《課多周刊》(第2期) 我們的微信公眾號(hào):fed-talk,更多精彩內(nèi)容皆在微信公眾號(hào),歡迎關(guān)注。 若有幫助,請(qǐng)把 課多周刊 推薦給你的朋友,你的支持是我們最大...

    ruicbAndroid 評(píng)論0 收藏0
  • 即將立秋的《課多周刊》(第2期)

    摘要:即將立秋的課多周刊第期我們的微信公眾號(hào),更多精彩內(nèi)容皆在微信公眾號(hào),歡迎關(guān)注。若有幫助,請(qǐng)把課多周刊推薦給你的朋友,你的支持是我們最大的動(dòng)力。課多周刊機(jī)器人運(yùn)營(yíng)中心是如何玩轉(zhuǎn)起來(lái)的分享課多周刊是如何運(yùn)營(yíng)并堅(jiān)持下來(lái)的。 即將立秋的《課多周刊》(第2期) 我們的微信公眾號(hào):fed-talk,更多精彩內(nèi)容皆在微信公眾號(hào),歡迎關(guān)注。 若有幫助,請(qǐng)把 課多周刊 推薦給你的朋友,你的支持是我們最大...

    MRZYD 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

最新活動(dòng)
閱讀需要支付1元查看
<