2010-06-30 34 views
47

mam typową funkcję JavaScript z niektórych parametrówjavascript opcjonalne argumenty funkcji

my_function = function(content, options) { action } 

gdybym wywołać funkcję w następujący sposób: „Opcje”

my_function (options) 

argument jest przekazywane jako „treści”

jak to obejść, aby można było przekazać oba argumenty lub tylko jeden? dziękuję

Odpowiedz

81

musisz zdecydować, jak który parametr, który chcesz traktować jako pojedynczy argument. Nie możesz traktować ich jako obu, content i options.

widzę dwie możliwości:

  1. albo zmienić kolejność argumentów, tj function(options, content)
  2. Sprawdź czy options jest zdefiniowana:

    function(content, options) { 
        if(typeof options === "undefined") { 
         options = content; 
         content = null; 
        } 
        //action 
    } 
    

    Ale potem trzeba odpowiednio udokumentować, co się dzieje, jeśli przekazujesz tylko jeden argument do funkcji, ponieważ nie jest to od razu jasne, patrząc na podpis.

+1

undefined jest właściwością globalną o stałej wartości, dlatego nie trzeba jej podawać. W przestarzałych przeglądarkach można przypadkowo ustawić dowolną wartość, ale nie jest tak w przypadku współczesnych przeglądarek. – andreszs

+5

@Andrew: 'typeof' zawsze zwraca ciąg znaków. Alternatywnie, 'if (options === undefined)' również by działało. Ale jak już powiedziałeś, możliwe jest przesłonięcie "undefined" w starszych przeglądarkach, więc nadal powszechną praktyką (jak sądzę) jest nie używanie bezpośrednio 'undefined' (chyba że zdefiniowałeś gdzieś jawnie). –

+1

nie porównuj ciągów z '===', nie są one konieczne dla tego samego obiektu, jeśli mają taką samą zawartość. – inetphantom

14

tak:

my_function (null, options) // for options only 
my_function (content) // for content only 
my_function (content, options) // for both 
0

dostaniesz ONZ przyjęła wartość argumentu jako niezdefiniowane. Ale w twoim przypadku musisz przekazać co najmniej wartość zerową w pierwszym argumencie.

Albo trzeba zmienić definicję metody jak

my_function = function(options, content) { action } 
21
my_function = function(hash) { /* use hash.options and hash.content */ }; 

a następnie zadzwonić:

my_function ({ options: options }); 
my_function ({ options: options, content: content }); 
+0

co jest hash rzeczywiście? – BlueBird

+0

Dlaczego nazywacie to "hash"? –

+0

@Muneer: To tylko przykład. – Sarfraz

0

Zadzwoń jak tego

my_function ("", options); 
3

Możesz także rozróżnić, jaki typ zawartości masz. Opcje kiedyś przedmiotem zawartość jest wykorzystywana jako ciąg, więc można powiedzieć:

if (typeof content === "object") { 
    options = content; 
    content = null; 
} 

Lub jeśli są mylone ze zmiany nazwy, można użyć tablicę argumentów, które mogą być bardziej prosta:

if (arguments.length === 1) { 
    options = arguments[0]; 
    content = null; 
} 
+1

Preferuję tę odmianę: 'var optional_arg = arguments.length> = 1? argumenty [0]: "domyślna wartość"; ' –

1

Możesz przekazać wszystkie opcjonalne argumenty w obiekcie jako pierwszy argument. Drugim argumentem jest twój oddzwonienie.Teraz można przyjąć dowolną liczbę argumentów, jak chcesz w swoim pierwszym obiektem argumentu, i sprawiają, że opcja tak:

function my_func(op, cb) { 
    var options = (typeof arguments[0] !== "function")? arguments[0] : {}, 
     callback = (typeof arguments[0] !== "function")? arguments[1] : arguments[0]; 

    console.log(options); 
    console.log(callback); 
} 

Jeśli nazwać bez przejazdu argument opcji, będzie ona domyślnie pusty obiektu:

my_func(function() {}); 
=> options: {} 
=> callback: function() {} 

Jeśli zadzwonisz go z argumentem opcji można uzyskać wszystkie swoje params:

my_func({param1: 'param1', param2: 'param2'}, function() {}); 
=> options: {param1: "param1", param2: "param2"} 
=> callback: function() {} 

