julik live

JavaScript - прототипы

Одна из непопулярных (но при этом невероятно практичных) возможностей JS - изменение прототипов (иными словами, добавление методов и свойств ко всем объектам определенного класса. А возможность между прочим - удобнейшая( !). Пример использования такой возможности - удобное "прокручивание" массивов.


При написании любого JavaScript'а рано или поздно возникает необходимость обработать все элементы массива. Традиционно это делается через конструкцию for:

for (var i =0; i  < myArr.length; i++) {
        myArr[i].doSomething();
}

Однако почему бы не сделать для себя небольшое удобство и не листать массив вот так:

while (var element = myArr.next() ) {
    var current = element;
}

Причем этот метод будет доступен для любого массива, в том числе для созданных стандартными системными средствами. А все благодаря тому, что у каждого объекта в JavaScript есть т.н. прототип, которому можно присваивать свойства и методы (поскольку формально в JS классов и их наследования нету, методы и свойства объектов можно расширять "анонимно" - простым присвоением снаружи). Чтобы создать наш метод next (по сути - итератор), мы обратимся к свойству prototype встроенного объекта Array. Заодно создадим простой указатель на элемент, используемый в настоящий момент, и еще несколько методов:

myArr.toLast()  //"промотать" массив до последнего элемента

myArr.rewind()  //перейти в начало массива, аналог функции reset() в PHP

myArr.next()  //возвращает следующий элемент массива

myArr.prev() //возвращает предыдущий элемент массива

Итак, приступим:

//Add method to initialize pointer
Array.prototype._checkPointer = function() {
    if (typeof(this._pointer) == 'undefined') {
        this._pointer = 1;
    }
}

//Add method to rewind forward
Array.prototype.rewind = function() {
    this._pointer = 1;
}

//Add method to move pointer to the end
Array.prototype.toLast = function() {
    this._checkPointer();
    this._pointer = this.length +1;
}

//Add method to go to next element
Array.prototype.next = function() {
    //check pointer
    this._checkPointer();
    // return current pointer position minus one
    if (this._pointer === this.length +1) {
        return false;
    } else {
        var ind = this._pointer -1;
        this._pointer ++;
        return this[ind];
    }
}

//Add method to go to previous element
Array.prototype.prev = function() {
    //check pointer status
    this._checkPointer();

    //check if we are at the first element
    if (this._pointer == 1) {
        return false;
    } else {
        //decrement pointer
        this._pointer -=1;
        return this[this._pointer -1];
    }
}

Таким образом мы присвоим эти методы всем существующим массивам (даже тем, которые были созданы до исполнения этого кода!). Дальнейшие варианты - действий на эту тему - например, функции toTranslit и fromTranslit для каждого объекта String и так далее. BTW - код грязный, несколько минут работы всего.

PHP сосет одним словом... Причем такая возможность должна быть не только в JavaScript для веб-страниц, но и в том JS, которым скриптятся InDesign CS, Director 2004, LiveMotion, Combustion...

Suspects: Веб-стройка

 
comments powered by Disqus

Aspirine not included.