Вопрос про scope
function fn(data){
return {
get: function(){
return data;
}
}
}
var test1 = fn(1);
var test2 = fn(2);
alert(test1.get());
alert(test2.get());
alert(test1.get());
Собственно, почему третий alert выводит 1?! Функция одна, а локальная область всегда новая при каждом вызове?! |
Функция не одна, ты каждый раз при вызове fn создаешь:
function(){
return data;
}
которая и замыкает разный data. |
А разве новая функция не берёт значение из scope fn?
|
Вот ещё пример:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<title></title>
</head>
<body>
<script type="text/javascript">
function fn(){
eval('var ' + this.name + ' = ' + this.value);
alert(this.name);
}
fn.call({
name: 'test1',
value: '1'
});
fn.call({
name: 'test2',
value: '2'
});
</script>
</body>
</html>
Поставьте брейкпоинт на alert. При втором вызове почему-то нет переменной test1. При вызове функции, её старый scope затирается? |
А понял о чем вопрос. Ну да каждый раз при вызове функции создается новый контекст исполнения (если не ошибаюсь в терминологии).
|
B~Vladi,
у вас сложилось превратное понимание замыканий при повторном вызове ф-ции, она не имеет понятия о пеерменных внутри нее созданных при более ранних ее вызовах. поэтому в вашем втором примере ф-ция не помнит переменную test1 Кстати, при кадом новом вызове ф-ции, создается новый [scope], а при завршении ее, убивается, если на него нету ссылок(например их созданных внутри ф-ций) поэтому в вашем первом примере, каждый вызов fn() создает новый [scope], который запоминается свежесозаднной ф-цией внутри fn() поэтому каждая из этих ф-ций помнит свой scope, и ничего не знает о чужом [scope] ф-ции -- это не что-то привязанное к самой ф-ции, а привязанное к ней, и ее одному запуску. новый запуск-новый [scope] |
Гадство. А как бы мне сделать так, чтобы я мог в уже существующий scope добавлять свои переменные?
Например есть функция:
function fn(){
var test = 1;
}
Я в неё хочу добавить ещё одну переменную - test2 после первого выполнения fn. Другими словами - мне нужен динамический scope... Есть другой вариант - with. Вот например мы можем обращаться к document без указания window. Какие есть отличия между такими scope? Вроде получается тоже самое:
var obj = {
a: 1
};
with(obj){
alert(a); // 1
a = 3
}
alert(obj.a); // 3
|
Цитата:
можно только менять уже определенные ранее в нем переменные. Цитата:
var obj = {
a: 1
};
with(obj){
alert(a); // 1
a = 3;
b=4;
}
alert(obj.a); // 3
alert(obj.b); // undefined вместо 4
alert(b); // 4 вместо undefined
Цитата:
|
Цитата:
|
Цитата:
чем оно вам не нравится? |
Цитата:
Цитата:
|
Цитата:
var global=1;
(function(){
var local=2;
window.fn=function(){
alert(global);
alert(local);
}
})()
fn();
Цитата:
постараюсь запомнить что с тобой на ты, но могу забыть |
Ну я всё равно не смогу добавить переменную local2 в scope анонимной функции, после её выполнения...
|
Цитата:
|
Цитата:
Ну вот представь глобальную область видимости. Хочу такую же, только свою. Но чтобы в глобальной не было моих переменных. А тобой можно на ты? Цитата:
|
B~Vladi, а Ваш вириант кошерен? Давайте тогда уточнять, что же вы подразумеваете под "своей областью видимости". Приводите пример из имеющихся языков программирования :)
|
Цитата:
Цитата:
|
Ты ты ты ты ты:)
А не вы:) Я то определился. Есть некая область видимости, из которой доступна глобальная (ну само собой). Есть 2 фронта. Первый фронт - мой. Из этого фронта я должен определять свои переменные, доступные только из этой "некой" области видимости, но не из глобальной. Необходимо, чтобы я в любой момент мог определить любую переменную с нужным мне именем. Второй фронт - вражеский. Из него можно получить доступ к переменным, определённым в первом фронте, просто обращаясь по имени (как к document, без указания window в глобальной области). Из этого же фронта нельзя определить свои переменные, разве что если они попадут в глобальную область - ничего страшного. Задачка не тривиальная, поэтому собсно и был создан этот сабж. У меня конечно же есть свои наработки, но пока не 100% того что я хочу. Сори, если кого ввел в заблуждение. Мне проще на словах рассказать. |
B~Vladi,
шаблонный движок чтоле? |
Цитата:
|
Всем спасибо, тему можно закрывать. Демо-код получился такой:
(function(){
if(this == window){
document.userScope = arguments.callee;
} else {
with(this.stack){ // Область видимости для вражеского фронта
eval('(function(){' + this.code + '}).call(this.module);');
}
this.stack[this.name] = this.module;
}
})();
(function(){ // Мой фронт
var userScope = document.userScope;
delete document.userScope;
var stack = {};
var module1 = {};
var module2 = {};
userScope.call({ // Добавляем первую переменную
name: 'module1',
code: 'this.fn = function(){console.log(module2)};', // Вражеский фронт
module: module1,
stack: stack
});
userScope.call({
name: 'module2',
code: 'console.log(this)',
module: module2,
stack: stack
});
module1.fn(); // После добавления новых переменных, старые их тоже видят.
})();
Ничего лишнего не попало во вражескую область видимости. |
| Часовой пояс GMT +3, время: 00:29. |