Może to oczywiście być manipulowane, aby pracować z większą ilością argumentów niż dwa, ale dostać more współpracowników nfusing. Jeśli możesz po prostu użyć obiektu jako pierwszego argumentu, możesz przekazać nieograniczoną liczbę argumentów za pomocą tego obiektu. Jeśli absolutnie potrzebujesz więcej argumentów opcjonalnych (np. My_func (arg1, arg2, arg3, ..., arg10, fn)), sugerowałbym użycie biblioteki takiej jak ArgueJS. Nie używałem go osobiście, ale wygląda obiecująco.

+0

bardzo dziękuję ... Dokładnie tego szukam. Mam 6 parametrów w mojej funkcji. niektóre parametry mają wartości domyślne. Ale niektóre parametry powinny być ustawione w wywołaniu funkcji. Myślę, że ta odpowiedź dobrze pasuje do mojej sprawy. Jeszcze raz dziękuję ... :) –

-1

Można również umieścić czek w akcji jak: options = !options ? content : options że ustawia opcje do pierwszego argumentu, jeśli nie sekund został przekazany, a następnie po prostu ustawić zawartość null (albo zignorować, jednak chcesz sprawdzić to)

2

Istnieją 2 sposoby, aby to zrobić.

1)

function something(options) { 
    var timeToLive = options.timeToLive || 200; // default to 200 if not set 
    ... 
} 

2)

function something(timeToDie /*, timeToLive*/) { 
    var timeToLive = arguments[1] || 200; // default to 200 if not set 
    .. 
} 

w 1), options jest obiekt JS, co kiedykolwiek potrzebne są atrybuty. Jest to łatwiejsze do utrzymania i przedłużenia.

W 2) podpis funkcji jest czytelny, aby przeczytać i zrozumieć, że można podać drugi argument. Widziałem ten styl używany w kodzie i dokumentacji Mozilli.

1

Utworzono prostą bibliotekę do obsługi opcjonalnych argumentów z funkcjami JavaScript, patrz https://github.com/ovatto/argShim. Biblioteka jest rozwijana z myślą o Node.js, ale powinna być łatwa do przeniesienia do pracy z np. przeglądarki.

Przykład:

var argShim = require('argShim'); 
var defaultOptions = { 
    myOption: 123 
}; 

var my_function = argShim([ 
    {optional:'String'}, 
    {optional:'Object',default:defaultOptions} 
    ], function(content, options) { 
    console.log("content:", content, "options:", options); 
    }); 

my_function(); 
my_function('str'); 
my_function({myOption:42}); 
my_function('str', {myOption:42}); 

wyjściowa:

content: undefined options: { myOption: 123 } 
content: str options: { myOption: 123 } 
content: undefined options: { myOption: 42 } 
content: str options: { myOption: 42 } 

Głównym celem biblioteki są moduły interfejsów, gdzie trzeba, aby być w stanie obsługiwać różne wywołania wywiezionych funkcji modułu.

+0

To jest bardzo szczegółowe i dodatkowo używa słowa "default", które jest już słowem kluczowym w JS. Nie polecam. –

+0

Pewnie, że może to być trochę gadatliwe, ale zapewnia pewne dodatkowe funkcje i proste sprawdzanie obecności argumentów. Piszenie tych samych funkcji w każdej z funkcji musi być jeszcze bardziej szczegółowe. Również podczas gdy niektóre nie lubią to zastrzeżone słowa kluczowe mogą być swobodnie używane jako nazwy właściwości w ES5. Jednak cała lib była dość pochopnie napisana, więc twój (i mój) przebieg może się różnić :) – ovatto

1

Wystarczy kopnąć martwego konia, ponieważ musiałem wprowadzić opcjonalny argument w środku dwóch lub więcej wymaganych argumentów. Użyj tablicy arguments i użyj last jako wymaganego argumentu nieobowiązkowego.

my_function() { 
    var options = arguments[argument.length - 1]; 
    var content = arguments.length > 1 ? arguments[0] : null; 
} 
1

Istnieje ładny odczyt parametrów domyślnych w ES6 on the MDN website here.
W ES6 można teraz wykonać następujące czynności:

secondDefaultValue = 'indirectSecondDefaultValue'; 

function MyObject(param1 = 'firstDefaultValue', param2 = secondDefaultValue){ 
    this.first = param1; 
    this.second = param2; 
} 

Można to wykorzystać również w następujący sposób:

var object = new MyObject(undefined, options); 

, który ustawia wartość domyślną 'firstDefaultValue' dla pierwszego param1 i swoją options dla drugiego param2.

Here a demonstration in a fiddle

0

Z ES6:

function test(a, b = 3) { 
    console.log(a, ' ', b); 
} 

test(1);  // Output: 1 3 
test(1, 2); // Output: 1 2 
Powiązane problemy