我正在尋找如下全部替代方案,以建立一個包含1到N的JavaScript數組,其中N僅在運行時才知道。 數組
var foo = []; for (var i = 1; i <= N; i++) { foo.push(i); }
在我看來,應該有一種沒有循環的方法。 瀏覽器
若是您碰巧像我同樣在您的應用程序中使用d3.js ,D3提供了一個幫助程序功能來幫助您執行此操做。 app
所以,要得到一個從0到4的數組,就像這樣簡單: dom
d3.range(5) [0, 1, 2, 3, 4]
並按照您的要求從1到5得到一個數組: 函數
d3.range(1, 5+1) [1, 2, 3, 4, 5]
查看本教程以獲取更多信息。 this
這多是生成數字數組的最快方法 spa
最短的 prototype
var a=[],b=N;while(b--)a[b]=b+1;
排隊 code
var arr=(function(a,b){while(a--)b[a]=a;return b})(10,[]); //arr=[0,1,2,3,4,5,6,7,8,9]
若是要從1開始 對象
var arr=(function(a,b){while(a--)b[a]=a+1;return b})(10,[]); //arr=[1,2,3,4,5,6,7,8,9,10]
須要功能嗎?
function range(a,b,c){c=[];while(a--)c[a]=a+b;return c}; //length,start,placeholder var arr=range(10,5); //arr=[5,6,7,8,9,10,11,12,13,14]
爲何?
while
是最快的循環
直接設置比push
更快
[]
比new Array(10)
快
簡短...看第一個代碼。 而後在這裏查看全部其餘功能。
若是你喜歡生活中不可缺乏的
for(var a=[],b=7;b>0;a[--b]=b+1); //a=[1,2,3,4,5,6,7]
要麼
for(var a=[],b=7;b--;a[b]=b+1); //a=[1,2,3,4,5,6,7]
如下函數返回一個由數字填充的數組:
var createArrayOfNumbers = function (n) { return Array.apply(null, new Array(n)).map(function (empty, index) { return index; }); };
請注意,使用數組構造函數建立的數組包含孔,所以沒法使用諸如map之類的數組函數遍歷該數組。 所以,使用Array.apply
函數。
您能夠這樣作:
var N = 10; Array.apply(null, {length: N}).map(Number.call, Number)
結果:[0、一、二、三、四、五、六、七、八、9]
或具備隨機值:
Array.apply(null, {length: N}).map(Function.call, Math.random)
結果:[0.708269490161910七、0.957222590921446七、0.858674854272976五、0.865384814329445四、0.00833987747319042七、0.991175662260502六、0.813342336099594八、0.837758846580982二、0.557757591595873二、0.16363654541783035]
首先,請注意Number.call(undefined, N)
等同於Number(N)
,後者僅返回N
稍後咱們將使用該事實。
Array.apply(null, [undefined, undefined, undefined])
等同於Array(undefined, undefined, undefined)
,後者產生一個三元素數組,並將undefined
分配給每一個元素。
您如何將其歸納爲N個元素? 考慮一下Array()
工做方式,它是這樣的:
function Array() { if ( arguments.length == 1 && 'number' === typeof arguments[0] && arguments[0] >= 0 && arguments && arguments[0] < 1 << 32 ) { return [ … ]; // array of length arguments[0], generated by native code } var a = []; for (var i = 0; i < arguments.length; i++) { a.push(arguments[i]); } return a; }
從ECMAScript 5開始 , Function.prototype.apply(thisArg, argsArray)
也接受鴨子類型的相似數組的對象做爲其第二個參數。 若是咱們調用Array.apply(null, { length: N })
,它將執行
function Array() { var a = []; for (var i = 0; i < /* arguments.length = */ N; i++) { a.push(/* arguments[i] = */ undefined); } return a; }
如今咱們有了一個N元素數組,每一個元素都設置爲undefined
。 當咱們在其上調用.map(callback, thisArg)
時,每一個元素都將設置爲callback.call(thisArg, element, index, array)
。 所以, [undefined, undefined, …, undefined].map(Number.call, Number)
會將每一個元素映射到(Number.call).call(Number, undefined, index, array)
,與Number.call(undefined, index, array)
相同Number.call(undefined, index, array)
,如前所述,其計算結果爲index
。 這樣就完成了其元素與其索引相同的數組。
爲何要麻煩Array.apply(null, {length: N})
而不是Array(N)
? 畢竟,這兩個表達式都將致使一個由N個元素組成的未定義元素數組。 區別在於,在前一個表達式中,每一個元素都顯式設置爲undefined,而在後一個表達式中,從未設置每一個元素。 根據.map()
的文檔:
僅對具備指定值的數組索引調用
callback
; 對於已刪除或從未分配值的索引,不會調用它。
所以, Array(N)
不夠; Array(N).map(Number.call, Number)
將致使長度爲N的未初始化數組。
因爲此技術依賴於ECMAScript 5中指定的Function.prototype.apply()
行爲,所以在ECMAScript 5以前的瀏覽器(例如Chrome 14和Internet Explorer 9)中將沒法使用 。
您可使用此:
new Array(/*any number which you want*/) .join().split(',') .map(function(item, index){ return ++index;})
例如
new Array(10) .join().split(',') .map(function(item, index){ return ++index;})
將建立如下數組:
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]