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

A native way of adding custom JavaScript functions into a method-calls chain

我想知道是否有本地方法可以做到这一点:

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.

但我认为这可能会导致将来发生冲突。我正在寻找一种在不接触原型的情况下做同样事情的方法。

老实说,我很惊讶没有答案。

有很多方法可以在本地引入链接。我喜欢用 revealing module pattern.

所以我创建了一个基本模型(继续将其放入您的 chrome 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();

您应该获得与每个函数对应的控制台记录文本。

通过在执行移动函数后返回 this 的范围,您公开了在该范围内返回的附加函数(请参阅代码中的注释)。然后可以将它们链接到当前函数的末尾,前提是它们在同一范围内。这允许您限定代码的特定部分。例如,对于这只狗,所有运动都限制在 self.movement,你可以将所有进食限制在 self.eat 等等

Read up on the revealing module pattern。虽然这不是唯一的方法。

为了 "plug" 一个未绑定的函数到对象的方法链中,你可以将它分配给一个 属性 并调用它:

function fn() {
    document.write('hi ');
    return this;
}

someObj = {
    meth1: function() {
        document.write('meth1 ');
        return this;
    },
    meth2: function() {
        document.write('meth2 ');
        return this;
    }
}

someObj
    .meth1()
    [someObj._=fn, '_']()
    .meth2()

如果你问我,这看起来不太漂亮。一个更具可读性的选项是动态添加 chain 方法,例如:

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

chainable(someObj).meth1().chain(fn).meth2()

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

检查这个例子:

   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.