Нативный способ добавления пользовательских функций JavaScript в цепочку вызовов методов

Я хотел бы знать, есть ли способ для этого:

Object.prototype.chain = function(f) { return f.call(this) }


function fun1() {
    doSomethingWithObject(this)
    return this
}

function fun2() {
    doSomethingElse(this)
    return this
}

someObject
    .method1('something')
    .method2()
    .chain(checkSomething() ? fun1 : fun2)
    .method3()

Но мне не хочется менять прототип Object. Есть ли способ сделать это без изменения прототипа Objects или других конструкторов, которые я использую (и я не разработчик)

Редактирование:

Я чувствую, что не очень хорошо объясняю, поэтому давайте добавим некоторые детали:

Что я хотел бы сделать, так это использовать некоторые API, которые я не определяю. someObject определяется следующим образом: с цепными методами:

var someObject = {
    method1: function(val) {
        // do something
        return this
    },
    method2: function() {
        // do something
        return this
    },
    method3: function() {
        // do something
        return this
    }
}

Теперь представьте, что я не могу изменить этот код, потому что этот объект из библиотеки, и поэтому я не хочу этого делать. Затем представьте, что я хотел бы связать методы и некоторые пользовательские функции (см. Мой первый фрагмент) для многих других объектов. Самое простое - подключить метод chain к Object.prototype.

Но я думаю, что это может привести к конфликтам в будущем. Я ищу способ сделать то же самое, не касаясь прототипа.

Ответ 1

Обертка - это то, что обернет любой объект, чтобы сделать его совместимым с "цепочкой", и добавит еще один цепной метод, который позволит вам подключать внешние функции и по-прежнему получать цепочку.

Проверьте этот пример:

   function myObj() {
    this.state = {
        a: 1
    };
    this.method1 = function () {
        console.log("1");
    }
    this.method2 = function () {
        console.log("2");
    }
    this.method3 = function () {
        console.log("3");
    }
    this.method4 = function () {
        console.log(this.state);
    }
}

function objectChainWrapper(obj) {
    this.chain = function (fn) {
        fn.call(obj);
        return this;
    }

    for (var prop in obj) {
        if (obj.hasOwnProperty(prop) && typeof obj[prop] == 'function') {
            this[prop] = (function (methodName) {
                return function () {
                    obj[methodName].call(obj);
                    return this;
                }
            }(prop))
        }
    }
}

var obj = new myObj();
var wrapper = new objectChainWrapper(obj);
var chainMethod = function(){ console.log('chain') };
var chainMethodState = function(){ console.log(this.state) };
wrapper.method1().method2().chain(chainMethodState).method3().chain(chainMethod).method4();

JSFIDDLE.

Ответ 2

Я удивлен, что нет никаких ответов на это, если честно.

Существует множество способов изначально ввести цепочку. Мне нравится использовать раскрытие шаблона модуля.

Итак, я создаю базовую модель (иди и запусти ее в хром консоли firefox)

var Dog = function(name) {
    var self = this;
    this.name = name;


     var core = {
            getName:function(){
                return self.name;
            }
        }; 

    this.movement = function(){     //this function will be exposed including its returned functions for chaining      
        console.log(self.name + " is getting restless... ");

        var jump = function(){
            console.log(self.name + " jumps around ");
            return this //returns the movement scope
        };
        var run = function(){
            console.log(self.name + " has decided to run");
            return this //returns the movement scope
        };

        return {
            jump:jump,
            run:run           
        };

    }       
    console.log("A Pup has been born, we shall call him... " + name);
    return{
        movement:self.movement    //only .movement is exposed to the outside world
    };
    }

Теперь создайте новую собаку, используя var p = new Dog("doggyName");

теперь вы можете цеплять функции. Попробуйте:

p.movement().jump().run().jump().run();

Вы должны получить текст, записанный в консоли, который соответствует каждой функции.

Возвращая объем этой функции после выполнения вашей функции перемещения, вы обнаружите дополнительные функции, которые возвращаются в этой области (см. комментарии в коде). Затем они могут быть привязаны к концу вашей текущей функции при условии, что они находятся в одном и том же объеме. Это позволяет вам обладать определенными частями вашего кода. Например, с этой собакой все движения ограничены до self.movement, вы можете иметь все, что есть, до self.eat и т.д.

Прочитайте раскрывающийся шаблон модуля. Хотя это не единственный способ сделать это.