我正在尝试编写一个适用于多种情况的添加函数。
add(2,2,2) //6
add(2,2,2,2) //8
add(2)(2)(2) // 6
add(2)(2)(2,2).value() //8
add(2,2)(2) + 2 //8
add(2).add(2) //4
add(2,2,2).add(2).add(2,2).value() //12
add(2,2,2).add(2).value() //8
这是我目前所拥有的:
function add(){
var sum = 0;
for( var i in arguments ){
sum += arguments[i];
}
var ret = add.bind(null, sum);
ret.value = function () {
return sum;
}
ret.add = function () {
for( var i in arguments ){
sum += arguments[i];
}
return sum;
}
ret.valueOf = function(){ return sum; };
return ret;
}
console.log(add(2,2,2));
console.log(add(2,2,2,2));
console.log(add(2)(2)(2));
console.log(add(2)(2)(2,2).value());
console.log(add(2,2)(2) + 2);
console.log(add(2).add(2));
console.log(add(2,2,2).add(2).value());
console.log(add(2,2,2).add(2).add(2,2).value());
我对最后两种情况有疑问:
add(2,2,2).add(2).add(2,2).value() //12
add(2,2,2).add(2).value() //8
如果我想将两个以上的链接在一起并向每个函数添加值函数,似乎我必须继续嵌套添加函数,但显然我缺少一些简单的东西可以让我链接它们尽我所能,并为其中任何一个赋予值(value)。
此外,他们还需要始终返回整数(而不是字符串),而且似乎有时他们会这样做,有时他们不会?
最佳答案
看看您在两个不同地方以类似方式使用 arguments 的方式,很明显您在重复功能,这就是为什么您遇到必须“无限嵌套”的问题".value() 方法。
要认识到的关键是 add() 可以返回一个函数,该函数引用自身作为它自己的 add 属性。这将允许 add(1,2)(3) 的行为与 add(1,2).add(3) 完全相同。这可以像这样完成:
function add() {
var sum = Array.prototype.reduce.call(arguments, function(l, r) {
return l + r;
}, 0);
var ret = add.bind(null, sum);
ret.add = ret;
ret.value = ret.valueOf = Number.prototype.valueOf.bind(sum);
ret.toString = Number.prototype.toString.bind(sum);
return ret;
}
snippet.log(add(2,2,2));
snippet.log(add(2,2,2,2));
snippet.log(add(2)(2)(2));
snippet.log(add(2)(2)(2,2).value());
snippet.log(add(2,2)(2) + 2);
snippet.log(add(2).add(2));
snippet.log(add(2,2,2).add(2).value());
snippet.log(add(2,2,2).add(2).add(2,2).value());
snippet.log(add(1, 2, 3)(4, 5).add(6, 7)(8).add(9, 10));
snippet.log(add(5,4)(3).add(2)(1) * 10);<!-- Provides the `snippet` object, see http://meta.stackexchange.com/a/242144/134069 -->
<script src="http://tjcrowder.github.io/simple-snippets-console/snippet.js"></script>
上述方法仍然存在两个潜在的问题,一个是次要的,另一个是不那么次要的:
add 函数(包括链接期间)时都会重新执行属性引用和函数定义add 标识符,将导致整个实现中断:function add() {
var sum = Array.prototype.reduce.call(arguments, function(l, r) {
return l + r;
}, 0);
var ret = add.bind(null, sum);
ret.add = ret;
ret.value = ret.valueOf = Number.prototype.valueOf.bind(sum);
ret.toString = Number.prototype.toString.bind(sum);
return ret;
}
var myAdd = add;
add = "boom!";
myAdd(1, 2, 3); // TypeError: add.bind is not a function
这两个问题都可以通过 IIFE 来解决:
var add = (function () {
var reduce = Array.prototype.reduce,
np = Number.prototype,
valueOf = np.valueOf,
toString = np.toString,
plus = function (l, r) { return l + r; };
return function add() {
var sum = reduce.call(arguments, plus, 0);
var ret = add.bind(null, sum);
ret.add = ret;
ret.value = ret.valueOf = valueOf.bind(sum);
ret.toString = toString.bind(sum);
return ret;
}
})();
var myAdd = add;
add = "U Can't Touch This"; // hammertime
snippet.log(myAdd(1, 2, 3)(4, 5).add(6, 7)(8).add(9, 10));
snippet.log(myAdd(5,4)(3).add(2)(1) * 10);<!-- Provides the `snippet` object, see http://meta.stackexchange.com/a/242144/134069 -->
<script src="http://tjcrowder.github.io/simple-snippets-console/snippet.js"></script>
关于javascript - "add"适用于不同链接/参数组合的函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28927510/
我正在尝试测试是否存在表单。我是Rails新手。我的new.html.erb_spec.rb文件的内容是:require'spec_helper'describe"messages/new.html.erb"doit"shouldrendertheform"dorender'/messages/new.html.erb'reponse.shouldhave_form_putting_to(@message)with_submit_buttonendendView本身,new.html.erb,有代码:当我运行rspec时,它失败了:1)messages/new.html.erbshou
我在从html页面生成PDF时遇到问题。我正在使用PDFkit。在安装它的过程中,我注意到我需要wkhtmltopdf。所以我也安装了它。我做了PDFkit的文档所说的一切......现在我在尝试加载PDF时遇到了这个错误。这里是错误:commandfailed:"/usr/local/bin/wkhtmltopdf""--margin-right""0.75in""--page-size""Letter""--margin-top""0.75in""--margin-bottom""0.75in""--encoding""UTF-8""--margin-left""0.75in""-
大约一年前,我决定确保每个包含非唯一文本的Flash通知都将从模块中的方法中获取文本。我这样做的最初原因是为了避免一遍又一遍地输入相同的字符串。如果我想更改措辞,我可以在一个地方轻松完成,而且一遍又一遍地重复同一件事而出现拼写错误的可能性也会降低。我最终得到的是这样的:moduleMessagesdefformat_error_messages(errors)errors.map{|attribute,message|"Error:#{attribute.to_s.titleize}#{message}."}enddeferror_message_could_not_find(obje
为了将Cucumber用于命令行脚本,我按照提供的说明安装了arubagem。它在我的Gemfile中,我可以验证是否安装了正确的版本并且我已经包含了require'aruba/cucumber'在'features/env.rb'中为了确保它能正常工作,我写了以下场景:@announceScenario:Testingcucumber/arubaGivenablankslateThentheoutputfrom"ls-la"shouldcontain"drw"假设事情应该失败。它确实失败了,但失败的原因是错误的:@announceScenario:Testingcucumber/ar
exe应该在我打开页面时运行。异步进程需要运行。有什么方法可以在ruby中使用两个参数异步运行exe吗?我已经尝试过ruby命令-system()、exec()但它正在等待过程完成。我需要用参数启动exe,无需等待进程完成是否有任何rubygems会支持我的问题? 最佳答案 您可以使用Process.spawn和Process.wait2:pid=Process.spawn'your.exe','--option'#Later...pid,status=Process.wait2pid您的程序将作为解释器的子进程执行。除
我有一些Ruby代码,如下所示:Something.createdo|x|x.foo=barend我想编写一个测试,它使用double代替block参数x,这样我就可以调用:x_double.should_receive(:foo).with("whatever").这可能吗? 最佳答案 specify'something'dox=doublex.should_receive(:foo=).with("whatever")Something.should_receive(:create).and_yield(x)#callthere
我正在为一个项目制作一个简单的shell,我希望像在Bash中一样解析参数字符串。foobar"helloworld"fooz应该变成:["foo","bar","helloworld","fooz"]等等。到目前为止,我一直在使用CSV::parse_line,将列分隔符设置为""和.compact输出。问题是我现在必须选择是要支持单引号还是双引号。CSV不支持超过一个分隔符。Python有一个名为shlex的模块:>>>shlex.split("Test'helloworld'foo")['Test','helloworld','foo']>>>shlex.split('Test"
我想在一个没有Sass引擎的类中使用Sass颜色函数。我已经在项目中使用了sassgem,所以我认为搭载会像以下一样简单:classRectangleincludeSass::Script::FunctionsdefcolorSass::Script::Color.new([0x82,0x39,0x06])enddefrender#hamlengineexecutedwithcontextofself#sothatwithintemlateicouldcall#%stop{offset:'0%',stop:{color:lighten(color)}}endend更新:参见上面的#re
我不确定传递给方法的对象的类型是否正确。我可能会将一个字符串传递给一个只能处理整数的函数。某种运行时保证怎么样?我看不到比以下更好的选择:defsomeFixNumMangler(input)raise"wrongtype:integerrequired"unlessinput.class==FixNumother_stuffend有更好的选择吗? 最佳答案 使用Kernel#Integer在使用之前转换输入的方法。当无法以任何合理的方式将输入转换为整数时,它将引发ArgumentError。defmy_method(number)
两者都可以defsetup(options={})options.reverse_merge:size=>25,:velocity=>10end和defsetup(options={}){:size=>25,:velocity=>10}.merge(options)end在方法的参数中分配默认值。问题是:哪个更好?您更愿意使用哪一个?在性能、代码可读性或其他方面有什么不同吗?编辑:我无意中添加了bang(!)...并不是要询问nobang方法与bang方法之间的区别 最佳答案 我倾向于使用reverse_merge方法:option