摘要:對象字面量形式通過構(gòu)造函數(shù)創(chuàng)建中是如何判斷的呢判斷是否為純粹的對象,必須滿足首先必須是對象不是對象并且原型要和的原型相等方法返回指定對象的原型即內(nèi)部屬性的值如果沒有繼承屬性,則返回。
前言
時間過得可真快,轉(zhuǎn)眼間2017年已去大半有余,你就說嚇不嚇人,這一年你成長了多少,是否荒度了很多時光,亦或者天天向上,收獲滿滿。今天主要寫一些看Zepto基礎(chǔ)模塊時,比較實用的部分內(nèi)部方法,在我們?nèi)粘9ぷ骰蛘邔W(xué)習(xí)中也會用的到。
源碼倉庫
原文鏈接
面試或者工作中經(jīng)常遇到要將多維數(shù)組鋪平成一維數(shù)組。例如將[1, 2, [3], [4], [5]]最后變成[1, 2, 3, 4, 5]
function flatten(array) { return array.length > 0 ? $.fn.concat.apply([], array) : array }
這里先將$.fn.concat理解成原生數(shù)組的concat方法,我們會發(fā)現(xiàn),其實他只能鋪平一層。例如
[1, 2, [3], [4, [5]]] => [1, 2, 3, 4, [5]]
那怎樣才能將多層嵌套的數(shù)組完全鋪平為一層呢?這里介紹兩種方式。
方式1
let flatten = (array) => { return array.reduce((result, val) => { return result.concat(Array.isArray(val) ? flatten(val) : val) }, []) }
測試
let testArr1 = [1, 2, 3, 4] let testArr2 = [1, [2], 3, [4, [5, [6, [7]]]]] console.log(flatten(testArr1)) // => [1, 2, 3, 4] console.log(flatten(testArr2)) // => [1, 2, 3, 4, 5, 6, 7]
方式2
let flatten = (array) => { let result = [] let idx = 0 array.forEach((val, i) => { if (Array.isArray(val)) { let value = flatten(val) let len = value.length let j = 0 result.length += len while ( j < len) { result[idx++] = value[j++] } } else { result[idx++] = val } }) return result }
同樣和上面得到的結(jié)果一致
2. 數(shù)組去重(uniq)數(shù)組去重可謂是老生常談的話題了,方式有非常多。好久之前寫過一篇關(guān)于去重的文章,歡迎查看。
let uniq = function (array) { return filter.call(array, function (item, idx) { return array.indexOf(item) == idx }) }
結(jié)合數(shù)組的filter方法,查看數(shù)組的某項出現(xiàn)的索引是不是與idx相等,不相等,肯定出現(xiàn)過2次以上,即將其過濾掉。其實結(jié)合es6中的Set數(shù)據(jù)結(jié)構(gòu),可以很方便的做到數(shù)組去重。
let uniq = (array) => { return [...new Set(array)] }
測試
let testArr = [1, 1, 2, 3, 0, -1, -1] console.log(uniq(testArr)) // => [1, 2, 3, 0, -1]3. 連字符轉(zhuǎn)駝峰(camelize)
這個方法挺實用的,可以將a-b-c這種形式轉(zhuǎn)換成aBC,當(dāng)然下劃線的數(shù)量可以是多個,a---b-----c => aBC
let camelize = function (str) { return str.replace(/-+(.)?/g, function (match, chr) { return chr ? chr.toUpperCase() : "" }) }4. 判斷是否為document對象(isDocument)。
通過dom元素的nodeType屬性可以知道其屬于哪種元素類型。結(jié)合下面這張表(developer.mozilla.org/en-US/docs/Web/API/Node/nodeType),其實不僅僅可以寫出判斷是否為document對象,還可以判斷是否為元素對象等。
function isDocument (obj) { return obj != null && obj.nodeType == obj.DOCUMENT_NODE }5. 判斷obj是否為類數(shù)組(likeArray)
什么是類數(shù)組對象呢?
類數(shù)組對象:
含有指向?qū)ο笤氐臄?shù)字索引下標(biāo)以及l(fā)ength屬性標(biāo)志屬性的個數(shù)
不含有數(shù)組的push、concat等方法
常見的類數(shù)組對象有auguments,document.getElementsByClassName等api獲取的dom集合,符合上述條件的對象等。
function likeArray(obj) { // !!obj 直接過濾掉了false,null,undefined,""等值 // 然后obj必須包含length屬性 var length = !!obj && "length" in obj && obj.length, // 獲取obj的數(shù)據(jù)類型 type = $.type(obj) // 不能是function類型,不能是window // 如果是array則直接返回true // 或者當(dāng)length的數(shù)據(jù)類型是number,并且其取值范圍是0到(length - 1)這里是通過判斷l(xiāng)ength - 1 是否為obj的屬性 return "function" != type && !isWindow(obj) && ( "array" == type || length === 0 || (typeof length == "number" && length > 0 && (length - 1) in obj) ) }
代碼上了注釋,主要我們來對比一下underscore中是如何判斷是否為類數(shù)組的。
var MAX_ARRAY_INDEX = Math.pow(2, 53) - 1; var getLength = property("length"); var isArrayLike = function(collection) { var length = getLength(collection); return typeof length == "number" && length >= 0 && length <= MAX_ARRAY_INDEX; };
underscore中判斷類數(shù)組比較寬松一些,MAX_ARRAY_INDEX是JavaScript 中能精確表示的最大數(shù)字,主要判斷對象的length屬性是否為數(shù)字類型,并且是否大于0且在MAX_ARRAY_INDEX范圍內(nèi)。
zepto中類數(shù)組判斷就比較嚴(yán)格了,因為window和函數(shù)其實都有l(wèi)ength屬性,這里把他們給過濾掉了。
6. 判斷是否為window對象window對象的window屬性指向其本身,我們來直接看下mdn上的解釋。
function isWindow (obj) { return obj != null && obj == obj.window }
但實際上下面的代碼也會被認(rèn)為是window對象。
let a = {} a.window = a a === a.window // true isWindow(a) // true7. 判斷數(shù)據(jù)類型
利用Object.prototype.toString方法來做數(shù)據(jù)類型的判斷。
let class2type = {} let toString = class2type.toString // Populate the class2type map $.each("Boolean Number String Function Array Date RegExp Object Error".split(" "), function(i, name) { class2type["[object " + name + "]"] = name.toLowerCase() })
最后class2type會變成
class2type = { "[object Boolean]": "boolean", "[object Array]": "array", "[object Number]": "number" ... }
接著就是type函數(shù)的定義了
function type(obj) { return obj == null ? String(obj) : class2type[toString.call(obj)] || "object" }
首先如果傳入的obj是null或者undefined,則用String函數(shù)返貨null或者undefined,而toString.call(obj)返回的正是形如[object Array],所以再結(jié)合上面的class2type變量,正好就可以得到例如。
type([]) => array type(1) => number8. 判斷是夠為純粹的對象(isPlainObject)
有時候我們想要符合這樣條件的對象。但是js中沒有直接給到能夠判斷是否為純粹的對象的方法。
// 對象字面量形式 let obj = { name: "qianlongo" } // 通過Object構(gòu)造函數(shù)創(chuàng)建 let person = new Object({ name: "qianlongo", sex: "boy" })
zepto中是如何判斷的呢?
// 判斷obj是否為純粹的對象,必須滿足 // 首先必須是對象 --- isObject(obj) // 不是window對象 --- !isWindow(obj) // 并且原型要和 Object 的原型相等 function isPlainObject(obj) { return isObject(obj) && !isWindow(obj) && Object.getPrototypeOf(obj) == Object.prototype }
Object.getPrototypeOf() 方法返回指定對象的原型(即, 內(nèi)部[[Prototype]]屬性的值),如果沒有繼承屬性,則返回 null 。
9. 判斷是否為空對象(isEmptyObject)// 判斷是否為空對象 // 使用for in遍歷,只要obj有屬性則認(rèn)為不是空對象 $.isEmptyObject = function (obj) { var name for (name in obj) return false return true }
主要是通過走一遍for循環(huán),來確定,所以會將以下數(shù)據(jù)也認(rèn)為是空對象。
null
undefined
[]
""
1024(數(shù)字)
true or false
{}
new Person() // 自定義的構(gòu)造函數(shù)
所以這里判斷空對象的初衷到底是不是只為了判斷形如{},new Object()呢
結(jié)尾暫時就更新這些,后續(xù)在閱讀源碼的過程中會陸續(xù)補充
參考資料
讀Zepto源碼之內(nèi)部方法
jQuery.isPlainObject
對jQuery.isPlainObject()的理解
Object.getPrototypeOf()
文章記錄
原來你是這樣的jsonp(原理與具體實現(xiàn)細(xì)節(jié))
誰說你只是"會用"jQuery?
向zepto.js學(xué)習(xí)如何手動觸發(fā)DOM事件
mouseenter與mouseover為何這般糾纏不清?
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://specialneedsforspecialkids.com/yun/112476.html
摘要:對象字面量形式通過構(gòu)造函數(shù)創(chuàng)建中是如何判斷的呢判斷是否為純粹的對象,必須滿足首先必須是對象不是對象并且原型要和的原型相等方法返回指定對象的原型即內(nèi)部屬性的值如果沒有繼承屬性,則返回。 前言 時間過得可真快,轉(zhuǎn)眼間2017年已去大半有余,你就說嚇不嚇人,這一年你成長了多少,是否荒度了很多時光,亦或者天天向上,收獲滿滿。今天主要寫一些看Zepto基礎(chǔ)模塊時,比較實用的部分內(nèi)部方法,在我們?nèi)?..
摘要:對象字面量形式通過構(gòu)造函數(shù)創(chuàng)建中是如何判斷的呢判斷是否為純粹的對象,必須滿足首先必須是對象不是對象并且原型要和的原型相等方法返回指定對象的原型即內(nèi)部屬性的值如果沒有繼承屬性,則返回。 前言 時間過得可真快,轉(zhuǎn)眼間2017年已去大半有余,你就說嚇不嚇人,這一年你成長了多少,是否荒度了很多時光,亦或者天天向上,收獲滿滿。今天主要寫一些看Zepto基礎(chǔ)模塊時,比較實用的部分內(nèi)部方法,在我們?nèi)?..
摘要:舉例需要注意的是,此時回調(diào)函數(shù)中的指向的就是數(shù)組或者對象的某一項。中提供的拷貝方法,默認(rèn)為淺拷貝,如果第一個參數(shù)為布爾值則表示深拷貝。 前言 平時開發(fā)過程中經(jīng)常會用類似each、map、forEach之類的方法,Zepto本身也把這些方法掛載到$函數(shù)身上,作為靜態(tài)方法存在,既可以給Zepto的實例使用,也能給普通的js對象使用。今天我們主要針對其提供的這些api做一些源碼實現(xiàn)分析。 源...
摘要:舉例需要注意的是,此時回調(diào)函數(shù)中的指向的就是數(shù)組或者對象的某一項。中提供的拷貝方法,默認(rèn)為淺拷貝,如果第一個參數(shù)為布爾值則表示深拷貝。 前言 平時開發(fā)過程中經(jīng)常會用類似each、map、forEach之類的方法,Zepto本身也把這些方法掛載到$函數(shù)身上,作為靜態(tài)方法存在,既可以給Zepto的實例使用,也能給普通的js對象使用。今天我們主要針對其提供的這些api做一些源碼實現(xiàn)分析。 源...
閱讀 2721·2023-04-26 02:28
閱讀 2551·2021-09-27 13:36
閱讀 3122·2021-09-03 10:29
閱讀 2751·2021-08-26 14:14
閱讀 2101·2019-08-30 15:56
閱讀 830·2019-08-29 13:46
閱讀 2609·2019-08-29 13:15
閱讀 454·2019-08-29 11:29