Der Sandbox-Modus ist im YUI3-Kern üblich. Dabei handelt es sich um eine Methode, die denselben Konstruktor (Konstruktor) verwendet, um unabhängige und nicht störende (in sich geschlossene) Instanzobjekte zu generieren, um eine Verschmutzung des globalen Objekts zu vermeiden.
Namespace
JavaScript selbst bietet keinen Namespace-Mechanismus. Um eine Kontamination des globalen Raums durch verschiedene Funktionen, Objekte und Variablennamen zu vermeiden, besteht der übliche Ansatz darin, einen Namespace für zu erstellen Ihre Anwendung oder Bibliothek. Erstellen Sie ein eindeutiges globales Objekt und fügen Sie diesem Objekt alle Methoden und Eigenschaften hinzu.
Codeauflistung 1: Traditioneller Namespace-Modus
/* BEFORE: 5 globals */ // constructors function Parent() {} function Child() {} // a variable var some_var = 1; // some objects var module1 = {}; module1.data = {a: 1, b: 2}; var module2 = {}; /* AFTER: 1 global */ // global object var MYAPP = {}; // constructors MYAPP.Parent = function() {}; MYAPP.Child = function() {}; // a variable MYAPP.some_var = 1; // an object MYAPP.modules = {}; // nested objects MYAPP.modules.module1 = {}; MYAPP.modules.module1.data = {a: 1, b: 2}; MYAPP.modules.module2 = {};
In diesem Code erstellen Sie ein globales Objekt MYAPP und hängen alle anderen Objekte und Funktionen als Attribute an MYAPP an.
Normalerweise ist dies eine bessere Möglichkeit, Namenskonflikte zu vermeiden und wird in vielen Projekten verwendet, aber diese Methode hat einige Nachteile.
Sie müssen allen Funktionen und Variablen, die hinzugefügt werden müssen, Präfixe hinzufügen.
Da es nur ein globales Objekt gibt, bedeutet dies, dass ein Teil des Codes das globale Objekt willkürlich ändern und dazu führen kann, dass der Rest des Codes passiv aktualisiert wird.
Globaler Konstruktor
Sie können einen globalen Konstruktor anstelle eines globalen Objekts verwenden. Wir haben diesen Konstruktor zum Erstellen von Objekten verwendet als Parameter für den Konstruktor. Diese Rückruffunktion ist eine unabhängige Sandbox-Umgebung, in der Sie Ihren Code speichern.
Codeauflistung 2: Verwendung der Sandbox
new Sandbox(function(box){ // your code here... });
Fügen wir der Sandbox einige weitere Funktionen hinzu.
Sie können eine Sandbox erstellen, ohne den Operator „new“ zu verwenden.
Der Sandbox()-Konstruktor akzeptiert einige zusätzliche Konfigurationsparameter, die die Namen der Module definieren, die zum Generieren des Objekts erforderlich sind. Wir möchten, dass der Code modularer ist.
Nachdem wir über die oben genannten Funktionen verfügen, sehen wir uns an, wie ein Objekt initialisiert wird.
Listing 3 zeigt, dass Sie ein Objekt mit den Modulen „ajax“ und „event“ erstellen können, ohne dass der Operator „new“ erforderlich ist.
Codeauflistung 3: Übergeben Sie den Modulnamen in Form eines Arrays
Sandbox(['ajax', 'event'], function(box){ // console.log(box); });
Codeauflistung 4: Übergeben Sie den Modulnamen in Form unabhängiger Parameter
Sandbox('ajax', 'dom', function(box){ // console.log(box); });
Codeauflistung 5 Es wird gezeigt, dass Sie das Platzhalterzeichen „*“ als Argument an den Konstruktor übergeben können, was bedeutet, dass alle verfügbaren Module aufgerufen werden. Der Einfachheit halber gilt: Wenn kein Modulname als Argument an den Konstruktor übergeben wird, Der Konstruktor behandelt „*“ als fehlendes Modul. Speichern Sie die zu übergebenden Parameter.
Codeauflistung 5: Aufrufen der verfügbaren Module
Sandbox('*', function(box){ // console.log(box); }); Sandbox(function(box){ // console.log(box); });
Codeauflistung 6 zeigt, dass Sie das Sandbox-Objekt mehrmals initialisieren und sie sogar verschachteln können, ohne sich umeinander kümmern zu müssen Konflikt.
Codeauflistung 6: Verschachtelte Sandbox-Instanzen
Sandbox('dom', 'event', function(box){ // work with dom and event Sandbox('ajax', function(box) { // another sandboxed "box" object // this "box" is not the same as // the "box" outside this function //... // done with Ajax }); // no trace of Ajax module here });
Wie aus den obigen Beispielen ersichtlich ist, generieren Sie im Sandbox-Modus durch Einschließen der gesamten Codelogik in eine Rückruffunktion verschiedene Instanzen basierend auf den Modulen, die Sie benötigen, und diese Instanzen arbeiten unabhängig voneinander, ohne sich gegenseitig zu stören, wodurch der globale Namensraum geschützt wird.
Jetzt sehen wir uns an, wie der Sandbox()-Konstruktor implementiert wird.
Modul hinzufügen
Bevor wir den Hauptkonstruktor implementieren, sehen wir uns an, wie man dem Sandbox()-Konstruktor ein Modul hinzufügt.
Da die Konstruktorfunktion Sandbox() auch ein Objekt ist, können Sie ihr ein Attribut namens „modules“ hinzufügen. Dieses Attribut ist ein Objekt, das einen Satz von Schlüssel-Wert-Paaren enthält, wobei jedes Paar einen Schlüssel enthält -value Der Schlüssel ist der Name des Moduls, das registriert werden muss, und der Wert ist die Eintragsfunktion des Moduls. Bei der Initialisierung des Konstruktors wird die aktuelle Instanz als erster Parameter an die Eintragsfunktion übergeben, sodass der Eintrag erfolgt Die Funktion kann der Instanz zusätzliche Attribute und Methoden hinzufügen.
In Codelisting 7 haben wir die Module „dom“, „event“ und „ajax“ hinzugefügt.
Codeauflistung 7: Registrierungsmodul
Sandbox.modules = {}; Sandbox.modules.dom = function(box) { box.getElement = function() {}; box.getStyle = function() {}; box.foo = "bar"; }; Sandbox.modules.event = function(box) { // access to the Sandbox prototype if needed: // box.constructor.prototype.m = "mmm"; box.attachEvent = function(){}; box.dettachEvent = function(){}; }; Sandbox.modules.ajax = function(box) { box.makeRequest = function() {}; box.getResponse = function() {}; };
Implementierung des Konstruktors
Codeauflistung 8 beschreibt die Methode zur Implementierung des Konstruktors mit mehreren wichtigen Punkten:
Wir prüfen, ob es sich um eine Instanz von Sandbox handelt. Wenn nicht, beweist dies, dass Sandbox nicht vom neuen Operator aufgerufen wurde, und wir werden sie erneut als Konstruktor aufrufen.
Sie können diesem innerhalb des Konstruktors Attribute hinzufügen, und Sie können auch Attribute zum Prototyp des Konstruktors hinzufügen.
Der Modulname wird in verschiedenen Formen an den Konstruktor übergeben, z. B. als Arrays, unabhängige Parameter, Platzhalterzeichen „*“ usw.
Bitte beachten Sie, dass wir in diesem Beispiel das Modul nicht aus einer externen Datei laden müssen, sondern in Systemen wie YUI3 können Sie nur das Basismodul (oft als Seed bezeichnet) und alle anderen Module laden wird aus einer externen Datei geladen.
一旦我们知道了所需的模块,并初始化他们,这意味着调用了每个模块的入口函数。
回调函数作为参数被最后传入构造器,它将使用最新生成的实例并在最后执行。
代码清单8:实现Sandbox构造器
<script> function Sandbox() { // turning arguments into an array var args = Array.prototype.slice.call(arguments), // the last argument is the callback callback = args.pop(), // modules can be passed as an array or as individual parameters modules = (args[0] && typeof args[0] === "string") ? args : args[0], i; // make sure the function is called // as a constructor if (!(this instanceof Sandbox)) { return new Sandbox(modules, callback); } // add properties to 'this' as needed: this.a = 1; this.b = 2; // now add modules to the core 'this' object // no modules or "*" both mean "use all modules" if (!modules || modules === '*') { modules = []; for (i in Sandbox.modules) { if (Sandbox.modules.hasOwnProperty(i)) { modules.push(i); } } } // init the required modules for (i = 0; i < modules.length; i++) { Sandbox.modules[modules[i]](this); } // call the callback callback(this); } // any prototype properties as needed Sandbox.prototype = { name: "My Application", version: "1.0", getName: function() { return this.name; } }; </script>