Ответы пользователя по тегу JavaScript
  • Для чего нужны замыкания (js)?

    @alexfarm2
    Замыкания в JavaScript.
    Допустим, мы вызываем внутри нашего кода какую-то функцию (назовем ее первичной функцией), т.е. какой-то код (назовем его вспомогательным), находящийся в теле этой функции. И этот вспомогательный код объявляет другую функцию (назовем ее вторичной функцией) и возвращает эту вторичную функцию в качестве возвращаемого значения.
    Здесь ключевой момент– не в коде создается, а код создает. Т.е. если бы мы не вызвали код первичной функции, то вторичная функция бы не была создана. Ее и в памяти-то нигде не было бы. К ней нельзя было бы обратиться. Интерпретатор не размещает ее в памяти, пока не будет вызвана первичная функция.
    В этом вспомогательном коде могут быть объявлены и инициализированы переменные, а внутри тела этой вторичной функции могут быть обращения к этим переменным, т.е. код может захватить некоторые ресурсы и ссылки на часть этих ресурсов передать в функцию.
    Тогда эта возвращенная вторичная функция будет иметь такую особенность, что внутри нее будут ссылки на некие ресурсы, находящиеся где-то. И если бы эти ресурсы были удалены, то при запуске этой функции на выполнение произошла бы ошибка (были бы не найдены какие-то затребованные данные). Поэтому когда такая функция объявляется в выполняемом коде (т.е. создается динамически) и при возвращении из кода присваивается какой-то переменной, то чтобы эта операция имела смысл, интерпретатор сохраняет в памяти созданные в коде данные, на которые ссылается эта функция.
    Именно память под данные, на которые ссылается вторичная функция, выделенная в момент выполнения кода первичной функции (в этот момент как раз создается и размещается в памяти и вторична функция) сохраняется. Остальная память, временно выделявшаяся при работе кода первичной функции, высвобождается.
    Т.е. эту вторичную функцию можно рассматривать просто как обычный объект, содержащий в своих полях некоторые данные. Естественно, пока на этот объект где-то будут оставаться ссылки, будут сохраняться в памяти и данные этого объекта.
    Пока где-то в коде существует действующая ссылка на эту вторичную функцию, будут работоспособными и все ссылки внутри этой функции на участки памяти с данными, которые выделялись при создании этой вторичной функции.
    Если мы второй раз вызовем первичную функцию, мы создадим уже совершенно другой объект вторичной функции, со своими данными.
    Эта вторичная функция, т.е. этот динамически созданный объект, называется, вы не поверите, - замыканием.
    Ответ написан
    Комментировать
  • Как работает Array.prototype.slice.call?

    @alexfarm2
    slice() или slice(0) - копирует массив (делает срез, начиная с нулевого элемента)
    При вызове без аргументов, параметр считается undefined, что преобразуется в ноль
    Array.prototype - это реальный объект, у которого есть метод slice()
    var a=Array.prototype.slice(0); -копируем объект Array.prototype в а
    var a=Array.prototype.slice(); -делаем то же самое

    Массивоподобный объект (псеводмассив) — это объект, который структурно похож на массив. У него есть числовые свойства (индексы) и свойство length.

    Вот пример массивоподобного объекта:
    var object = {0: 1, 1: 2, 2: 3, length: 3}

    Преобразуем массивоподобный объект в массив:
    var array = Array.prototype.slice.call(object); // Или сокращённая форма: [].slice.call(object);

    Здесь мы вызываем метод slice на объекте Array.prototype, но контекстом является объект object, т.е. пытаемся сделать срез с объекта object, начиная с нулевого элемента. Срезом будет полноценный массив.

    console.log( array ); // [1, 2, 3]

    Можно вызвать slice и с параметром:
    var array2 = Array.prototype.slice.call(object,1);

    console.log( array2 ); // [2, 3]
    Ответ написан
    Комментировать