Я боролся с этим в течение последних нескольких дней и был счастлив столкнуться с этим вопросом. Однако после некоторых экспериментов ни один из ответов не кажется удовлетворительным хотя бы для одного случая: передача данных между публичной и приватной функциями.
Ниже приведены три примера использования call, 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();
Использование «вызова»:
"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();
Без вызова или привязки:
"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();
Обновление и возможный ответ. Мне было любопытно посмотреть, есть ли у Алисы доступ к закрытым переменным в «доме», когда Алиса вызывается без «вызова» или «привязки», и ее контекст не определен (или окно). Да, поэтому мой предварительный ответ на ОП (и на себя) состоит в том, чтобы просто вызвать приватную функцию в обычном режиме: без «привязки», без «вызова» и без необходимости передавать в контексте, но «использовать строгий», если это вас беспокоит чтобы увидеть контекст окна, всплывающий при запуске частной функции. Похоже, что в «окне» не создается новое свойство, и нет конфликтов, если в окне есть объект с тем же именем, что и приватная функция (независимо от того, включен или выключен строгий режим). Если и есть подводные камни, то я их еще не встречал.
"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);
person
Walt
schedule
04.02.2017