我在一生中收集了许多有用的功能。
function one(num){
return num+1;
}
function two(num){
return num+2;
}
我可以用two(two(one(5)))
但我更愿意使用(5).one().two().two()
如何在不使用原型的情况下实现这一目标?
我试图了解下划线如何工作,但他们的代码太强烈而无法理解
答案 0 :(得分:22)
点语法是为对象保留的。所以你可以做类似
的事情function MyNumber(n) {
var internal = Number(n);
this.one = function() {
internal += 1;
// here comes the magic that allows chaining:
return this;
}
// this.two analogous
this.valueOf = function() {
return internal;
}
}
new MyNumber(5).one().two().two().valueOf(); // 10
或者您将在本机Number对象/函数的原型上实现这些方法。这将允许(5).one()...
答案 1 :(得分:6)
为了避免像在@ Bergi的解决方案中那样在链的末尾调用toValue
,您可以使用附加方法的函数。当尝试将原始类型转换为原始类型时,JS会自动调用toValue
。
function MyNumber(n) {
function x () { }
x.one = function() { n++; return this; };
x.valueOf = function() { return n; };
return x;
}
然后,
MyNumber(5).one().one()
> 7
答案 2 :(得分:4)
一个不错的通用替代方法是创建自定义函数组合函数
var go = function(x, fs){
for(var i=0; i < fs.length; i++){
x = fs[i](x);
}
return x;
}
您可以这样称呼它:
go(5, [one, two, two])
我个人并不是方法链的忠实粉丝,因为它将你限制在一组预定义的函数中,并且“链接对象”中的值与外部的自由值之间存在一种阻抗不匹配。
答案 3 :(得分:0)
另一种选择是使用lodash flow功能。例如:
<html>
<head>
<title>The Pragmatic Octopus</title>
<meta charset="utf-8"/>
<link rel='stylesheet' href='style.css'/>
<script src='script.js'></script>
</head>
<body>
<div id="wrapper">
<div id="header">
<h1 class="Octagon">The Pragmatic Octopus</h1>
<p class="LT">Lee Townsend</p>
<a href="www.google.com">
<p class="boi">Contact</p>
</a>
<a href="www.google.com">
<p class="iob">Information</p>
</a>
</div>
<div id="content">
<img src="https://s32.postimg.org/406x38nlh/imageedit_1_3827627792 .jpg" alt="mmm~" id="manyarms">
<img src="http://www.wonderslist.com/wp-content/uploads/2014/07/Blue-ringed-octopus.jpg" alt="~mmm" id="sensible">
<p id="verr">Here comes a very special boi!</p>
<p id="special">He loves to pose for photos!</p>
</div>
<div id="footer">
© Hecc
</div>
</div>
</body>
</html>
我更喜欢为变量分配新链。它给它一个明确的名称,并鼓励重复使用。
顺便说一下,lodash还有助于将其他参数传递给链的功能。例如:
var five = _.flow(one, two, two)
five(5)
还有许多其他有用的功能可以帮助进行功能链接,例如部分,传播,翻转,否定等等。