2016-05-20 6 views
3

配列と別の関数を入力とする関数を記述しようとしています。私は供給機能について知っている唯一のことは、しかし、それはどちらか関数が配列または単一値の入力を受け取るかどうかを調べる

  1. は、単一の数の引数を取り、新しい番号または

  2. 数字の配列を受け取りを返し、数字の新しい配列を返すことです。私の機能で

、私はそれがArray.prototype.map()付属の関数を呼び出すかどうかを決定するために第一又は第二のケースだかどうかを確認したいです。

したがって、これらの二つの機能を持つ...

var unknownFunction = function(unknownInput) { 
    //Does stuff with input 

    //returns number or array of numbers... 
    return someValueOrValues 
} 

var mainFunction = function(anArray, preFunction){ 

    // SOME CODE TO CHECK IF ARG NEEDS TO BE NUMBER OR ARRAY 
    // ... 
    // ... 

    **ANSWER WOULD FIT HERE** 


    if(argIsNumber === true){ 
    // function takes NUMBER 
    anArray = anArray.map(preFunction) 
    }else{ 
    // function takes ARRAY 
    anArray = preFunction(anArray) 
    } 

    // DO STUFF WITH ARRAY AFTER USER FUNCTION HAS MADE IT'S MODIFICATIONS 
    // ... 
    // ... 
    // ... 

    return anArray; 
} 

それを呼び出すために最善の方法を把握するために最初の関数の内部で突くする方法はありますか?

+2

try/catchに入れることができます。配列にアクセスしようとすると数字だけでエラーが発生します。 – durbnpoisn

+4

これはできません。関数が関数を実行しないで配列や数値を受け入れるかどうかを(一般的に)知ることはできません。これは[Halting Problem](https://en.wikipedia.org/wiki/Halting_problem)のサブクラスであり、解決策はありません。 – meagar

+0

@meagarは正しいですが、Function.prototype.toStringを使用すると、ほとんどのブラウザで関数のソースコードとパラメータ名のいくつかの規則が返されます。最初のパラメータの名前がarrayであるが、偽のprofではないが動作するかもしれない場合 – csharpfolk

答えて

1

私はtry-catchアプローチを使用しますが、実際の関数をテストし、次のtry関数を試してみると失敗します。

あなたの関数がunknow関数として渡されるとしましょう。彼らはそれぞれ1を加えることによって数を変更するだけです。

function onlyTakesNumber(num) { 
    return num + 1; 
} 

function onlyTakesArray(arr) { 
    return arr.map(num => num + 1); 
} 

ここにあなたの主な機能があります。 tryの中の追加のマップの理由は、配列がonlyTakesNumber関数に渡された場合に、文字列を返さないようにテストすることです。追加のテストマップは、コードがcatchにホップする必要があるかどうかを再度明らかにする。ここで

var mainFunction = function (anArray, preFunction) { 

    try { 
     // the map on the end checks to make sure you did not get a string back 
     anArray = preFunction(anArray).map(test => test); 
    } 
    catch (e) { 
     anArray = anArray.map(preFunction); 
    } 

    // Do whatever else with anArray 

    return anArray; 
}; 


console.log(mainFunction([1, 2, 3], onlyTakesArray)); // [2, 3, 4] 
console.log(mainFunction([7, 8, 9], onlyTakesNumber)); // [8, 9, 10] 

あなたが最も短い答えは

+0

恐ろしい解決策。これはアンチパターンとして知られています! –

+0

@MatíasFidemraizer、あなたの答えは実際の問題に対処さえしていません。OPは "私が提供されている機能について知っているのはそれだけですが..."です。彼は、これを行うかどうかを決める関数にアクセスすることはできません: 'func.type =" number ";'、あなたの答えにはヒンジが付いています。 – KevBot

+0

関数オブジェクトにプロパティを追加できるように、その関数にアクセスする必要はありません。 –

2

JavaScriptは動的に型指定された言語なので、関数の入力パラメータは、引数で呼び出されると、型を持ちます。

一つエレガントで可能なアプローチは、入力パラメータの型ヒントために全体与えられた関数にプロパティを追加している:あなたはconvention over configurationを使用してコーディングを考える必要があり、動的型付けの言語で作業する場合

var func = function() {}; 
func.type = "number"; // a function decorator 

var mainFunction = function(anArray, inputFunc) { 
    if(typeof inputFunc != "function") { 
     throw Error("Please supply a function as 'inputFunc'!"); 
    } 

    switch(inputFunc.type) { 
     case "number": 
      return anArray.map(preFunction); 

     case "array": 
      return preFunction(anArray); 

     default: 
      throw Error("Type not supported"); 
    } 
}; 

mainFunction([1,2,3], func); 

をして/またはduck typingを使用します。強く型付けされた言語で提供される型の安全性は、良い文書に置き換えられます。例えば

が述語 機能の期待されるタイプ何 mainFunctionを伝えるために typeプロパティを持つ2番目のパラメータとしての機能を提供します。

+1

なぜ私がdownvoteを持っているのか知っていて、何とか私のアプローチが壊れているかどうかを知ることができます。 –

+0

Matias、残念ながら@kevbotの観測結果は正確です - 私は関数にアクセスできません型プロパティが追加されるかどうかを決定します。それにもかかわらず、私はこれはかなり独創的な解決策だと思うし、try/catchソリューションの原因が問題を引き起こし始めるならば、私はこのアプローチを働かせる方法を見つけようとします。ありがとう! –

+0

@SteveLadavichコメントに他の回答者に言ったように、関数にアクセスして関数オブジェクトに型プロパティを追加する必要はありません。これらの関数を定義するのは、プロパティ全体を追加するだけです。 AngularJSでは、このパターンは*明示的な注射*: 'controller。$ inject = [" $ scope "]'を定義するために使用され、* decorator *と共通のパターンです。 –

-1

でこれをテストすることができJSFiddleです: "あなたはできません"。

+1

最短のコメントは "なぜ?"です。 – ocanal

+0

できません! 外部関数は、あなたがハードコードして戻さない限り、他の関数の引数にアクセスすることはできません。 –

+0

@ocanal、昨日は、JavaScriptの新人は、ある種のハッキングがあるかどうかを尋ねることは禁じられていないことを知っていますが、その答えは永遠に続くでしょう:あなたはできません - それはセキュリティ上の問題です。 –

関連する問題