摘要:背景在閱讀教程時有這么段其中這個表達式有點讓人費解。對象就是一個類數(shù)組對象,因為沒有初始化下標,的值,所以獲取,下標的值得到的都是。
背景
在閱讀VueJS教程時有這么段demo code:
render: function (createElement) { return createElement("div", Array.apply(null, { length: 20 }).map(function () { return createElement("p", "hi") }) ) }
其中這個表達式Array.apply(null, { length: 20 })有點讓人費解。第一感覺這個表達式就是為了創(chuàng)建一個長度為20的數(shù)組,但表達式Array(20)也可以實現(xiàn)這個功能啊,為啥非要寫那么復(fù)雜呢?看來情況沒那么簡單。。。
表達式Array.apply(null, { length: 2 })的值先溫故下基礎(chǔ)(為了方便驗證將表達式改成Array.apply(null, { length: 2 }),即length的值改成2):
基礎(chǔ)1: Array構(gòu)造函數(shù)直接調(diào)用Array函數(shù)跟new方式調(diào)用是等價的,即:
var a = Array(2); // 等價于var a = new Array(2);
表示:創(chuàng)建一個長度為2的數(shù)組,注意該數(shù)組的元素并沒有被初始化,即:
console.log(0 in a); // false console.log(1 in a); // false, 因為數(shù)組下標0,1還未初始化 console.log(a[0]); // undefined, 因為數(shù)組下標0還未初始化,訪問不存在的屬性返回undefined基礎(chǔ)2: apply函數(shù)
ES5開始apply函數(shù)的第二個參數(shù)除了可以是數(shù)組外,還可以是類數(shù)組對象(即包含length屬性,且length屬性值是個數(shù)字的對象)。對象{length: 2}就是一個類數(shù)組對象,因為沒有初始化下標0,1的值,所以獲取0,1下標的值得到的都是undefined。
console.log(a[0]); // undefined console.log(a[1]); // undefined // 可以轉(zhuǎn)成真正的數(shù)組 var a = Array.prototype.slice.call({length: 2}); console.log(Array.isArray(a)) // true再看表達式Array.apply(null, { length: 2})的值
溫故了基礎(chǔ)后再看表達式Array.apply(null, { length: 2 })他就等價于:
// 1 熟悉一點: {length: 2}作為Array.apply第二個參數(shù)等同于[undefined, undefined]作為Array.apply第二個參數(shù) Array.apply(null, [undefined, undefined]); // 2 再熟悉一點:apply方法的執(zhí)行結(jié)果 Array(undefined, undefined); // 3 再再熟悉一點:Array方法直接調(diào)用和new方式調(diào)用等價 new Array(undefined, undefined);
這樣就很容易知道該表達式的值是一個長度為2,且每個元素值都被初賦值為undefined的數(shù)組(注意此時不是數(shù)組元素沒有初始化,而是初始化成undefined,這就是跟Array(2)的區(qū)別)。
為啥非要寫那么復(fù)雜呢?回到最初的問題:為啥非要寫那么復(fù)雜呢?回答這個問題前還得溫故下map方法(來自MDN描述):
It is not called for missing elements of the array (that is, indexes that have never been set, which have been deleted or which have never been assigned a value).
即map函數(shù)并不會遍歷數(shù)組中沒有初始化或者被delete的元素(有相同限制還有forEach, reduce方法)。OK,疑問到此終于真相大白了:寫這么“復(fù)雜”就是為了實現(xiàn):創(chuàng)建一個長度為20,且每個元素都被初始化的數(shù)組。這樣map方法就可以循環(huán)20次了。
// 被初始化的數(shù)組 Array.apply(null, {length: 20}).map(function(val, index){ console.log(index); // 循環(huán)20次 }); // 未被初始化的數(shù)組 Array(20).map(function(val, index){ console.log(index); // 不會被執(zhí)行 });
其實這已經(jīng)是實現(xiàn)該功能很簡潔的寫法了,不得不佩服vuejs文檔作者的基礎(chǔ)功力。
如果為了少寫幾個字的話還可以把該表達式修改成:
Array.apply(null, Array(20)); // 第二個參數(shù)用Array(20)代替{length: 20}
還可以使用ES6 API更直觀表達意圖:
// 方法1: Array.from({length: 20}) // 方法2 Array(20).fill(null)其他
Array(2) 等價于[,,],不等價于[undefined, undefined]
參考Apply函數(shù)
Array.prototype.map方法
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://specialneedsforspecialkids.com/yun/88845.html
摘要:檢測數(shù)組或者檢測對象的原型鏈是否指向構(gòu)造函數(shù)的對象或者終極大招注意不可以用此方法檢查常用方法合并多個數(shù)組,返回合并后的新數(shù)組,原數(shù)組沒有變化。返回值是由被刪除的元素組成的一個數(shù)組。 定義數(shù)組 const array = [1, 2, 3]; 或者 const array = new Array(); array[0] = 1; 建議盡量使用第一種形式定義數(shù)組,采用new的形式在大量的數(shù)...
摘要:檢測數(shù)組或者檢測對象的原型鏈是否指向構(gòu)造函數(shù)的對象或者終極大招注意不可以用此方法檢查常用方法合并多個數(shù)組,返回合并后的新數(shù)組,原數(shù)組沒有變化。返回值是由被刪除的元素組成的一個數(shù)組。 定義數(shù)組 const array = [1, 2, 3]; 或者 const array = new Array(); array[0] = 1; 建議盡量使用第一種形式定義數(shù)組,采用new的形式在大量的數(shù)...
摘要:數(shù)組元素甚至可以是對象或其它數(shù)組。它執(zhí)行的是淺拷貝,這意味著如果數(shù)組元素是對象,兩個數(shù)組都指向相同的對象,對新數(shù)組中的對象修改,會在舊的數(shù)組的相同對象中反應(yīng)出來。 JS中的數(shù)組是弱類型的,數(shù)組中可以含有不同類型的元素。數(shù)組元素甚至可以是對象或其它數(shù)組。JS引擎一般會優(yōu)化數(shù)組,按索引訪問數(shù)組常常比訪問一般對象屬性明顯迅速。數(shù)組長度范圍 from 0 to 4,294,967,295(2^...
摘要:作者原文章創(chuàng)建數(shù)組除了字面量和外,還可以通過創(chuàng)建,為數(shù)組的長度。生成了長度為的空數(shù)組,注意,和數(shù)組中元素賦值為是有區(qū)別的中查看空數(shù)組為,而賦值為的數(shù)組為。 作者 @zwhu原文章 @github 創(chuàng)建數(shù)組除了字面量和 new Array() 外,還可以通過 Array(n) 創(chuàng)建,n 為數(shù)組的長度。 Array(n) 生成了長度為 n 的空數(shù)組,注意,和數(shù)組中元素賦值為 undefin...
閱讀 2742·2021-11-24 10:23
閱讀 1153·2021-11-17 09:33
閱讀 2503·2021-09-28 09:41
閱讀 1409·2021-09-22 15:55
閱讀 3641·2019-08-29 16:32
閱讀 1903·2019-08-29 16:25
閱讀 1056·2019-08-29 11:06
閱讀 3421·2019-08-29 10:55