Учитывая следующий фрагмент javascript в области видимости:
var x = 10;
function sayx() {
alert(x);
}
sayx();
Конечно, вы ожидаете, что в окне сообщения будет напечатано '10', вы можете сделать несколько вложенных функций, чтобы взаимодействовать с тем, как определяется 'x', потому что при определении того, что такое среда, идет цепочка областей действия.
Вы даже можете выполнить уровень 'перекомпиляции' с помощью eval, чтобы добавить новые области во время выполнения .. например:
var x = 10;
function sayx() {
alert(x);
}
function wrap(f) {
return eval('(function() { var x = 20;(' + f + ')(); })');
}
wrap(sayx)();
Это работает, потому что у функции будет вызываться функция toString, которая будет возвращать «исходный» источник .. таким образом, мы по существу создаем упакованную версию функции, которая имеет новую область видимости, которая переопределяет x .. результатом будет предупреждение поле с надписью «20», а не «10».
Однако на первый взгляд это может работать, но цепочка областей действия нарушена, следующий элемент в цепочке уже не тот, потому что функция 'f' теперь определена в другом месте ... еще хуже то, что унаследованная цепочка областей действия может содержать много ссылок, к которым у вызывающей функции не должно быть доступа.
Итак, есть ли более поддерживаемый и работоспособный способ внедрения элемента области? что-то вроде:
function withScope(f, scope) { ??? }
---
var x = 10, y = 10;
function dothemath() {
alert(x + y);
}
var haxthemath = withScope(dothemath, { x: 9000 });
haxthemath(); // 9010 not 20
Я предполагаю, что ответ «нет», некоторые могут утверждать, что есть проблемы «безопасности» с такой инъекцией области, но, учитывая, что вы все равно можете добиться цели (хотя и сильно сломанной), я не думаю, что это ..
Преимущества этого состоят в том, что вы можете фактически подделать свои собственные псевдопеременные.
Заранее спасибо.
Отредактируйте, просто поясните немного, представьте, что я хотел бы 'withScope' функцию, которая имела следующую цепочку областей действия:
Window - window properties
Object - { var x = 10 }
Object - { var y = 5 + x }
Я хотел бы получить возможность вернуть функцию, которая фактически имела бы ту же цепочку + область, которую я предоставляю ... т.е.:
withScope(somefunc, { foo: 'bar' })
дал бы мне
Window - window properties
Object - { var x = 10 }
Object - { var y = 5 + x }
Ext scope - { foo = 'bar' }
Все предыдущие постоянные переменные будут найдены, потому что моя расширенная область ничего о них не говорит.