2011-02-02 8 views
62

Mam wiele "klas" JavaScriptu zaimplementowanych we własnym pliku JavaScript. Dla rozwoju te pliki są ładowane pojedynczo, a do produkcji są łączone, ale w obu przypadkach muszę ręcznie zdefiniować kolejność ładowania, upewniając się, że B pojawia się po A, jeśli B używa A. Zamierzam użyć RequireJS jako implementacji CommonJS Modules/AsynchronousDefinition, aby automatycznie rozwiązać ten problem.RequireJS: Jak zdefiniować moduły zawierające pojedynczą "klasę"?

Czy jest lepszy sposób na to, niż zdefiniowanie modułów, które eksportują jedną klasę? Jeśli nie, jak nazwać, co moduł eksportuje? Moduł "pracownik" eksportujący klasę "Pracownik", jak w poniższym przykładzie, nie wydaje mi się wystarczający dla DRY.

define("employee", ["exports"], function(exports) { 
    exports.Employee = function(first, last) { 
     this.first = first; 
     this.last = last; 
    }; 
}); 

define("main", ["employee"], function (employee) { 
    var john = new employee.Employee("John", "Smith"); 
}); 

Odpowiedz

108

Opcja AMD proposal pozwala po prostu zwrócić wartość wyeksportowanego obiektu. Należy jednak zauważyć, że jest to cecha propozycji AMD, jest to tylko propozycja interfejsu API i utrudni przetłumaczenie modułu z powrotem na zwykły moduł CommonJS. Myślę, że to jest w porządku, ale przydatne informacje.

Więc można wykonać następujące czynności:

Wolę modułów, które eksportują funkcję konstruktora, aby rozpocząć z nazwy wielkich liter, więc nie zoptymalizowana wersja tego modułu będzie również w Employee.js

define("Employee", function() { 
    //You can name this function here, 
    //which can help in debuggers but 
    //has no impact on the module name. 
    return function Employee(first, last) { 
     this.first = first; 
     this.last = last; 
    }; 
}); 

teraz w innym module, można użyć modułu Employee tak:

define("main", ["Employee"], function (Employee) { 
    var john = new Employee("John", "Smith"); 
}); 
+0

Wow, odpowiedź prosto od @jrburke, mr. Wymagaj sam JS! +1! – Bart

98

Jako dodatek do odpowiedzi jrburke jest zauważyć, że nie ma powrotu c funkcja onstructor bezpośrednio. Do najbardziej przydatnych klas będziesz również dodać metody poprzez prototyp, który można zrobić tak:

define('Employee', function() { 
    // Start with the constructor 
    function Employee(firstName, lastName) { 
     this.firstName = firstName; 
     this.lastName = lastName; 
    } 

    // Now add methods 
    Employee.prototype.fullName = function() { 
     return this.firstName + ' ' + this.lastName; 
    }; 

    // etc. 

    // And now return the constructor function 
    return Employee; 
}); 

W rzeczywistości jest dokładnie taki wzór przedstawiono w this example at requirejs.org.

+1

Witaj Mark, twój wpis jest dokładnie tym, czego szukam. Z wyjątkiem jednej rzeczy. Czy jest możliwe zdefiniowanie niektórych pól dla obiektu Employee, które nie są częścią konstruktora? Na przykład mieć pozycję i metodę positionToUpper, ale w jakiś sposób zdefiniować tę właściwość nie w konstruktorze employee = new Employee ("john", "smith"); employee.position = 'manager'; alert (employee.positionToUpper()); –

+4

Alex, ten przykład był dla mnie pomocny, jest bardzo dobrze udokumentowany i prawdopodobnie dostarcza przykładów, których szukasz: https://gist.github.com/jonnyreeves/2474026 –

+0

@NathanPrather to świetny odnośnik - komentarze pomogły przetłumaczyć ja z tła Java – y3sh

Powiązane problemy