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