2010-07-10 18 views

Odpowiedz

22

Jak znaleźć ten?

function Foobar(foobar) { 
    this.foobar = foobar; 
} 

Foobar.prototype = { 
    foobar: null 
}; 

Foobar.fromComponents = function(foo, bar) { 
    var foobar = foo + bar; 
    return new this(foobar); 
}; 
+2

wróć nowe to (foobar); nie działa. Zmieniam po powrocie nowy Foobar (foobar); i wszystko działa poprawnie. – isxaker

+6

Nie rozumiem. Czy możesz dodać kod, w którym faktycznie go używasz? Czy za każdym razem będziesz musiał dzwonić z Components? Ponieważ nie jest to naprawdę konstruktor, ale raczej funkcja pomocnicza. @ Odpowiedź bobince wydaje się wtedy bardziej dokładna. – hofnarwillie

+1

Jeśli to * działa *, jest to skomplikowany wzorzec. –

3

Czasami wartości domyślne parametrów są wystarczające dla wielu konstruktorów. A gdy to nie wystarcza, staram się łączyć większość funkcji konstruktora w funkcję init (other-params), która jest wywoływana później. Rozważ także użycie koncepcji fabryki, aby utworzyć obiekt, który może skutecznie tworzyć inne obiekty, które chcesz.

http://en.wikipedia.org/w/index.php?title=Factory_method_pattern&oldid=363482142#Javascript

+1

Metoda fabryczna to dobre rozwiązanie - pamiętaj, aby nie mylić jej z użyciem osobnej klasy fabrycznej, co prawdopodobnie nie ma znaczenia w tym przypadku. –

+1

Ten link nie prowadzi do nikąd. Na tej stronie nie ma kotwicy Javascript. – Rob

+1

wskazał na starą wersję. wiki usunięto przykłady js. – eruciform

88

JavaScript nie ma przeciążania funkcji, w tym metod lub konstruktorów.

Jeśli chcesz, aby funkcja zachowywała się inaczej, w zależności od liczby i typów przekazywanych parametrów, musisz ręcznie je wykryć. JavaScript z przyjemnością wywoła funkcję z mniejszą lub większą liczbą niż zadeklarowana liczba argumentów.

function foo(a, b) { 
    if (b===undefined) // parameter was omitted in call 
     b= 'some default value'; 

    if (typeof(a)==='string') 
     this._constructInSomeWay(a, b); 
    else if (a instanceof MyType) 
     this._constructInSomeOtherWay(a, b); 
} 

Można również uzyskać dostęp arguments jako tablica-jak uzyskać wszelkie dalsze argumenty przekazane w.

Jeśli potrzebujesz bardziej złożone argumenty, to może być dobry pomysł, aby umieścić niektóre lub wszystkie z nich wewnątrz odnośnika obiektu:

function bar(argmap) { 
    if ('optionalparam' in argmap) 
     this._constructInSomeWay(argmap.param, argmap.optionalparam); 
    ... 
} 

bar({param: 1, optionalparam: 2}) 

Python pokazuje, jak domyślne i nazwane argumenty mogą zostać wykorzystane na pokrycie większości przypadków użycia w bardziej praktycznym i wdzięku sposób niż funkcja przeciążenia. JavaScript, nie tak bardzo.

+1

Dzięki, to jest naprawdę miłe. Powiedziałbym, że druga opcja jest użyteczna nie tylko wtedy, gdy masz złożone argumenty, ale także proste, ale trudne do odróżnienia argumenty, np. obsługa 'MyObj ({foo:" foo "})' plus 'MyObj ({bar:" bar "})'. MyObj ma dwa konstruktory - ale oba przyjmują jeden argument, który jest ciągiem :-) –

+1

Czy możesz dodać więcej do kodu przykładowego dla tego konkretnego przykładu. –

+0

Witam @DougHauf, książka Crockforda "JavaScript: The Good Parts" zawiera sekcję o nazwanych "Specyfikatorach obiektów", wiele przykładów odnosi się do niej online. –

