如何在JavaScript中创建可链函数

How to make chainable function in JavaScript?

本文关键字:函数 创建 JavaScript      更新时间:2023-09-26

让我们想象一下这样的函数:

function foo(x) {
    x += '+';
    return x;
}

用法如下:

var x, y;
x = 'Notepad';
y = foo(x);
console.log(y); // Prints 'Notepad+'.

我正在寻找一种方法来创建可与其他函数链接的函数。

想象用法:

var x, y;
x = 'Notepad';
y = x.foo().foo().toUpperCase(); // Prints 'NOTEPAD++'.
console.log(y);

我该怎么做呢?

当然,技巧是一旦修改完成就返回对象:

String.prototype.foo = function() {
    return this + "+";
}
var str = "Notepad";
console.log(str.foo().foo().toUpperCase());
http://jsfiddle.net/Xeon06/vyFek/

为了使该方法在String上可用,我正在修改它的原型。注意不要在Object上这样做,因为在枚举它们的属性时可能会导致问题。

如果我没记错的话,您可以使用"this"作为函数(它所属的对象)的上下文并返回它以使函数可链接。换句话说:

var obj = 
{
    f1: function() { ...do something...; return this;},
    f2: function() { ...do something...; return this;}
}

,那么你可以像obj.f1().f2()

那样链接调用

请记住,您将无法通过调用obj.f1(). touppercase()来实现您所期望的-它将执行f1(),返回"this"并尝试调用obj.toUpperCase()。

这里有一种不干扰String.prototype的方法,通过返回一个类似于字符串的对象,并附带一个foo()方法。然而,这种方法也有一些缺点,比如它没有返回一个实际的字符串。

// Returns an object similar to a string, with an additional method foo()
function foo(str) {
  return Object.assign(`${str ?? this}+`, {
    foo
  });
}
var str = "Notepad";
console.log(
  "EXAMPLE - foo(str).foo().toUpperCase():",  
  foo(str).foo().toUpperCase()
);
console.log("---");
console.log("Some issues with this solution:");
console.log("typeof foo(str):", typeof foo(str));
console.log("foo(str).foo():", foo(str).foo());
console.log(
  "You may need to use toString() - foo(str).foo().toString():",
  foo(str).foo().toString()
);
.as-console-wrapper { min-height: 100% }