[英]Function Arguments Passing and Return
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]()
應該返回“ Number”(類似於typeof 1
)。 而是返回undefined
。 為什么?
要了解為什么this
不是對函數所在對象的引用,您必須了解JavaScript沒有類。 它具有功能。
在JavaScript中,函數永遠不會嚴格地“綁定”到對象,就像它們在Java,C#等有類語言中一樣。 javascript函數只是另一種類型,例如string
和number
,這意味着您可以像其他任何類型一樣在變量中傳遞函數。 在您的示例中, 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));
該代碼將無法正常工作,因為在匿名函數中,當在另一個上下文中使用時,您將丟失對foo對象的this.baz
的引用
您可以使用apply()
方法重新定義上下文,如下所示
var foo = {
bar: function() { return this.baz; },
baz: 1
};
(function(){
return arguments[0].apply(foo);
})(foo.bar);
並正確返回1
因為apply()方法將執行上下文更改為作為參數傳遞的對象
typeof arguments[0].apply(foo);
返回number
如預期
您可以通過this
語句引用foo。
您應該像下面這樣編寫一個包裝器,如果在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);
這指的是酒吧功能本身。
var foo = {
bar: function() {return foo.baz; },
baz:1
};
(function(){
return typeof arguments[0]();
})(foo.bar);
小提琴: http : //jsfiddle.net/W9Jqb/
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.