将自定义JavaScript函数添加到方法调用链中的本机方法

nia*_*hoo 11 javascript method-chaining

我想知道是否有本地方式这样做:

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()
Run Code Online (Sandbox Code Playgroud)

但我不想改变原型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
    }
}
Run Code Online (Sandbox Code Playgroud)

现在假设我无法更改此代码,因为此对象来自库,因此我不想这样做.然后,假设我想链接方法和一些自定义函数(请参阅我的第一个代码段)以获取更多不同的对象.最简单的chain方法是附加一个方法Object.prototype.

但我认为它可能导致未来的冲突.我正在寻找一种方法来做同样的事情而不触及原型.

Jay*_*Jay 5

我很惊讶,说实话,没有答案.

有许多方法可以原生地引入链接.我喜欢使用揭示模块模式.

所以我创建了一个基本模型(继续并在你的firefox控制台的chrome中查看它)

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
    };
    }
Run Code Online (Sandbox Code Playgroud)

现在创建一个新的狗使用 var p = new Dog("doggyName");

现在,你可以链接功能.尝试:

p.movement().jump().run().jump().run();
Run Code Online (Sandbox Code Playgroud)

您应该获得与每个功能对应的控制台记录文本.

通过在执行移动函数后返回此范围,可以公开在该范围内返回的其他函数(请参阅代码中的注释).然后,只要它们位于相同的范围内,它们就可以链接到当前函数的末尾.这允许您范围代码的特定部分.例如,对于这只狗,所有的动作都是范围的self.movement,你可以吃所有的吃东西self.eat等等

阅读揭示模块模式.虽然这不是唯一的方法.


Ami*_*ich 2

包装器可以包装任何对象以使其与“链接”兼容,并将添加另一个链方法,该方法允许您插入外部函数并仍然获得链接。

检查这个例子:

   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();
Run Code Online (Sandbox Code Playgroud)

JSFIDDLE