Javascript-форум (https://javascript.ru/forum/)
-   Общие вопросы Javascript (https://javascript.ru/forum/misc/)
-   -   Вызов вложенной функции объявленной без ключевого слова var (https://javascript.ru/forum/misc/75511-vyzov-vlozhennojj-funkcii-obyavlennojj-bez-klyuchevogo-slova-var.html)

ytil 15.10.2018 18:34

Вызов вложенной функции объявленной без ключевого слова var
 
Всем привет. Уважаемые знатоки, подскажите пожалуйста, почему в учебном примере ниже при объявлении вложенной функции buffer.clear не используется ключевое слово var. И почему если его все таки испорльзовать то функция перестает быть доступной из глобальной области видимости.

З.Ы. Также не понимаю, почему функция buffer.clear вообще является доступной из global, ведь она является переменной функции makeBuffer и должна иметь возможность вызываться только в пределах этой функции?

function makeBuffer() {
  var text = '';

  function buffer(piece) {
    if (arguments.length == 0) { // вызов без аргументов
      return text;
    }
    text += piece;
  };

  buffer.clear = function() {
    text = "";
  }

  return buffer;
};

var buffer = makeBuffer();

buffer("Тест");
buffer(" тебя не съест ");
alert( buffer() ); // Тест тебя не съест

buffer.clear();

alert( buffer() ); // ""

Dilettante_Pro 15.10.2018 19:59

ytil,
.clear() - это метод функции, создаваемой функцией makeBuffer(), которая возвращает создаваемую функцию туда, откуда вызывается.
var buffer создана в глобальной области, доступна и она, и ее метод. Возможно, вас путают одинаковые имена buffer в глобальной и локальной областях - можете изменить одно из них.

ytil 15.10.2018 20:27

в данном примере я могу изменить имя buffer.clear = func... например на method = func...

А после вызвать method() из глобальной области видимости и произойдет тоже самое. Вы бы не могли объяснить механику, почему так происходит? Ведь в названии метода нет никакой привязки к функции в которой он создан.

Выходит, что все методы которые мы создаем в функциях доступны в глобальной области видимости под любым именем. Т.е. мы можем таким образом вызвать любой метод в любом месте когда, а сам метод уже будет оперировать той областью видимости которая была у функции в которой он был создан?

Aetae 15.10.2018 21:01

"buffer" которой прописывается buffer.clear и "buffer" которой присваивается результат makeBuffer - это две разные переменные, волей кода ссылающиеся на одну конкретную функцию и названные одинаково.
Первая "buffer" как и положено доступна лишь внутри функции makeBuffer, вторая же "buffer" явно задаётся в глобальной области видимости.
Назовите их по-разному и разбирайтесь дальше.)

Что касается области видимости - в js функция захватывает ту область видимости в которой создана, что называется замыканием. Назначена ли она как метод или нет, значения то не имеет.

ytil 15.10.2018 21:48

Цитата:

Сообщение от Aetae (Сообщение 496424)
"buffer" которой прописывается buffer.clear и "buffer" которой присваивается результат makeBuffer - это две разные переменные.

Не могли бы пояснить чуть подробнее, почему переменных две.
Наверное, я просто не понимаю что такое "метод". Ведь синтаксис присвоения метода выглядит так, будто мы назначаем функцию на предварительно объявленную переменную.

Я и называл метод (правильно называть метод?) buffer.clear по другому, но как бы я не называл его, он доступен всегда и под любым именем из глобальной области, это мне и не понятно, почему он доступен и откуда интерпретатор знает откуда его вызывать и с какой областью видимости разрешать ему работать.

Возможно эти детали будут рассматриваться в учебнике дальше) но пока я не могу уснуть не познав истину.

Спасибо за отзывы.

Dilettante_Pro 15.10.2018 22:39

Если вы измените buffer.clear на method, то тем самым вы обьявите глобальную функцию. Переменная, обьявленная в локальной области без var, является глобальной.

ytil 15.10.2018 22:53

Цитата:

Сообщение от Dilettante_Pro (Сообщение 496430)
Если вы измените buffer.clear на method, то тем самым вы обьявите глобальную функцию. Переменная, обьявленная в локальной области без var, является глобальной.

да, вы правы, дело в том, что в онлайн редакторе jsfiddle не был включен строгий режим, в котором таким фокусы не работают


Часовой пояс GMT +3, время: 03:22.