讀zepto核心源碼學(xué)習(xí)JS筆記(2)--工具函數(shù)

1. $.type $.isArray $.isFunction $.isNumeric $.isPlainObject $.isWindow

  • 判斷對象的方法介紹
    在zepto源碼中,使用了Object.prototype.toString.call()方法判斷對象的類型管挟,以下簡單介紹下此方法的大致情況
//null
Object.prototype.toString.call(null);//”[object Null]”
//undefined
Object.prototype.toString.call(undefined);//”[object Undefined]”
//string
Object.prototype.toString.call(“aaa”);//”[object String]”
//number
Object.prototype.toString.call(111);//”[object Number]”
//boolean
Object.prototype.toString.call(true);//”[object Boolean]”
//函數(shù)
Function fn(){console.log(“xixi”);}
Object.prototype.toString.call(fn);//”[object Function]”
//數(shù)組類型
var arr = [1,2,,3,4];
Object.prototype.toString.call(arr);//”[object Array]”
//日期
var date = new Date();
Object.prototype.toString.call(date);//”[object Date]”
//自定義類型
//不能判斷aa是不是AA的實例,要用instanceof判斷
function AA(a, b) {
    this.a = a;
    this.b = b;
}
var aa = new AA("xixi", 'haha');
Object.prototype.toString.call(aa); //”[object Object]”
Object.prototype.toString.call(aa); //”[object Object]”
//正則
var aa = /^\w$/
Object.prototype.toString.call(aa); //”[object RegExp]”
  • 在zepto中,先定義了一個空對象class2type,并取出對象函數(shù)自帶的toString方法犯戏,即為Object.prototype.toString.call()
class2type = {},
toString = class2type.toString,

然后填充class2type的值固蚤;

$.each("Boolean Number String Function Array Date RegExp Object Error".split(" "), function(i, name) {
    class2type["[object " + name + "]"] = name.toLowerCase()
    //最終結(jié)果
    //class2type[”[object Boolean]”] = boolean,
    //class2type[”[object Number]”] = number,
    //class2type[”[object String]”] = string,
    // ...
  })
  • 準(zhǔn)備工作做完娘汞,就可以進(jìn)行對象的判斷了;

    • 首先封裝一個判斷方法夕玩,根據(jù)這個方法的返回值來判斷對象的類型你弦;
    //比如,如果要判斷function aa(){};則返回class2type[Object.prototype.toString.call(aa)]==class2type[”[object Function]”]==function燎孟;所以就判斷出為函數(shù)
    function type(obj) {
     //如果obj為null或者undefined,返回字符串'null','undefined';否則返回class2type[]或者object
          return obj == null ? String(obj) :class2type[toString.call(obj)] || "object"
    }
    
    $.type = type
    
    • 下面根據(jù)上面的封裝方法返回值判斷類型禽作;

      • 判斷函數(shù)
      function isFunction(value) {
          return type(value) == "function"
        }
      
      $.isFunction = isFunction
      
      • 判斷window;根據(jù)widow自己的屬性來判斷;window.window = window;
      function isWindow(obj) {
          return obj != null && obj == obj.window
        }
      
      $.isWindow = isWindow
      
      • 判斷document
      function isDocument(obj) {
          return obj != null && obj.nodeType == obj.DOCUMENT_NODE
        }
      
      • 判斷是否為對象
      function isObject(obj) {
          return type(obj) == "object"
        }
      
      • 對于通過字面量定義的對象和new Object的對象返回true揩页,new Object時傳參數(shù)的返回false
      function isPlainObject(obj) {
          return isObject(obj) && !isWindow(obj) && obj.__proto__ == Object.prototype
        }
      
      $.isPlainObject = isPlainObject
      
      • 判斷數(shù)組
      function isArray(value) {
          return value instanceof Array
        }
      
      $.isArray = isArray
      
      • 判斷類數(shù)組
      function likeArray(obj) {
          return typeof obj.length == 'number'
        }
      
      • 空對象
      $.isEmptyObject = function(obj) {
          var name
          for (name in obj) return false
          return true
        }
      
      • 有限數(shù)值或者字符串表達(dá)的數(shù)字
      $.isNumeric = function(val) {
          var num = Number(val), type = typeof val
          return val != null && type != 'boolean' &&
            (type != 'string' || val.length) &&
            !isNaN(num) && isFinite(num) || false
        }
      

2. $.camelCase

camelize = function(str){ 
    return str.replace(/-+(.)?/g,
        function(match, chr){ return chr ? chr.toUpperCase() : '' }
    ) 
}
$.camelCase = camelize
  • 用法

    $.camelCase('hello-there') //=> "helloThere"
    $.camelCase('helloThere')  //=> "helloThere"
    
  • str.replcace(a,b)

    將str中的a替換成b;上面代碼中將b用了函數(shù)返回值來表達(dá);

