关于javascript函数valueOf \ toString和'curry'函数在Chrome,Firefox和节点环境

时间:2017-11-25 18:11:50

标签: javascript node.js google-chrome firefox

我写了一个函数:

function add(){
    let arr = [];
    arr = arr.concat(Array.prototype.slice.apply(arguments))
    let fun = function(){
        arr = arr.concat(Array.prototype.slice.apply(arguments))
        return fun
    }
    fun.toString = function(){
        console.log(222)
        return arr.reduce(function(total, num){
            return total+num
        }, 0)
    }
    return fun
}
console.log(add(1,2)(2,3)(3))

这是在Chrome中: enter image description here

两个问题:

  1. 在第一行,为什么'f 11',而不是'11'

  2. 为什么首先输出'f 11',而不是'222',我认为首先应该执行类型转换,然后在控制台上输出计算结果。

  3. 另一个奇怪的是,它是Firefox中具有相同代码的结果: enter image description here

    节点环境中的结果: enter image description here

    我不明白为什么,似乎在FF和节点中,没有执行计算操作。

    请帮助我......非常感谢!

2 个答案:

答案 0 :(得分:1)

首先,您可以稍微美化整个代码:

function add(..arr){
  function fun(...args){
   arr.push(...args);
   return fun
  }

  fun.toString = function(){
    return arr.reduce((total, num) => total + num)
  };
  return fun;
}

正如您所注意到的,记录功能完全取决于环境。 Firefox和Node返回该功能的代码,而Chrome确实如下:

out( "f" + add.toString())

所以我们调用了toString函数并记录了一些东西。为了在不同的环境之间保持一致的行为,我们可以明确地调用toString:

console.log(add(1)(2)(3).toString());

可以推断:

console.log("" + add(1)(2));

答案 1 :(得分:0)

如果您想要的是add,它是可变的和咖喱的(我仍然认为这很奇怪),只需这样做:

const add = (...args) => {
  let accum = args;
  let f = (...fargs) => {
    if (!fargs.length) {
      return accum.reduce((a, b) => { return a + b; }, 0);
    } else {
      accum = accum.concat(fargs);
      return f;
    }
  };
  return f;
};

add(1,2,3)(); // 6
add(1)(2,3)(); // 6
add()(); // 0

现在,您只需调用返回的函数,不带参数即可获取值。您可以使用它来使其更高效(例如,在循环中使用.push而不是.concat)但这应该有效。