1.1 underscore.js源碼
Underscore.js 沒有對(duì)原生 JavaScript 對(duì)象進(jìn)行擴(kuò)展,而是通過(guò)調(diào)用 _() 方法進(jìn)行封裝,一旦封裝完成,原生 JavaScript 對(duì)象便成為一個(gè) Underscore 對(duì)象。
1.1.1 判斷給定變量是否是對(duì)象
// Is a given variable an object?
_.isObject = function(obj) {
var type = typeof obj;
return type === 'function' || type === 'object' && !!obj;
};
這是underscore.js的判斷給定變量是否是object的一段源碼。 我們知道typeof會(huì)返回如下六個(gè)值:
1. 'undefined' --- 這個(gè)值未定義;2. 'boolean' --- 這個(gè)值是布爾值;3. 'string' --- 這個(gè)值是字符串;4. 'number' --- 這個(gè)值是數(shù)值;5. 'object' --- 這個(gè)值是對(duì)象或null;6. 'function' --- 這個(gè)值是函數(shù)。
而&&的優(yōu)先級(jí)要高與||。!!的作用相當(dāng)于Boolean(),將其轉(zhuǎn)換為布爾值。
1.1.2 判斷給定值是否是DOM元素
// Is a given value a DOM element?
_.isElement = function(obj) {
return !!(obj && obj.nodeType === 1);
};
同樣!!相當(dāng)于Boolean()的作用,nodeType === 1則說(shuō)明是元素節(jié)點(diǎn),屬性attr是2 ,文本text是3
<body>
<p id="test">測(cè)試</p><script>
var t = document.getElementById('test');
alert(t.nodeType);//1
alert(t.nodeName);//p
alert(t.nodeValue);//null</script></body>
firstChild屬性
var t = document.getElementById('test').firstChild;
alert(t.nodeType);//3
alert(t.nodeName);//#test
alert(t.nodeValue);//測(cè)試
文本節(jié)點(diǎn)也算是一個(gè)節(jié)點(diǎn),所以p的子節(jié)點(diǎn)是文本節(jié)點(diǎn),所以返回3
1.2 zepto源碼
1.2.1 判斷是否是數(shù)組
isArray = Array.isArray ||
function(object){ return object instanceof Array }
Array.isArray() 方法:如果一個(gè)對(duì)象是數(shù)組就返回true,如果不是則返回false。
instanceof 用于判斷一個(gè)變量是否某個(gè)對(duì)象的實(shí)例,如
var a= [];
alert(a instanceof Array);//返回 true
同時(shí) alert(a instanceof Object) 也會(huì)返回 true
isArray 返回布爾值,如果Array.isArray為true,則返回true,否則返回object instanceof Array的結(jié)果。
1.2.2 數(shù)據(jù)類型判斷
class2type = {},
function type(obj) {
return obj == null ? String(obj) :
class2type[toString.call(obj)] || "object"
}
function isFunction(value) { return type(value) == "function" }
function isWindow(obj) { return obj != null && obj == obj.window }
function isDocument(obj) { return obj != null && obj.nodeType == obj.DOCUMENT_NODE }
function isObject(obj) { return type(obj) == "object" }
class2type是一個(gè)空對(duì)象,實(shí)際上一個(gè)什么都沒有的空對(duì)象是這樣創(chuàng)建的Object.create(null);
我們可以通過(guò)Object.prototype.toString.call()方法來(lái)判斷數(shù)據(jù)類型,例如:
console.log(Object.prototype.toString.call(123)) //[object Number] console.log(Object.prototype.toString.call('123')) //[object String] console.log(Object.prototype.toString.call(undefined)) //[object Undefined] console.log(Object.prototype.toString.call(true)) //[object Boolean] console.log(Object.prototype.toString.call({})) //[object Object] console.log(Object.prototype.toString.call([])) //[object Array] console.log(Object.prototype.toString.call(function(){})) //[object Function]
首先如果參數(shù)obj是undefined或null,則通過(guò)String(obj)轉(zhuǎn)換為對(duì)應(yīng)的原始字符串“undefined”或“null”。
然后class2type[toString.call(obj)]首先借用Object的原型方法toString()來(lái)獲取obj的字符串表示,返回值的形式是 [object class],其中的class是內(nèi)部對(duì)象類。
然后從對(duì)象class2type中取出[object class]對(duì)應(yīng)的小寫字符串并返回;如果未取到則一律返回“object。
1.2.3 get方法
get: function(idx){
return idx === undefined ? slice.call(this) : this[idx >= 0 ? idx : idx + this.length]
},
取集合中對(duì)應(yīng)指定索引的值,如果idx小于0,則idx等于idx+length,length為集合的長(zhǎng)度.
可能你剛看到slice.call(this)會(huì)覺得很納悶,其實(shí)不僅是zepto.js的源碼,包括jQuery,backbone的源碼都是這么寫的,只不過(guò)它們?cè)谧铋_頭做了聲明:
var push = array.push;var slice = array.slice;var splice = array.splice;
所以slice.call(this)其實(shí)還是Array.slce.call(this)