3. $.contain

//為了判斷某個節(jié)點是不是另一個節(jié)點的后代,瀏覽器引入了contains()方法;
$.contains = document.documentElement.contains ?
//如果瀏覽器支持contains()方法,就執(zhí)行這個函數(shù)
    function(parent, node) {
      return parent !== node && parent.contains(node)
    } :
    //否則循環(huán)判斷
    function(parent, node) {
      while (node && (node = node.parentNode))
        if (node === parent) return true
      return false
}
  • 檢查父節(jié)點是否包含給定的dom節(jié)點旷偿,如果兩者是相同的節(jié)點,則返回false爆侣。

4. $.each

$.each = function(elements, callback){
    var i, key
    if (likeArray(elements)) {
      for (i = 0; i < elements.length; i++)
        if (callback.call(elements[i], i, elements[i]) === false) return elements
    } else {
      for (key in elements)
        if (callback.call(elements[key], key, elements[key]) === false) return elements
    }

    return elements
}
  • 遍歷,將每次循環(huán)的值作為callback的上下文;如果callback返回的結(jié)果為false,遍歷停止;

5. $.extend

function extend(target, source, deep) {
    for (key in source)
    //如果是神拷貝,source[key]是對象或者數(shù)組
      if (deep && (isPlainObject(source[key]) || isArray(source[key]))) {
      //source[key]是對象,而target[key]不是對象
        if (isPlainObject(source[key]) && !isPlainObject(target[key]))
          target[key] = {}
      //source[key]是數(shù)組,而target[key]不是數(shù)組
        if (isArray(source[key]) && !isArray(target[key]))
          target[key] = []
          //遞歸
        extend(target[key], source[key], deep)
      }
      else if (source[key] !== undefined) target[key] = source[key]
  }
$.extend = function(target){
    var deep, args = slice.call(arguments, 1)
    //如果傳入的第一個參數(shù)為布爾值
    if (typeof target == 'boolean') {
      deep = target
     //將除第一個參數(shù)外的參數(shù)賦值給target
      target = args.shift()
    }
    //遍歷參數(shù),將參數(shù)都復(fù)制到target上;
    args.forEach(function(arg){ extend(target, arg, deep) })
    return target
  }
  • 我們首先看一下用法;
$.extend(target, [source, [source2, ...]])   ? target
$.extend(true, target, [source, ...])   ? target v1.0+
var target = { one: 'patridge' },
source = { two: 'turtle doves' }
$.extend(target, source)//{one: "patridge", two: "turtle doves"}
  • target代表被拓展的對象,source為源對象;deep代表是深復(fù)制還是淺復(fù)制;

    • 對于字符串來說,淺復(fù)制是對值的復(fù)制,,對于對象來說,淺復(fù)制是對對象地址的復(fù)制,兩者共同指向同一個地址,其中一個改變,另一個對象也會隨之改變,而深復(fù)制是在堆區(qū)中開辟一個新的,兩個對象則指向不同的地址,相互獨立;
  • slice.call(arguments, 1)選取傳入?yún)?shù)的第一個參數(shù)到最后一個參數(shù);

5. $.inArray

$.inArray = function(elem, array, i){
    return emptyArray.indexOf.call(array, elem, i)
}
  • 用法
$.inArray("abc",["bcd","abc","edf","aaa"]);//=>1
$.inArray("abc",["bcd","abc","edf","aaa"],1);//=>1
$.inArray("abc",["bcd","abc","edf","aaa"],2);//=>-1
  • 返回數(shù)組中指定元素的索引值狸捅,如果沒有找到該元素則返回-1。

6. $.map

$.map = function(elements, callback){
    var value, values = [], i, key
    if (likeArray(elements))
      for (i = 0; i < elements.length; i++) {
        value = callback(elements[i], i)
        if (value != null) values.push(value)
      }
    else
      for (key in elements) {
        value = callback(elements[key], key)
        if (value != null) values.push(value)
      }
    return flatten(values)
 }
  • element為類數(shù)組對象或者對象;

    • 如果為類數(shù)組對象的話,用for循環(huán)
    • 如果為對象的話,用fo.....in....循環(huán)
    • 再將索引和值傳給callback,
    • 如果callback的返回值不是null或者undefined,存入新的數(shù)組
    • 最后將數(shù)組扁平化flatten()---數(shù)組降維,二維數(shù)組轉(zhuǎn)為一維數(shù)組
  • flatten()

    function flatten(array) { return array.length > 0 ? $.fn.concat.apply([], array) : array }

    這里巧妙應(yīng)用了apply方法,apply方法的第一個元素會被當(dāng)作this,第二個元素被做為傳入的參數(shù)arguments;
    例如:concat.apply([],[[1],[2],[3]]),等價于[].concat([1],[2],[3]),輸出的值為[1,2,3],就實現(xiàn)了數(shù)組的扁平化;

