Ich habe in den letzten paar Tagen damit zu kämpfen, und war glücklich, auf diese Frage zu kommen. Nach einigen Experimenten scheint jedoch keine der Antworten für mindestens einen Fall zufriedenstellend zu sein: die Weitergabe von Daten zwischen der öffentlichen und der privaten Funktion.
Im Folgenden finden Sie drei Beispiele, die 'call', 'bind' und einen einfachen Aufruf verwenden. Die Bindung scheint die einzige Möglichkeit zu sein, die private Methode im lokalen Bereich zu halten und auch den Datenaustausch zwischen privaten und öffentlichen Methoden zu ermöglichen. Der andere Vorschlag, den Kontext an die private Methode zu übergeben, würde die private Methode immer noch außerhalb des Moduls ausführen lassen (wenn ich es richtig verstanden habe).
Interessanterweise erlaubt die Verwendung eines einfachen Aufrufs (mit/ohne striktem Modus) den Datenaustausch, selbst wenn der Kontext der privaten Methode 'undefiniert'/'Fenster' ist.
Mit 'bind':
"use strict";
var home = (function(){
var bob = function(){
console.log("Bob's scope: " + Object.keys(this)); // "Bob's scope: init"
var bob_says = "Hello";
var fBound = alice.bind(this);
var alice_reply = fBound(bob_says);
console.log("Alice answered: " + alice_reply); // "Alice answered: Hello Bob"
};
var alice = function(bob_greeting){
var scope = this ? Object.keys(this) : this;
console.log("Alice's scope: " + scope); // "Alice's scope: init"
console.log("Bob said: " + bob_greeting); // "Bob said: Hello"
return bob_greeting + " Bob";
};
return { init : bob };
})();
home.init();
Mit 'Anruf':
"use strict";
var home = (function(){
var bob = function(){
console.log("Bob's scope: " + Object.keys(this)); // "Bob's scope: init"
var bob_says = "Hello";
var alice_reply = alice.call(this, bob_says);
console.log("Alice answered: " + alice_reply); // "Alice answered: undefined Bob"
};
var alice = function(self, bob_greeting){
var scope = this ? Object.keys(this) : this;
console.log("Alice's scope: " + scope); // "Alice's scope: init"
console.log("Bob said: " + bob_greeting); // "Bob said: undefined"
return bob_greeting + " Bob";
};
return { init : bob };
})();
home.init();
Ohne Anruf oder binden:
"use strict";
var home = (function(){
var bob = function(){
console.log("Bob's scope: " + Object.keys(this)); // "Bob's scope: init"
var bob_says = "Hello";
var alice_reply = alice(bob_says);
console.log("Alice answered: " + alice_reply); // "Alice answered: Hello Bob"
};
var alice = function(bob_greeting){
var scope = this ? Object.keys(this) : this;
console.log("Alice's scope: " + scope); // "Alice's scope: undefined"
console.log("Bob said: " + bob_greeting); // "Bob said: Hello"
return bob_greeting + " Bob";
};
return { init : bob };
})();
home.init();
Update und mögliche Antwort. Ich war neugierig, ob, wenn Alice ohne 'Call' oder 'Bind' aufgerufen wird und ihr Kontext nicht definiert ist (oder Fenster), hat sie Zugriff auf private Variablen in 'Home'? Ja, also ist meine vorläufige Antwort auf das OP (und ich), die private Funktion einfach normal zu nennen: kein 'bind', kein 'call' und keine Notwendigkeit, den Kontext zu überschreiten, sondern 'strict', wenn es Sie stört um zu sehen, dass der Fensterkontext beim Ausführen der privaten Funktion auftaucht. Es scheint, dass keine neue Eigenschaft im "Fenster" erstellt wird, und es gibt keine Konflikte, wenn das Fenster ein Objekt mit demselben Namen wie die private Funktion hat (ob der strikte Modus aktiviert oder deaktiviert ist). Wenn es Gotchas gibt, bin ich ihnen noch nicht begegnet.
"use strict";
var alice = "Hi, I'm global's Alice";
var home = (function(){
var bob = function(){
console.log("Bob's scope: " + Object.keys(this)); // "Bob's scope: init"
var bob_says = "Hello";
var alice_reply = alice(bob_says);
console.log("Alice answered: " + alice_reply); // "Alice answered: Hello Bob. I'm in the garage."
};
var alice_location = "in the garage.";
var alice = function(bob_greeting){
var scope = this ? Object.keys(this) : this;
console.log("Alice's scope: " + scope); // "Alice's scope: undefined"
console.log("Bob said: " + bob_greeting); // "Bob said: Hello"
return bob_greeting + " Bob. I'm " + alice_location;
};
return { init : bob };
})();
home.init();
console.log(alice);
Explizit erscheint am besten. Allerdings habe ich einen kleinen Vorteil bei der Verwendung von Anrufen festgestellt - wenn Sie einen Debugger verwenden, können Sie Getter direkt über das Objekt "this" direkt erreichen – Skyler