摘要:的作用相當(dāng)于,將其轉(zhuǎn)換為布爾值。用于判斷一個變量是否某個對象的實例,如返回同時也會返回返回布爾值,如果為,則返回,否則返回的結(jié)果。
underscore.js源碼
Underscore.js 沒有對原生 JavaScript 對象進行擴展,而是通過調(diào)用 _() 方法進行封裝,一旦封裝完成,原生 JavaScript 對象便成為一個 Underscore 對象。
判斷給定變量是否是對象// 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)先級要高與||。!!的作用相當(dāng)于Boolean(),將其轉(zhuǎn)換為布爾值。
判斷給定值是否是DOM元素// Is a given value a DOM element? _.isElement = function(obj) { return !!(obj && obj.nodeType === 1); };
同樣!!相當(dāng)于Boolean()的作用,nodeType === 1則說明是元素節(jié)點,屬性attr是2 ,文本text是3
測試
firstChild屬性
var t = document.getElementById("test").firstChild; alert(t.nodeType);//3 alert(t.nodeName);//#test alert(t.nodeValue);//測試
文本節(jié)點也算是一個節(jié)點,所以p的子節(jié)點是文本節(jié)點,所以返回3
zepto源碼 判斷是否是數(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的結(jié)果。
數(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)轉(zhuǎn)換為對應(yīng)的原始字符串“undefined”或“null”。
然后class2type[toString.call(obj)]首先借用Object的原型方法toString()來獲取obj的字符串表示,返回值的形式是 [object class],其中的class是內(nèi)部對象類。
然后從對象class2type中取出[object class]對應(yīng)的小寫字符串并返回;如果未取到則一律返回“object。
get方法get: function(idx){ return idx === undefined ? slice.call(this) : this[idx >= 0 ? idx : idx + this.length] },
取集合中對應(yīng)指定索引的值,如果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)
prototype.js源碼//為對象添加 class 屬性值 addClassName: function(element, className) { element = $(element); Element.removeClassName(element, className); element.className += " " + className; }, //為對象移除 class 屬性值 removeClassName: function(element, className) { element = $(element); if (!element) return; var newClassName = ""; var a = element.className.split(" "); for (var i = 0; i < a.length; i++) { if (a[i] != className) { if (i > 0) newClassName += " "; newClassName += a[i]; } } element.className = newClassName; },
因為addClassName依賴于removeClassName(),所以先分析后者,$()是先將元素封裝成prototype對象,
if(!element) return
這句的意思就是如果元素對象不存在,則忽略不再繼續(xù)執(zhí)行的意思,也就是終止的意思。
split() 方法用于把一個字符串分割成字符串?dāng)?shù)組。
如果把空字符串 ("") 用作 分隔符,那么 該對象 中的每個字符之間都會被分割。
判斷是否擁有 class 屬性值//是否擁有 class 屬性值 hasClassName: function(element, className) { element = $(element); if (!element) return; var a = element.className.split(" "); for (var i = 0; i < a.length; i++) { if (a[i] == className) return true;//返回正確的處理結(jié)果 } return false;//返回錯誤的處理結(jié)果 },兼容舊版本瀏覽器增加Array的push方法
/** * 為兼容舊版本的瀏覽器增加 Array 的 push 方法。 */ if (!Array.prototype.push) { Array.prototype.push = function() { var startLength = this.length;//this指代Array for (var i = 0; i < arguments.length; i++) this[startLength + i] = arguments[i];//this依舊指代Array return this.length; } }
!Array.prototype.push如果為true,說明瀏覽器不支持該方法,則往下執(zhí)行。this[startLength + i] = arguments[i]將傳遞進來的每個參數(shù)依次放入數(shù)組中,最后返回數(shù)組的長度
訪問對象可以使用(.)表示法,也可以使用[]來訪問,同樣訪問數(shù)組元素也是
jQuery 源碼jQuery源碼太多關(guān)聯(lián)了,所以不好多帶帶拿出來做分析,就舉一兩個簡單的例子吧:
toArray方法jQuery.prototype = { toArray: function() { return slice.call( this ); }, }
Array.prototype.slice.call(arguments)能將具有length屬性的對象轉(zhuǎn)成數(shù)組,也就是說其目的是將arguments對象的數(shù)組提出來轉(zhuǎn)化為數(shù)組。例如:
slice有兩個用法,一個是String.slice,一個是Array.slice,第一個返回的是字符串,第二個返回的是數(shù)組。
Array.prototype.slice.call(arguments)能夠?qū)?b>arguments轉(zhuǎn)成數(shù)組,那么就是arguments.toArray().slice();
因為arguments并不是真正的數(shù)組對象,只是與數(shù)組類似而已,所以它并沒有slice這個方法,而Array.prototype.slice.call(arguments)可以理解成是將arguments轉(zhuǎn)換成一個數(shù)組對象,讓arguments具有slice()方法。 比如:
var arr = [1,2,3,4]; console.log(Array.prototype.slice.call(arr,2));//[3,4]
Array
這是我們想要的基對象名稱
prototype
這可以被認為是一個數(shù)組的實例方法的命名空間
slice
這提取數(shù)組的一部分并返回新的數(shù)組,并沒有開始和結(jié)束索引,它只是返回一個數(shù)組的拷貝
call
這是一個非常有用的功能,它允許你從一個對象調(diào)用一個函數(shù)并且使用它在另一個上下文環(huán)境
下面的寫法是等效的:
Array.prototype.slice.call == [].slice.call
看這個例子:
object1 = { name:"frank", greet:function(){ alert("hello "+this.name) } }; object2 = { name:"trigkit4" }; // object2沒有g(shù)reet方法 // 但我們可以從object1中借來 object1.greet.call(object2);//彈出hello trigkit4
分解一下就是object1.greet運行彈出hello + "this.name",然后object2對象冒充,this就指代object2
var t = function(){ console.log(this);// String [ "t", "r", "i", "g", "k", "i", "t", "4" ] console.log(typeof this); // Object console.log(this instanceof String); // true }; t.call("trigkit4");
call(this)指向了所傳進去的對象。
在Object.prototype中已經(jīng)包含了一些方法:
1.toString ( ) 2.toLocaleString ( ) 3.valueOf ( ) 4.hasOwnProperty (V) 5.isPrototypeOf (V) 6.propertyIsEnumerable (V)on方法
jQuery.fn.extend({ on: function( types, selector, data, fn, /*INTERNAL*/ one ) { var type, origFn; // Types can be a map of types/handlers if ( typeof types === "object" ) { // ( types-Object, selector, data ) if ( typeof selector !== "string" ) { // ( types-Object, data ) data = data || selector; selector = undefined; } } }) jQuery.extend(object) :為擴展jQuery類本身.為類添加新的方法。 jQuery.fn.extend(object) :給jQuery對象添加方法。
!= 在表達式兩邊的數(shù)據(jù)類型不一致時,會隱式轉(zhuǎn)換為相同數(shù)據(jù)類型,然后對值進行比較.
!== 不會進行類型轉(zhuǎn)換,在比較時除了對值進行比較以外,還比較兩邊的數(shù)據(jù)類型, 它是恒等運算符===的非形式。
on : function(){} 是js對象字面量的寫法
{鍵:值,鍵:值}語法中的“健/值”會成為對象的靜態(tài)成員。如果給某個“健”指定的值是一個匿名函數(shù),那么該函數(shù)就會變成對象的靜態(tài)方法;否則就是對象的一個靜態(tài)屬性。
type: function( obj ) { if ( obj == null ) { return obj + ""; } return typeof obj === "object" || typeof obj === "function" ? class2type[ toString.call(obj) ] || "object" : typeof obj; },
前面已經(jīng)分析了,class2type = {};所以class2type[ toString.call(obj) ] =
{}.toString.call(obj)。它的作用是改變toString的this指向為object的實例。
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://systransis.cn/yun/91504.html
摘要:問題回答者黃軼,目前就職于公司擔(dān)任前端架構(gòu)師,曾就職于滴滴和百度,畢業(yè)于北京科技大學(xué)。最后附上鏈接問題我目前是一名后端工程師,工作快五年了。 showImg(https://segmentfault.com/img/bVbuaiP?w=1240&h=620); 問題回答者:黃軼,目前就職于 Zoom 公司擔(dān)任前端架構(gòu)師,曾就職于滴滴和百度,畢業(yè)于北京科技大學(xué)。 1. 前端開發(fā) 問題 大...
摘要:在這篇文章中,分享了他如何克服恐懼并開始使用源代碼來提高他的知識和技能。不久之后,你正在閱讀的源代碼將引導(dǎo)您進入規(guī)范。 通過閱讀源碼來提高js知識 原文傳送門:《Improve Your JavaScript Knowledge By Reading Source Code》 showImg(https://segmentfault.com/img/remote/14600000197...
摘要:特意對前端學(xué)習(xí)資源做一個匯總,方便自己學(xué)習(xí)查閱參考,和好友們共同進步。 特意對前端學(xué)習(xí)資源做一個匯總,方便自己學(xué)習(xí)查閱參考,和好友們共同進步。 本以為自己收藏的站點多,可以很快搞定,沒想到一入?yún)R總深似海。還有很多不足&遺漏的地方,歡迎補充。有錯誤的地方,還請斧正... 托管: welcome to git,歡迎交流,感謝star 有好友反應(yīng)和斧正,會及時更新,平時業(yè)務(wù)工作時也會不定期更...
摘要:老姚淺談怎么學(xué)鑒于時不時,有同學(xué)私信問我老姚,下同怎么學(xué)前端的問題。擼碼聽歌,全局控制。 淺析用 js 解析 xml 的方法 由于項目上需要解析 xml,于是各種百度,然后自己總結(jié)了下各個主流瀏覽器解析 xml 的方法,只能是很淺顯的知道他的用法,但是還沒有深層次的研究。 裝 X - 建立自己的斗圖網(wǎng)站庫 之前加過一個斗圖群,看到很多經(jīng)典的表情,然后就收藏到了 QQ, 迫于本屌絲開不起...
摘要:最近很熱的討論關(guān)于真阿當(dāng)對目前流行前端技術(shù)的批判我眼中的前端框架,,,以及我看前端架構(gòu)關(guān)于前端工具變化過快的討論我感覺到的前端變化上面幾篇文章對于前端的發(fā)展討論較多。 showImg(https://segmentfault.com/img/bVr3sx); 最近很熱的討論 關(guān)于『真阿當(dāng)』對目前流行前端技術(shù)的批判 https://www.zhihu.com/question/3892...
閱讀 1842·2021-09-22 15:55
閱讀 3532·2021-09-07 10:26
閱讀 638·2019-08-30 15:54
閱讀 693·2019-08-29 16:34
閱讀 847·2019-08-26 14:04
閱讀 3271·2019-08-26 11:47
閱讀 2142·2019-08-26 11:33
閱讀 2300·2019-08-23 15:17