var singleton = (function () {
var data, method_args;
data = [];
method_args = [];
function add (items) {
var i;
data.push(items);
method_args.push(arguments);
}
function remove () {
data.pop();
method_args.push(arguments);
}
return {
add : add,
remove : remove
}
}());
Есть доступ к объекту singleton.
Публичные методы синглтона (он приведен как пример, и ценность составляет создаваемое при его инициализации замыкание) вызывают методы массива, который хотелось бы достать. В этих методах this ссылается на вожделенный массив. Значит до него можно добраться через this.
Если бы не было method_args.push, то можно было бы обойтись переопределением Array.prototype.push (с обязательным возвратом все на свои места после «кражи» объекта).
var original_push,
data;
// запоминаем как было
original_push = Array.prototype.push;
// подставляем фальшивый метод
Array.prototype.push = function () {
// извлекаем ссылку
data = this;
};
// запускаем фальшивый метод
singleton.add();
// возвращаем все на свои места
Array.prototype.push = original_push;
// массив в наших руках
console.log(data);
Однако push используется не единожды. Разовое невыполнение метода может повлечь за собой поломку. А этого не хочется. Хочется ссылку на массив. Значит переписать код выше, сохраняя стандартную логику работы. Создаем новый метод push, который умен достаточно, чтобы взять ссылку this только при первом вызове, и может имитировать поведение по умолчанию.
var original_push,
fake_method_calls,
data;
// запоминаем как было
original_push = Array.prototype.push;
// считаем
fake_method_calls = 0;
// подставляем фальшивый метод
Array.prototype.push = function () {
// запоминаем this только для первого вызова
if (fake_method_calls === 0) {
data = this;
}
fake_method_calls += 1;
// стандартная логика
return original_push.apply(this, arguments);
}
// запускаем фальшивый метод
singleton.add();
// возвращаем все на свои места
Array.prototype.push = original_push;
// массив в наших руках
console.log(data);
Вуаля: овцы целы (стандартная логика не нарушена) и волки сыты (ссылка в руках).