Вопрос:

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

javascript methods chaining method-chaining

27474 просмотра

5 ответа

21007 Репутация автора

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

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

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

Что я знаю:

  1. Функции должны возвращать сами, иначе "вернуть это";
  2. Цепные функции должны находиться в родительской функции, также как в jQuery. .Css () - это вспомогательный метод 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();
Автор: Geuis Источник Размещён: 08.07.2009 05:58

Ответы (5)


36 плюса

2329 Репутация автора

Решение

В 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();

Назначая

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

В приведенных выше примерах «this» относится к объекту окна, если вы не заключили функции в другую функцию или объект.

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

Автор: Lark Размещён: 08.07.2009 06:22

4 плюса

56660 Репутация автора

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

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

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

HTMLElement.prototype.setAttr = function(attr) {
    HTMLElement.prototype.setAttribute(attr);
    return this;
}
Автор: kojiro Размещён: 10.06.2012 01:43

1 плюс

20339 Репутация автора

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

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;
};

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

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

Автор: FishBasketGordo Размещён: 10.06.2012 01:51

-4 плюса

177 Репутация автора

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

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

Автор: Shankar Us Размещён: 19.11.2014 12:27

0 плюса

372 Репутация автора

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

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

$('#demo');

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

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

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

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

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

Автор: ryanwaite28 Размещён: 16.03.2017 06:13
Вопросы из категории :
32x32