Как работает цепочка базовых объектов/функций в javascript?

Я пытаюсь получить принципы выполнения цепочки функций в стиле jQuery прямо в моей голове. Под этим я подразумеваю:

var e = f1('test').f2().f3();

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

что я знаю:

  1. функции должны вернуться сами, ака " вернуть это;"
  2. цепные функции должны находиться в родительской функции, ака в jQuery, .УСБ() является суб метод jQuery (с), отсюда и jQuery().css ();
  3. родительская функция должна либо возвращать себя, либо новый экземпляр самой себя.

этот пример работал:

var one = function(num){
    this.oldnum = num;

    this.add = function(){
        this.oldnum++;
        return this;
    }

    if(this instanceof one){
        return this.one;    
    }else{
        return new one(num);    
    }
}
var test = one(1).add().add();

но этот не делает:

var gmap = function(){

    this.add = function(){
        alert('add');

        return this;    
    }   

    if(this instanceof gmap) {
        return this.gmap;   
    } else{
        return new gmap();  
    }

}
var test = gmap.add();

5 ответов


в JavaScript функции являются объектами первого класса. Когда вы определяете функцию, это конструктор для этого объекта функции. Другими словами:

var gmap = function() {
    this.add = function() {
        alert('add');
    return this;
    }

    this.del = function() {
       alert('delete');
       return this;
    }

    if (this instanceof gmap) {
        return this.gmap;
    } else {
        return new gmap();
    }
}
var test = new gmap();
test.add().del();

присвоить

new gmap();
для теста переменной теперь вы создали новый объект, который" наследует " все свойства и методы из конструктора gmap () (class). Если вы запустите фрагмент выше, вы увидите предупреждение "добавить"и " удалить".

в приведенных выше примерах "это" относится к окну объект, если вы не обернете функции в другую функцию или объект.


к сожалению, прямой ответ должен быть "нет". Даже если вы можете переопределить существующие методы (которые вы, вероятно, можете во многих UAs, но я подозреваю, не можете в IE), вы все равно застряли бы с неприятными переименованиями:

HTMLElement.prototype.setAttribute = function(attr) { 
    HTMLElement.prototype.setAttribute(attr) //uh-oh;  
}

лучшее, что вы могли бы, вероятно, уйти с помощью другого имени:

HTMLElement.prototype.setAttr = function(attr) {
    HTMLElement.prototype.setAttribute(attr);
    return this;
}

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

function MyObject() { };

MyObject.prototype.func1 = function(a, b) { };

переписать func1 для chainability, сделайте это:

MyObject.prototype.std_func1 = MyObject.prototype.func1;
MyObject.prototype.func1 = function(a, b) {
    this.std_func1(a, b);
    return this;
};

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

к тому времени, как вы сделаете всю эту работу, вы можете понять что есть лучшие способы выполнить то, что вы пытаетесь сделать, например, использовать библиотеку, в которой уже встроена цепочка. *кашель* jQuery *кашель*


цепочка методов в значительной степени вызывает метод объекта, возвращаемого другой функцией/методом. например (с помощью jquery):

$('#demo');

эта функция jQuery выбирает и возвращает объект jquery элемент DOM с демонстрацией id. если элемент был текстовым узлом (элементом), мы могли бы связать метод возвращаемого объекта. например:

$('#demo').text('Some Text');

Итак, пока функция / метод возвращает объект, вы можете связать метод возвращаемого объекта с исходным оператором.

Что касается того, почему последние не работают, обратите внимание, где и когда ключевое слово есть. Скорее всего, это вопрос контекста. Когда вы звоните this убедитесь, что this относится к самому объекту функции, а не к объекту окна / глобальной области.

надеюсь, что это поможет.


просто вызовите метод как VAR test = gmap ().add ();

поскольку gmap-это функция, а не переменная