2010-07-04 20 views
27

我正在使用JavaScript和jQuery。我想實施params。在C#中,它看起來像這樣:如何最好地在JavaScript中實現params?

/* 
* odp  the object to test 
* error a string that will be filled with the error message if odp is illegal. Undefined otherwise. 
* 
* Returns true if odp is legal. 
*/ 
bool isLegal(odp, out error); 

在JS中做這種事情的最佳方法是什麼?對象?

function isLegal(odp, errorObj) 
{ 
    // ... 
    errorObj.val = "ODP failed test foo"; 
    return false; 
} 

Firebug告訴我,上述方法可行,但有沒有更好的方法?

+0

尼克,我知道這是不久前,但我想我終於爲你[答](https://stackoverflow.com/a/48517986/1016343)。是的,你可以在JavaScript中完成輸出參數。 – Matt 2018-01-30 09:30:33

回答

13

我認爲這是非常多的唯一方法(但我不是一個硬核JavaScript程序員;))。

,你也可以考慮什麼是使用一個回調函數:

function onError(data) { 
    // do stuff 
} 


function isLegal(odp, cb) { 
    //... 
    if(error) cb(error); 
    return false; 
} 

isLegal(value, onError); 
+1

+1,這是更實用的方法,但它需要您立即處理錯誤。這也是我的經驗中最常見的。 – gradbot 2010-07-04 21:58:22

33

通過@Felix克林提到的回調方法可能是最好的主意,但我也發現,有時很容易利用的Javascript對象文字語法,只是有你的函數出錯返回一個對象:

function mightFail(param) { 
    // ... 
    return didThisFail ? { error: true, msg: "Did not work" } : realResult; 
} 

那麼當你調用該函數:

var result = mightFail("something"); 
if (result.error) alert("It failed: " + result.msg); 

沒有花哨和幾乎沒有防彈,但當然它可以在一些簡單的情況下。

+0

+1,這種方法在JSON調用中很常見,但我很少在代碼中看到它。 – gradbot 2010-07-04 21:59:48

+1

+1我喜歡這個... – Julien 2012-03-05 09:24:48

+1

因爲我對Javascript如何處理參數很感興趣,所以來到這個頁面,我對接受的答案感到失望。在編寫非常程序化的邏輯時,具有確定的返回類型以及具有確定類型的一對多出參數的能力是非常強大的。不幸的是,憑藉我的名聲,我無法投票。 – 2014-06-10 22:38:00

13

是的,正如你自己所說的,對象是在JavaScript中通過引用傳遞數據的最好和唯一的方法。我會保持你的isLegal的功能,例如,簡單地這樣稱呼它:

var error = {}; 
isLegal("something", error); 
alert(error.val); 
+1

+1,這種風格是最接近C#的。 – gradbot 2010-07-04 22:00:49

+0

這太棒了.. – 2015-11-26 11:03:44

3

還有另一種方式JS可以通過「出」參數。但我相信你已經提到了最適合你的情況。

數組也通過引用傳遞,而不是值。因此就像您可以將對象傳遞給函數,然後在函數中設置對象的屬性,然後返回並訪問該對象的屬性一樣,可以類似地將數組傳遞給函數,設置數組的某些值在函數內部,並返回並訪問數組外的值。

所以在每一種情況下你都可以問自己:「數組還是對象更好?」

+0

雖然這是可能的,但爲了清晰調用代碼,我建議@ Pointy的回答:使用重載的返回值,因爲它的邊界更清晰。 – cmroanirgo 2013-01-13 20:50:13

1

我不會發布任何code但在這裏的答案是什麼都做不到這是把原因。我在本地JS競技場工作,出現了一些問題,因爲我們無法寫入參數而沒有難看的黑客攻擊。

這是我的解決方案:

// Functions that return parameter data should be modified to return 
    // an array whose zeroeth member is the return value, all other values 
    // are their respective 1-based parameter index. 

That doesn't mean define and return every parameter. Only the parameters that recieve output.

其原因的做法是這樣的:可能需要的任何數量的程序Multiple return values。這就產生了一種情況,即具有命名值的對象(最終不會與所有操作的詞彙上下文同步),不斷地需要被記住以便適當地使用該過程。

