簡體   English   中英

如何將數據傳遞給JavaScript中的匿名函數?

[英]How is data passed to anonymous functions in JavaScript?

當我將'this'傳遞給匿名函數時:

MyClass.prototype.trigger = function(){
    window.setTimeout(function(){this.onTimeout();},1000);
}

我得到一個“this.onTimeout不是一個函數” - 錯誤。 我想在匿名函數執行時'this'不再可用了嗎? 所以我一直這樣做:

MyClass.prototype.trigger = function(){
    var me = this
    window.setTimeout(function(){me.onTimeout();},1000);
}

這真的是你應該做的事情嗎? 它有點工作,但感覺很奇怪。

然后我們有這個例子:

$(function(){
    function MyClass(){
        this.queue = new Array();
    }
    MyClass.prototype.gotAnswer = function(count){
        $('body').append("count:"+count+"<br/>");
    }
    MyClass.prototype.loadAll = function(){
        var count = 0;
        var item;
        while(item = this.queue.pop()){
            count++;
            var me = this;
            $.getJSON("answer.html",{},function(data){me.gotAnswer(count);});
        }
    }

    var o = new MyClass();
    o.queue.push(1);
    o.queue.push(2);
    o.loadAll();

});

這輸出:

2
2

不應該輸出:

1
2

代替? 然后我發現將$ .getJSON語句放在另一個函數中使它全部工作:

MyClass.prototype.loadAll = function(){
    var count = 0;
    var item;
    while(item = this.queue.pop()){
        count++;
        this.newRequest(count);
    }
}
MyClass.prototype.newRequest = function(count){
    var me = this;
    $.getJSON("answer.html",null,function(data){ me.gotAnswer(count); });
}

這輸出:

1
2

(或者相反。)這里發生了什么? 將變量傳遞給anonnymous函數的正確方法是什么?

抱歉這個令人困惑和冗長的帖子。

你所經歷的是正確的行為 - 這不是一個好的行為,但它是語言的一部分。 每個函數定義中重置“this”的值。 有四種方法可以調用具有不同方法來設置“this”的函數。

  1. 常規函數調用
      myFunc(param1,param2); 
    這種調用函數的方法總是將“this”重置為全局對象。 這就是你的情況。
  2. 將其稱為一種方法
      myObj.myFunc(param1,param2); 
    毫無疑問,將“this”設置為調用該方法的任何對象。 在這里,“this”==“myObj”。
  3. 應用方法調用
      myFunc.apply(myObj,[param1,param2]) 
    這是一個有趣的 - 這里“this”設置為您作為apply方法的第一個參數傳遞的對象 - 就像在沒有該方法的對象上調用方法一樣(注意函數被寫為這樣稱呼)。 默認情況下,所有函數都具有apply方法。
  4. 作為構造函數(帶“new”)
      myNewObj = new MyConstructor(param1,param2); 
    當您以這種方式調用函數時,“this”被初始化為一個新對象,該對象從函數的prototype屬性繼承方法和屬性。 在這種情況下,新對象將繼承自MyConstructor.prototype。 此外,如果您未明確返回值,則將返回“this”。

您使用的解決方案是推薦的解決方案 - 將“this”的外部值分配給另一個在您的函數內仍然可見的變量。 我唯一要改變的是將變量稱為“那個”,如TörökGábor所說 - 這是事實上的標准,可能會讓你的代碼更容易為其他程序員閱讀。

你對閉包感到困惑。

對於第一個問題,是的,你是對的,這就是它可以做到的方式。 唯一的區別是有約定命名變量that保存this

MyClass.prototype.trigger = function(){
    var that = this;
    window.setTimeout(function(){that.onTimeout();},1000);
}

在StackOverflow上已有一個很好的關於此的線程。 檢查問題的答案javascript關閉是如何工作的?

你的第二個問題是循環Javascript閉包的完全重復- 簡單的實際例子

如果在新方法中,你將遇到同樣的問題:newRequest你必須使用“for”或“while”語句。 另一個解決方案是創建一個閉包:

像那樣:

$.getJSON("answer.html",{},(function(me){return function(data){me.gotAnswer(count);}})(this));

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM