2012-08-23 80 views
0

我有以下功能:「這個」無效的範圍與功能

function a() { 
    var d = { 
     foo : "text" 
    }; 
    for(var b in c) { 
     if(c.hasOwnProperty(b)) { 
     d[b] = function() { 
      return c[b].apply(this, arguments); 
     }; 
     } 
    } 
    return d; 
    } 

    var c = { 
    a : function() { alert(this.foo); }, 
    b : function() { return this.a(); } 
    } 

    a().a(); // nothing happens 

    // but the following works : 
    var c = { 
    a : function() { alert(this.foo); } 
    } 

    a().a(); // output : text 

我想,這是因爲在.apply方法this。我怎樣才能解決這個問題?

+3

天啊。你爲什麼要寫這麼複雜的行爲?! – Florent

+0

@Florent只是爲了讓生活更輕鬆.... – Neal

+0

函數a()將會像100或1000次那樣使用,所以我不希望它包含很多大函數,所以我想以某種方式鏈接一個( ).a()到ca(),而不是每次都在()函數中創建它。我無法創建全局函數,因爲很多函數可能已經由javascript定義。 – John

回答

1

它不工作,因爲您的函數「a」中的迭代器變量「b」是共享由每個關閉。

試試這個:

for(var b in c) { 
    if(c.hasOwnProperty(b)) { 
    d[b] = function(b) { 
     return function() { return c[b].apply(this, arguments); }; 
    }(b); 
    } 
} 

Here is the working version as a jsfiddle.

+0

謝謝,它現在可以工作。 – John

0

一個()在全球範圍內執行。當你調用c [b] .apply(this,arguments)時,它也會在全局範圍內執行。 for循環是循環迭代的,它首先遍歷b,它在全局作用域中執行b,它在全局作用域中調用a,循環調用c,在全局作用域中調用b,...

結果:RangeError:超出最大調用堆棧大小

+0

這並不準確。外部「a」返回一個擁有自己「a」屬性的對象。因此,'a()。a()'將導致該內部函數將第一個'a()'返回的對象作爲其this引用。 – Pointy

+0

是的,我發現自己發佈後,但我想增加另一層間接的答案是無助於澄清事情。 –