草庐IT

javascript - "add"适用于不同链接/参数组合的函数

coder 2024-05-06 原文

我正在尝试编写一个适用于多种情况的添加函数。

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/

有关javascript - "add"适用于不同链接/参数组合的函数的更多相关文章

  1. ruby-on-rails - rails : "missing partial" when calling 'render' in RSpec test - 2

    我正在尝试测试是否存在表单。我是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

  2. ruby-on-rails - 由于 "wkhtmltopdf",PDFKIT 显然无法正常工作 - 2

    我在从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""-

  3. ruby-on-rails - Rails 常用字符串(用于通知和错误信息等) - 2

    大约一年前,我决定确保每个包含非唯一文本的Flash通知都将从模块中的方法中获取文本。我这样做的最初原因是为了避免一遍又一遍地输入相同的字符串。如果我想更改措辞,我可以在一个地方轻松完成,而且一遍又一遍地重复同一件事而出现拼写错误的可能性也会降低。我最终得到的是这样的:moduleMessagesdefformat_error_messages(errors)errors.map{|attribute,message|"Error:#{attribute.to_s.titleize}#{message}."}enddeferror_message_could_not_find(obje

  4. ruby - 检查 "command"的输出应该包含 NilClass 的意外崩溃 - 2

    为了将Cucumber用于命令行脚本,我按照提供的说明安装了arubagem。它在我的Gemfile中,我可以验证是否安装了正确的版本并且我已经包含了require'aruba/cucumber'在'features/env.rb'中为了确保它能正常工作,我写了以下场景:@announceScenario:Testingcucumber/arubaGivenablankslateThentheoutputfrom"ls-la"shouldcontain"drw"假设事情应该失败。它确实失败了,但失败的原因是错误的:@announceScenario:Testingcucumber/ar

  5. ruby-on-rails - 如何在 ruby​​ 中使用两个参数异步运行 exe? - 2

    exe应该在我打开页面时运行。异步进程需要运行。有什么方法可以在ruby​​中使用两个参数异步运行exe吗?我已经尝试过ruby​​命令-system()、exec()但它正在等待过程完成。我需要用参数启动exe,无需等待进程完成是否有任何ruby​​gems会支持我的问题? 最佳答案 您可以使用Process.spawn和Process.wait2:pid=Process.spawn'your.exe','--option'#Later...pid,status=Process.wait2pid您的程序将作为解释器的子进程执行。除

  6. ruby - RSpec - 使用测试替身作为 block 参数 - 2

    我有一些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

  7. ruby - 如何在 Ruby 中拆分参数字符串 Bash 样式? - 2

    我正在为一个项目制作一个简单的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"

  8. ruby - 在没有 sass 引擎的情况下使用 sass 颜色函数 - 2

    我想在一个没有Sass引擎的类中使用Sass颜色函数。我已经在项目中使用了sassgem,所以我认为搭载会像以下一样简单:classRectangleincludeSass::Script::FunctionsdefcolorSass::Script::Color.new([0x82,0x39,0x06])enddefrender#hamlengineexecutedwithcontextofself#sothatwithintemlateicouldcall#%stop{offset:'0%',stop:{color:lighten(color)}}endend更新:参见上面的#re

  9. ruby - 检查方法参数的类型 - 2

    我不确定传递给方法的对象的类型是否正确。我可能会将一个字符串传递给一个只能处理整数的函数。某种运行时保证怎么样?我看不到比以下更好的选择:defsomeFixNumMangler(input)raise"wrongtype:integerrequired"unlessinput.class==FixNumother_stuffend有更好的选择吗? 最佳答案 使用Kernel#Integer在使用之前转换输入的方法。当无法以任何合理的方式将输入转换为整数时,它将引发ArgumentError。defmy_method(number)

  10. ruby-on-rails - 在默认方法参数中使用 .reverse_merge 或 .merge - 2

    两者都可以defsetup(options={})options.reverse_merge:size=>25,:velocity=>10end和defsetup(options={}){:size=>25,:velocity=>10}.merge(options)end在方法的参数中分配默认值。问题是:哪个更好?您更愿意使用哪一个?在性能、代码可读性或其他方面有什么不同吗?编辑:我无意中添加了bang(!)...并不是要询问nobang方法与bang方法之间的区别 最佳答案 我倾向于使用reverse_merge方法:option

随机推荐