使用規定的方法,您只需知道what you calledwhere you should be looking而不是必須知道您在尋找什麼

還有一個優點是,「健壯和愚蠢的」可以編寫包圍所需的過程調用,以使此操作「更透明」的alogrithms。

這將是明智的使用objectfunction,或array(所有這一切都是對象)作爲一個「回寫輸出」參數,但我相信,如果有多餘的工作一定要做,它應該由編寫該工具包的人來完成,以使事情更簡單,或擴展功能。

這是一個適合所有情況的答案,讓APIs看起來應該在第一眼看起來,而不是看起來像和每個類似的意大利麪條編織掛毯,無法弄清楚的hobble-cobbled編織如果它是定義數據

恭喜,祝你好運。

我正在使用webkitgtk3和接口一些本地C庫特效。所以這個經過驗證的代碼示例至少可以用於說明目的。

// ssize_t read(int filedes, void *buf, size_t nbyte) 
SeedValue libc_native_io_read (SeedContext ctx, SeedObject function, SeedObject this_object, gsize argument_count, const SeedValue arguments[], SeedException *exception) { 


    // NOTE: caller is completely responsible for buffering! 

        /* C CODING LOOK AND FEEL */ 


    if (argument_count != 3) { 
     seed_make_exception (ctx, exception, xXx_native_params_invalid, 
      "read expects 3 arguments: filedes, buffer, nbyte: see `man 3 read' for details", 
      argument_count 
     ); return seed_make_undefined (ctx); 
    } 

    gint filedes = seed_value_to_int(ctx, arguments[0], exception); 
    void *buf = seed_value_to_string(ctx, arguments[1], exception); 
    size_t nbyte = seed_value_to_ulong(ctx, arguments[2], exception); 

    SeedValue result[3]; 

    result[0] = seed_value_from_long(ctx, read(filedes, buf, nbyte), exception); 
    result[2] = seed_value_from_binary_string(ctx, buf, nbyte, exception); 

    g_free(buf); 
    return seed_make_array(ctx, result, 3, exception); 

} 
+0

這是一個在JavaScript中返回參數的好主意。對我最有意義。 – Sunil 2014-01-31 21:43:57

1

以下是我正在使用的方法。這是這個問題的答案。但是代碼尚未經過測試。

function mineCoords(an_x1, an_y1) { 
    this.x1 = an_x1; 
    this.y1 = an_y1; 
} 

function mineTest(an_in_param1, an_in_param2) { 

    // local variables 
    var lo1 = an_in_param1; 
    var lo2 = an_in_param2; 

    // process here lo1 and lo2 and 
    // store result in lo1, lo2 

    // set result object 
    var lo_result = new mineCoords(lo1, lo2); 
    return lo_result; 
} 

var lo_test = mineTest(16.7, 22.4); 
alert('x1 = ' + lo_test.x1.toString() + ', y1 = ' + lo_test.y1.toString()); 
2