9

Idąc dalej z odpowiedzią eruciform, można łańcuch rozmowy new do swojego sposobu init ty.

function Foo() { 
    this.bar = 'baz'; 
} 

Foo.prototype.init_1 = function (bar) { 
    this.bar = bar; 
    return this; 
}; 

Foo.prototype.init_2 = function (baz) { 
    this.bar = 'something to do with '+baz; 
    return this; 
}; 

var a = new Foo().init_1('constructor 1'); 
var b = new Foo().init_2('constructor 2'); 
+0

Więc w zasadzie to, co tu robisz, zabiera obiekt Foo, a następnie wywołuje parametry init_1 i init_2 z funkcjami prototypu. Jeśli twój init_1 i init_2 mają funkcję słowa z nimi. –

+0

czy musi być średnik po znaku} w pierwszym Foo(). –

+0

Dzięki Doug, dokonałem zmiany. – laughingbovine

10

nie miał ochoty robić to ręcznie, jak w odpowiedzi bobince, więc ja po prostu całkowicie oszukany jQuery plugin opcji wzór.

Oto konstruktor:

//default constructor for Preset 'class' 
function Preset(params) { 
    var properties = $.extend({ 
     //these are the defaults 
     id: null, 
     name: null, 
     inItems: [], 
     outItems: [], 
    }, params); 

    console.log('Preset instantiated'); 
    this.id = properties.id; 
    this.name = properties.name; 
    this.inItems = properties.inItems; 
    this.outItems = properties.outItems; 
} 

Oto różne sposoby konkretyzacji:

presetNoParams = new Preset(); 
presetEmptyParams = new Preset({}); 
presetSomeParams = new Preset({id: 666, inItems:['item_1', 'item_2']}); 
presetAllParams = new Preset({id: 666, name: 'SOpreset', inItems: ['item_1', 'item_2'], outItems: ['item_3', 'item_4']}); 

A oto, co to wykonane:

presetNoParams 
Preset {id: null, name: null, inItems: Array[0], outItems: Array[0]} 

presetEmptyParams 
Preset {id: null, name: null, inItems: Array[0], outItems: Array[0]} 

presetSomeParams 
Preset {id: 666, name: null, inItems: Array[2], outItems: Array[0]} 

presetAllParams 
Preset {id: 666, name: "SOpreset", inItems: Array[2], outItems: Array[2]} 
+0

Zrobiłem ten sam wzorzec w pliku node.js również teraz z: https://www.npmjs.com/package/extend –

1

Więc tak jak sformułowane wcześniej, wiele rozwiązań, to, co widzisz ogólnie w takich datach, to statyczne metody:

Date.UTC("some params"); 

To nie jest właściwy konstruktor chociaż, to chociaż

function someObject(a,b,c,d,e,f) { 
a = a || "default"; 
b = b || "defaultb" 
} 

można iść maszynopis lub transpile go ES5?

constructor(a:string, b = "default value", c:number? //optional 
) { 

} 
2

Jest to przykład podany dla wielu konstruktorów w Programming in HTML5 with JavaScript and CSS3 - Exam Ref.

function Book() { 
    //just creates an empty book. 
} 


function Book(title, length, author) { 
    this.title = title; 
    this.Length = length; 
    this.author = author; 
} 

Book.prototype = { 
    ISBN: "", 
    Length: -1, 
    genre: "", 
    covering: "", 
    author: "", 
    currentPage: 0, 
    title: "", 

    flipTo: function FlipToAPage(pNum) { 
     this.currentPage = pNum; 
    }, 

    turnPageForward: function turnForward() { 
     this.flipTo(this.currentPage++); 
    }, 

    turnPageBackward: function turnBackward() { 
     this.flipTo(this.currentPage--); 
    } 
}; 

var books = new Array(new Book(), new Book("First Edition", 350, "Random")); 
+0

i niezmienność? używanie prototypu powoduje, że właściwości są publiczne, prawda? –

Powiązane problemy