2011-12-21 103 views
1
var foo = { 
    bar: function() { return this.baz; }, 
    baz: 1 
    }; 
    (function(){ 
    return typeof arguments[0](); 
    })(foo.bar); 

爲什麼此代碼返回undefined函數參數傳遞和返回

我會假設arguments[0]將持有foo.bar,這是一個函數。當通過arguments[0]()調用時,它應該返回函數評估的結果,在這種情況下爲1。因此,typeof arguments[0]()應返回「號碼」(如typeof 1)。相反,它返回undefined。爲什麼?

回答

-2

這指的是條形函數本身。

var foo = { 
    bar: function() {return foo.baz; }, 
    baz:1 
    }; 
    (function(){ 
    return typeof arguments[0](); 
    })(foo.bar); 

小提琴:http://jsfiddle.net/W9Jqb/

+1

它不。 'this'關鍵字指向執行上下文。在給定的例子中,這就是調用它的匿名函數的範圍。由於它本身是從全局範圍調用的,因此'this'只是指向全局'window'對象。 – PPvG 2011-12-21 10:04:23

+1

如果我們在這個對象中有很多的功能,並且我們想改變foo的名字,那將會令人尷尬:) – abuduba 2011-12-21 10:09:39

+1

爲什麼這是公認的答案?我認爲這個問題是*「爲什麼這個代碼返回'undefined'?」*,而不是*「你能幫我找到一個醜陋的黑客來解決這個問題嗎?」*。 – PPvG 2011-12-23 10:34:15

5

代碼將無法在另一種情況下使用時

可以使用apply()方法重新定義的背景下,像這樣

var foo = { 
    bar: function() { return this.baz; }, 
    baz: 1 
}; 

(function(){ 
    return arguments[0].apply(foo); 
})(foo.bar); 
你就失去了參考Foo對象的 this.baz匿名函數內部,因爲工作

和這個返回正確1因爲apply()方法改變執行上下文作爲參數傳遞的對象

typeof arguments[0].apply(foo); 

如預期的那樣返回number

+0

回報的typeof參數[0]。適用(foo);我想這就是你的意思。我看到了應用的方便性和執行環境的意義。 – 2011-12-21 09:59:25

8

要理解爲什麼this不是在函數所在,你要明白,JavaScript沒有類對象的引用。它有功能。

在JavaScript中,函數從不嚴格地「綁定」到對象,就像它們在Java,C#等有類語言中一樣。 javascript函數只是另一種類型,如stringnumber,這意味着您可以像任何其他類型一樣在變量中傳遞函數。在您的示例中,foo.bar中包含的函數完全不知道foo。這只是一個功能,意識到自己的業務。

那麼this關鍵字是做什麼用的?它指向執行上下文。在您的示例中,您從全局範圍(即window)調用foo.bar中的函數,這就是它指向的內容。您可以使用apply()在正確的範圍內調用該函數,但爲此您需要訪問該範圍(在本例中爲foo對象)。這就消除了僅僅傳遞函數的安全優勢,沒有任何對象。爲了「解決」這個「問題」,ECMAScript 5(未來版本的JavaScript)引入了bind()。這個方便的功能,您可以將它傳遞給另一個函數,這樣之前綁定到特定的執行範圍的函數:

var foo = { 
    bar: function() { return this.baz; }, 
    baz: 1 
}; 

var callback = foo.bar.bind(foo); 

(function(){ 
    return typeof arguments[0](); 
}(callback)); 
+0

另外,請注意'bind()'實際上可以在大多數現代瀏覽器中使用,如今:http://jsfiddle.net/54dzA/。除了我們還不能使用它,因爲IE 6不支持它。或IE 7或IE 8。 – PPvG 2011-12-21 10:50:42

1

您可以通過this聲明reffering爲foo。

你應該寫這樣的包裝下面這將是否會非常有幫助,我們想改變foo的名字的時候,我們就會有很多的功能,在富

var foo = { 
    bar: function() { return this.baz; }, 
    baz: 1 
    }; 

(function(a){ 
for(var i in a){ 
    if(typeof a[i] === "function"){ 

     a[i] = (function(f){ 
      return function(){ 
       return f.apply(a,arguments); 
      } 
     })(a[i]) 
    } 
} 
})(foo); 

    (function(){ 
    return typeof arguments[0](); 
    })(foo.bar);