2012-09-23 35 views
2

我想用自調用函數初始化一個數組,初始值爲從0到4的數字的平方。new關鍵字創建一個新對象,因此可以在關鍵字new之後訪問在IIFE正文中使用this.xthis[x]的新創建對象的字段。該代碼是:使用自調用函數進行數組初始化

var arr = new (function() { 
    for (var i=0; i<5; i++) { this[i]=i*i; } 
})(); 

現在,你可以訪問變量arr的相應字段,如arr[4],並獲得16。如果你只使用arr就像使用對象一樣工作,那就太好了,但是一旦你嘗試像數組一樣對待它,你就會遇到問題。也就是說,你可以不適用像reduce功能吧:

< arr.reduce(...); 
> TypeError: arr.reduce is not a function 

這是因爲arr是一個真正的對象,而不是一個數組:

< arr; 
> ({0:0, 1:1, 2:4, 3:9, 4:16}) 

因此,這裏是我的問題:如何避免這樣的行爲在這個方法內?如何讓JavaScript將這個新創建的對象解釋爲一個數組?

+2

爲什麼不直接返回數組?例如,'var arr =(function(){ret = []; for(var i = 0; i <5; i ++){ret [i] = i * i;} return ret;)();' –

回答

3

沒有IEFE它是更短,更明確:

var arr = []; 
for (var i=0; i<5; i++) arr[i] = i*i; 

沒有額外的計數器變量i,你可以這樣做:

for (var arr=[]; arr.length<5;) arr[arr.length] = Math.pow(2, arr.length); 
2

你並不需要使用new關鍵字進行...

var arr = (function() { 
       var x = []; 
       for (var i=0; i<4; i++) 
        x.push(i*i); 
       return x; 
      })(); 

new關鍵字創建一個對象,並設置它的構造函數,然後結合this它和調用函數。除了調用函數之外,你不需要任何東西,所以只需要這樣做。

+0

目的是寫一個oneliner,避免像'var x = []; ... return x;'。 比較: 'var arr = [];對於(var i = 0; i <5; i ++)arr.push(i * i);' 好的,這是一個oneliner,但是初始值可能會以更復雜的方式計算。 –

+0

@AndreiSmolensky:使用匿名函數並立即調用它們的原因是由於Javascript的範圍規則(事實上你不能擁有塊級的本地語言)。在初始化代碼中寫入初始化代碼會泄露變量(例如,在你的例子中是'i')。任何數量的javascript代碼都可以是單行代碼,因爲除了一些有關分號插入的白癡規則外,換行符相當於Javascript的空間。 – 6502