Come si chiama una funzione pubblica da una funzione privata nel modello di modulo JavaScript?Come si chiama una funzione pubblica da una funzione privata nel modello di modulo JavaScript
Ad esempio, nel seguente codice,
var myModule = (function() {
var private1 = function(){
// How to call public1() here?
// this.public1() won't work
}
return {
public1: function(){ /* do something */}
}
})();
Questa domanda è stato chiesto twicebefore, con una diversa risposta accettata per ciascuno.
- Salvare un riferimento all'oggetto di reso prima di restituirlo, quindi utilizzare tale riferimento per accedere al metodo pubblico. Vedi answer.
- Salvare un riferimento al metodo pubblico nella chiusura e utilizzarlo per accedere al metodo pubblico. Vedi answer.
Mentre queste soluzioni funzionano, sono insoddisfacenti da un punto di vista OOP. Per illustrare cosa intendo, prendiamo un'implementazione concreta di un pupazzo di neve con ognuna di queste soluzioni e confrontale con un semplice oggetto letterale.
Snowman 1: Salva di riferimento per tornare all'oggetto
var snowman1 = (function(){
var _sayHello = function(){
console.log("Hello, my name is " + public.name());
};
var public = {
name: function(){ return "Olaf"},
greet: function(){
_sayHello();
}
};
return public;
})()
pupazzo di neve 2: Salva riferimento alla funzione pubblica
var snowman2 = (function(){
var _sayHello = function(){
console.log("Hello, my name is " + name());
};
var name = function(){ return "Olaf"};
var public = {
name: name,
greet: function(){
_sayHello();
}
};
return public;
})()
pupazzo di neve 3: letterale oggetto
var snowman3 = {
name: function(){ return "Olaf"},
greet: function(){
console.log("Hello, my name is " + this.name());
}
}
Possiamo vedere che i tre sono identici nella funzionalità e hanno gli stessi identici metodi pubblici.
Se lanciamo un test di semplice prioritario, tuttavia
var snowman = // snowman1, snowman2, or snowman3
snowman.name = function(){ return "Frosty";}
snowman.greet(); // Expecting "Hello, my name is Frosty"
// but snowman2 says "Hello, my name is Olaf"
vediamo che 2 # fallisce.
Se lanciamo una prova di prototipo di primaria importanza,
var snowman = {};
snowman.__proto__ = // snowman1, snowman2, or snowman3
snowman.name = function(){ return "Frosty";}
snowman.greet(); // Expecting "Hello, my name is Frosty"
// but #1 and #2 both reply "Hello, my name is Olaf"
vediamo che sia # 1 e # 2 non riescono.
Questa è una situazione davvero brutta. Solo perché ho scelto di ridefinire il mio codice in un modo o nell'altro, l'utente dell'oggetto restituito deve esaminare attentamente come ho implementato tutto per capire se è in grado di sovrascrivere i metodi del mio oggetto e si aspetta che funzioni ! Mentre le opinioni qui sono diverse, la mia opinione è che il comportamento di override corretto sia quello del semplice oggetto letterale. ci
è un modo per chiamare un metodo pubblico da uno privato in modo che gli atti oggetto risultante come un oggetto letterali rispetto a sovrascrivere il comportamento:
Quindi, questa è la vera questione?
Una nota importante nelle insidie che si discutono: la mia comprensione del modello di modulo è che è davvero un'alternativa all'approccio del polimorfismo prototipo/OOP di JS. In quanto tale, penso che abbia senso evitare di usare i due insieme - non lo vedo come una trappola * di per sé *. – EyasSH
@ EyasSH: può essere usato in questo modo, tuttavia penso che sia più un artefatto che può essere usato per una specie di eredità piuttosto che una caratteristica intenzionale. Sembra essere usato principalmente per emulare membri privati (o non esponendo cose che altri non dovrebbero giocare) e anche per migliorare le prestazioni. – RobG
@RobG, giusto, ma è possibile dichiarare le funzioni private in una chiusura mentre si attacca al modello di prototipo. In tal caso, l'uso di '' this this''' va bene. Il mio punto è, se si sta utilizzando il modello del modulo, penso che guardare il modulo <-> l'interazione del prototipo non è una vera ragione per non utilizzare un approccio. Potrebbe essere un buon motivo per limitarsi al prototipo se pensi che chiunque usi il tuo codice lo farà ... – EyasSH