Javascript.RU

Создать новую тему Ответ
 
Опции темы Искать в теме
  #11 (permalink)  
Старый 06.03.2009, 11:07
...
Отправить личное сообщение для Zeroglif Посмотреть профиль Найти все сообщения от Zeroglif
 
Регистрация: 09.03.2008
Сообщений: 216

Dmitry A. Soshnikov,

Спасибо за подробные размышления, чем больше думаю, тем больше слоняюсь к мысли, что условия не нужны, в смысле "все функции замыкания и точка".
Ответить с цитированием
  #12 (permalink)  
Старый 06.03.2009, 22:04
Профессор
Отправить личное сообщение для Dmitry A. Soshnikov Посмотреть профиль Найти все сообщения от Dmitry A. Soshnikov
 
Регистрация: 25.02.2008
Сообщений: 707

Сообщение от Zeroglif
тем больше слоняюсь к мысли, что условия не нужны
Возможно. Возможно, в JS оно и так. Хотя, для полного определения, всё же, наверное, лучше две теории упоминать.

Но, сегодня более глубоко посмотрел, как это дело обстоит в Python'е (да-да, опять Питон ). Так вот. Там так же работает механизм цепи скопов (т.е. из вложенных функций мы можем достучаться до всех вышестоящих переменных/объектов, включая глобальный скоп). Однако, начиная с версии Python'a 3.0, у функций есть интересное свойство - __closure__, которое:

Цитата:
None or a tuple of cells that contain bindings for the function’s free variables.
Можно почитать здесь - http://docs.python.org/3.0/reference/datamodel.html, конкретно раздел "Callable types".

Это свойство, как было сказано, хранит кортеж (tuple, неизменяемый массив) свободных переменных функции. Т.е. это тот самый [[scope]] из JS, который записался в функцию при её создании, только здесь мы имеем к нему доступ явно. Но! Самое интересное здесь то, что глобальные переменные туда не входят! Здесь, если функция глобальная - у неё, считается, нет свободных лексических локальных переменных (и в этом случае, __closure__ == None):

a = 10

# глобальная функция
def x():
    print(a)

x() # 10, работает, но:

x.__closure__ # None


А теперь с вложенными функциями:

a = 10

def x():
    b = 20

    def y(): # первая вложенная
        c = 30

        def z(): # вторая вложенная
            print(a, b, c)

        return z # возврат из y

    return y # возврат из x

# проверка

dy = x() # вернувшаяся функция "y"

dz = dy() # вернувшаяся функция "z", можно было сразу - x()()

dz() # 10, 20, 30

# замыкание внешней функции "x"
x.__closure__ # None

# замыкание внутренней функции "y" (dy)
dy.__closure__ # (<cell at 0x0143AE70: int object at 0x1E1E5678>,) - кортеж из одного элемента

dy.__closure__[0] # <cell at 0x0143AE70: int object at 0x1E1E5678> - этот самый элемент, объект cell

dy.__closure__[0].cell_contents # а вот она наша 20!

dy.__closure__[1] # ошибка! нет элемента с индексом 1, только одна свободная переменная, глобальная "а" сюда не входит

# замыкание внутренней функции "z" (dz)

dz.__closure__ # два объекта, как и ожидалось - (<cell at 0x0143E970: int object at 0x1E1E5718>, <cell at 0x0143AE70: int object at 0x1E1E5678>)

dz.__closure__[0].cell_contents # 30
dz.__closure__[1].cell_contents # 20
dz.__closure__[2].cell_contents # ошибка, только две свободные переменные


Т.е. здесь, обособление лексических переменных от глобальных представлено явно. И именно лексические переменные попали в замыкание.

P.S.:> Zeroglif, скачай, поставь интерпретатор Python'a, тоже, как и JS, интересно.

P.S.[2]:> сейчас ещё и Ruby посмотрел - там тоже есть явное разделение на глобальные переменные (префикс - $: $a, $b и т.д.), и локальные - без префиксов. Так вот глобальные переменные могут использоваться в методах (def'ы), в то время как локальные для глобального контекста - нет:

a = 10
def x
  puts a
end
x # ошибка, переменная "а" не определена

$b = 10
def y
  puts $b
end
y # 10, все Ок


В свою очередь замыкания в Ruby, которые создаются через block'и, lambda'ы и Proc'ы, запоминают эти лексические переменные:

a = 10
x = lambda {
  puts a
}

x.call # 10


В общем, сколько идей, столько и реализаций
__________________
Тонкости ECMAScript
Ответить с цитированием
Ответ



Опции темы Искать в теме
Искать в теме:

Расширенный поиск


Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Сторонние библиотеки - быть или не быть? IIIEPJIOK Оффтопик 64 21.03.2009 19:39
аякс!что это такое Рудольф AJAX и COMET 4 11.02.2009 21:11
Что означает конструкция ? ivanmara Общие вопросы Javascript 55 07.01.2009 02:54
Как понимать это выражение? Хранитель Света Общие вопросы Javascript 2 22.07.2008 17:03
ассоциативный массив где ключ это год или ..... Sandr Общие вопросы Javascript 8 18.07.2008 15:39