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);
Вуаля: овцы целы (стандартная логика не нарушена) и волки сыты (ссылка в руках).
