Подтвердить что ты не робот

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

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

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

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

Что я знаю:

  • Функции должны возвращаться, ака "вернуть это";
  • Цепные функции должны находиться в родительской функции, так как в jQuery,.css() является вспомогательным методом jQuery(), поэтому jQuery(). css();
  • Родительская функция должна либо возвращать себя, либо сам новый экземпляр.

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

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();
4b9b3361

Ответ 1

В 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(). Если вы запустите фрагмент выше, вы увидите предупреждение для "добавить" и "удалить".

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

Мне сложно понять цепочку, по крайней мере, для меня, но как только я это понял, я понял, насколько мощным инструментом может быть.

Ответ 2

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

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

Лучшее, что вы могли бы избежать, это другое имя:

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

Ответ 3

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

function MyObject() { };

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

Чтобы переписать func1 для цепочки, сделайте следующее:

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

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

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

Ответ 4

Во-первых, позвольте мне сказать, что я объясняю это своими словами.

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

$('#demo');

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

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

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

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

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

Ответ 5

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

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