Заметки в категории «JavaScript» (страница 18)

Очередь: синхронное выполнение функций

С использованием событийной (event-driven ) модели программирования появляется множество асинхронных вызовов, которые не всегда должны выполняться асинхронно. Чтобы упорядочить этот хаос я написал небольшой модуль, реализующий очередь.


/**
 * @method  add       добавить функцию в очередь
 * @method  interate  выполнить первую в очереди функцию и удалить ее из очереди
 * @method  clear     очистить очередь
 */
var Queue = function () {
    this.members = [];
};
Queue.prototype = {
    add: function (f) {
        if (f instanceof Function) {
            this.members.push(f);
        }
    },
    iterate: function () {
        if (this.members.length > 0) {
            var func = this.members.shift();
            func.call(this);
        }
    },
    clear: function () {
        this.members = [];
    }
};

При вызове функции, контекстом ее выполнения становится очередь. Перед тем как завершить свое выполнение каждая асинхронная функция должна позаботиться о вызове следующего элемента очереди через метод iterate.


function () {
    // сохраняем контекст (очередь) в локальную переменную
    var queue = this;
    $.get('data.xml', function (data) {
        // в этом месте this уже не ссылается на очередь
        process(data);
        // подолжаем исполнение очереди
        queue.iterate();
    });
}

Комментарии к заметке: 1

Добавить в один массив другой массив

Родной метод concat не годится, так как он делает копию массива после слияния, а нужно во чтобы то не стало сохранить исходный объект. Метод push тоже не подходит, так как добавляет массив как вложенный. Самое очевидное решение — циклом добавить элементы.

Но есть более элегантный метод!

var a = [1,2];
Array.prototype.push.apply(a, [11,12,13]);

Трюк основан на вызове через apply стандартного метода push объекта Array. Аргументы для push разворачиваются из массива. Контекстом исполнения, разумеется, является наш модифицируемый массив. Тот самый цикл, который мы могли написать явным образом и который бы исполнялся интерпретатором команда за командой, выполнится неявно и с гораздо большей скоростью.

Оставте свой комментарий

Определить координаты события (DOM Event)

Любое DOM-событие содержит в себе информацию о том, где находился указать мышки в момент возникновения этого события. Беда в том, что в различных браузерах эти поля называются по-разному и содержат информацию в различных системах отчета.

Эта функция нормализует информацию и приводит координаты в одну систему отсчета — относительно левого верхнего угла страницы.


function (e) {
    var point = {};
    if (e.pageX && e.pageY) {
        point.x = e.pageX;
        point.y = e.pageY;
    } else {
        point.x = e.clientX + (document.documentElement.scrollLeft ? document.documentElement.scrollLeft : document.body.scrollLeft);
        point.y = e.clientY + (document.documentElement.scrollTop ? document.documentElement.scrollTop : document.body.scrollTop);
    }
    return point;
}

Если используется jQuery, то аналогичные данные можно получить из полей pageX и pageY объекта, который передается в обработчик обытия.

Комментарии к заметке: 1

Создать независимую копию JavaScript массива

В JavaScript все присваивания объектов реализуются через передачу ссылок на них.

var oldArray = ["a", "b", "c"];
var newArray = oldArray;

Хоть мы и получили две разные переменные, но тем не менее они обе ссылаются на один и тот же объект массива. Если сейчас в одном массиве произвести какие-либо манипуляции с элементами, то аналогичные изменения можно будет увидеть и в другом.

Если вы хотите сделать независимую копию массива, то нужно использовать метод slice без аргументов.


var oldArray = ["a", "b", "c"];
var newArray = oldArray.slice();

Массивы oldArray и newArray будут состоять из одних и тех же элементов, но фактически это будут разные объекты.

Важно запомнить, что если массив состоит из сущностей Array или Object, то они по прежнему будут ссылаться на родительские объекты.

Комментарии к заметке: 11