7. $.noop

$.noop = function() {}
  • 引用空函數(shù)

8. $.parseJSON

if (window.JSON) $.parseJSON = JSON.parse
  • 原生JSON.parse的別名累提;接受一個JSON字符串尘喝,返回解析后的javascript對象。

9. $.trim

$.trim = function(str) {
    return str == null ? "" : String.prototype.trim.call(str)
}
  • 去除字符串開頭和結(jié)尾的空格
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末斋陪,一起剝皮案震驚了整個濱河市朽褪,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌无虚,老刑警劉巖缔赠,帶你破解...
    沈念sama閱讀 211,376評論 6 491
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異友题,居然都是意外死亡嗤堰,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,126評論 2 385
  • 文/潘曉璐 我一進(jìn)店門度宦,熙熙樓的掌柜王于貴愁眉苦臉地迎上來踢匣,“玉大人告匠,你說我怎么就攤上這事±牖#” “怎么了后专?”我有些...
    開封第一講書人閱讀 156,966評論 0 347
  • 文/不壞的土叔 我叫張陵,是天一觀的道長输莺。 經(jīng)常有香客問我戚哎,道長,這世上最難降的妖魔是什么嫂用? 我笑而不...
    開封第一講書人閱讀 56,432評論 1 283
  • 正文 為了忘掉前任型凳,我火速辦了婚禮,結(jié)果婚禮上嘱函,老公的妹妹穿的比我還像新娘甘畅。我一直安慰自己,他們只是感情好实夹,可當(dāng)我...
    茶點故事閱讀 65,519評論 6 385
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著粒梦,像睡著了一般亮航。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上匀们,一...
    開封第一講書人閱讀 49,792評論 1 290
  • 那天缴淋,我揣著相機與錄音,去河邊找鬼泄朴。 笑死重抖,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的祖灰。 我是一名探鬼主播钟沛,決...
    沈念sama閱讀 38,933評論 3 406
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼局扶!你這毒婦竟也來了恨统?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 37,701評論 0 266
  • 序言:老撾萬榮一對情侶失蹤三妈,失蹤者是張志新(化名)和其女友劉穎畜埋,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體畴蒲,經(jīng)...
    沈念sama閱讀 44,143評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡悠鞍,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,488評論 2 327
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了模燥。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片咖祭。...
    茶點故事閱讀 38,626評論 1 340
  • 序言:一個原本活蹦亂跳的男人離奇死亡掩宜,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出心肪,到底是詐尸還是另有隱情锭亏,我是刑警寧澤,帶...
    沈念sama閱讀 34,292評論 4 329
  • 正文 年R本政府宣布硬鞍,位于F島的核電站慧瘤,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏固该。R本人自食惡果不足惜锅减,卻給世界環(huán)境...
    茶點故事閱讀 39,896評論 3 313
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望伐坏。 院中可真熱鬧怔匣,春花似錦、人聲如沸桦沉。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,742評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽纯露。三九已至剿骨,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間埠褪,已是汗流浹背浓利。 一陣腳步聲響...
    開封第一講書人閱讀 31,977評論 1 265
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留钞速,地道東北人贷掖。 一個月前我還...
    沈念sama閱讀 46,324評論 2 360
  • 正文 我出身青樓,卻偏偏與公主長得像渴语,于是被迫代替她去往敵國和親苹威。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 43,494評論 2 348

推薦閱讀更多精彩內(nèi)容

  • 工廠模式類似于現(xiàn)實生活中的工廠可以產(chǎn)生大量相似的商品驾凶,去做同樣的事情屠升,實現(xiàn)同樣的效果;這時候需要使用工廠模式。簡單...
    舟漁行舟閱讀 7,724評論 2 17
  • 單例模式 適用場景:可能會在場景中使用到對象狭郑,但只有一個實例腹暖,加載時并不主動創(chuàng)建,需要時才創(chuàng)建 最常見的單例模式翰萨,...
    Obeing閱讀 2,058評論 1 10
  • 三脏答、閉包和高階函數(shù) 3.1 閉包 3.1.1 變量的作用域 所謂變量的作用域,就是變量的有效范圍。通過作用域的劃分...
    梁同學(xué)de自言自語閱讀 1,448評論 0 6
  • 第一次聽到母親哭泣是1998年殖告,那一年我上二年級阿蝶,面對三個上門的村干部催繳集資,母親手里拿不出錢黄绩,急得團(tuán)團(tuán)轉(zhuǎn)......
    阿土127閱讀 397評論 0 4
  • 世界上的事啊羡洁,真奇怪,真真假假爽丹,挺讓人覺得唏噓筑煮。——大栗致自己 這兩天粤蝎,我學(xué)習(xí)了如何排版和剪輯視頻真仲。沒學(xué)之前,總給...
    有杕之杜閱讀 482評論 1 3