我正在使用回調方法(類似於Felix Kling's approach)來模擬輸出參數的行爲。我的答案與Kling的不同之處在於,回調函數充當引用捕獲閉包而不是處理程序。

這種方法受到JavaScript冗長的匿名函數語法的限制,但它嚴格地從其他語言中複製出參數語義。

function isLegal(odp, out_error) { 
    //... 
    out_error("ODP failed test foo"); // Assign to out parameter. 
    return false; 
} 

var error; 
var success = isLegal(null, function (e) { error = e; }); 

// Invariant: error === "ODP failed test foo". 
0

通常的方法給你在Javascript中列出的具體使用情況,而事實上大多數高級語言,是靠錯誤(又名例外),讓你知道什麼時候發生了異常的發生。沒有辦法在Javascript中通過引用傳遞值類型(字符串,數字等)。

我只是這樣做。如果您確實需要將自定義數據返回給調用函數,則可以繼承Error。

var MyError = function (message, some_other_param) 
{ 
    this.message = message; 
    this.some_other_param = some_other_param; 
} 
//I don't think you even need to do this, but it makes it nice and official 
MyError.prototype = Error; 
... 
if (something_is_wrong) 
    throw new MyError('It failed', /* here's a number I made up */ 150); 

我知道,捕捉異常是一種痛苦,但後來又一次跟蹤引用。

如果你真的很需要的東西,接近變量的行爲,目的是通過默認引用傳遞,並能輕而易舉地從其他scopes--

function use_out (outvar) 
{ 
    outvar.message = 'This is my failure'; 
    return false; 
} 

var container = { message : '' }; 
var result = use_out(container); 
console.log(container.message); ///gives the string above 
console.log(result); //false 

捕獲數據,我認爲這正好一個一些方法來回答你的問題,但我認爲你的整個方法從一開始就被打破。Javascript支持許多更加優雅和強大的方法來從函數中獲取多個值。做一些關於發電機,關閉,地獄甚至回撥的閱讀在某些情況下可以很好 - 查看延續傳球的風格。

我這整個咆哮點是鼓勵任何閱讀他們的編程風格適應限制,他們正在使用,而不是試圖迫使他們從其他語言把它學會了語言的能力。

(BTW有些人強烈反對關閉,因爲它們會導致惡副作用,但我不會聽他們的。他們是較真的,副作用是很多的應用幾乎是不可避免的沒有很多的繁瑣的回溯和周圍步進着-GET-有從 - 這裏的障礙。如果需要的話,在一個整潔的詞彙範圍,讓他們都在一起,而不是分散在晦澀的指針和引用的hellscape聽起來好多我)

0

到目前爲止我看到的答案都沒有在JavaScript中實現參數,因爲它們在C#中使用(out關鍵字)。它們只是一個解決方法,在發生錯誤時返回對象。

但你會怎麼做,如果你真的需要out參數?

,因爲JavaScript不直接支持它,你需要建立的東西是接近C#的out參數。看看這種方法,我在JavaScript中模擬C#的DateTime.TryParse函數。輸出參數是結果,並且,因爲JavaScript不提供out關鍵字,我使用.value在函數內部傳遞函數之外的值(作爲啓發MDN suggestion):

// create a function similar to C#'s DateTime.TryParse 
 
var DateTime = []; 
 
DateTime.TryParse = function(str, result) { 
 
    result.value = new Date(str); // out value 
 
    return (result.value != "Invalid Date"); 
 
}; 
 

 
// now invoke it 
 
var result = []; 
 
if (DateTime.TryParse("05.01.2018", result)) { 
 
    alert(result.value); 
 
} else { 
 
    alert("no date"); 
 
};

運行該代碼段,你會看到它的作品。請注意,result需要初始化爲,之前的空數組您調用該函數。這是必需的,因爲在函數內部「注入」.value屬性。


現在你可以使用上面的圖案來寫一個函數作爲一個在你的問題(這也說明你如何模仿C#中的新丟棄參數out _):

// create a function similar to C#'s DateTime.TryParse 
 
var DateTime = []; 
 
DateTime.TryParse = function(str, result) { 
 
    result.value = new Date(str); // out value 
 
    return (result.value != "Invalid Date"); 
 
}; 
 

 
// returns false, if odb is no date, otherwise true 
 
function isLegal(odp, errorObj) { 
 
    if (DateTime.TryParse(odp, [])) { // discard result here by passing [] 
 
    // all OK: leave errorObj.value undefined and return true 
 
    return true; 
 
    } else { 
 
    errorObj.value = "ODP failed test foo"; // return error 
 
    return false; 
 
    } 
 
} 
 

 
// now test the function 
 
var odp = "xxx01.12.2018xx"; // invalid date 
 
var errorObj = []; 
 
if (!isLegal(odp, errorObj)) alert(errorObj.value); else alert("OK!");

注:使用丟棄參數如上圖所示,而不是在JavaScript中你可以ALS Ø使用undefined檢查,即在功能檢查中的

if (result === undefined) { 
    // do the check without passing back a value, i.e. just return true or false 
}; 

然後,它可以完全省略result作爲參數,如果沒有必要,所以你可以調用它像

if (DateTime.TryParse(odp)) { 
    // ... same code as in the snippet above ... 
}; 
相關問題