Function.prototype.toString的预期与实现

531 阅读2分钟

前言

最近在掘金看文章,遇到一个经典的面试题,于是便试着写了下,结果发现与文章输出不太一样,于是深入下去求证了下,便有了这篇文章。

验证

题目的代码大概如下,网上能查到非常多类似的题目,大多题解都会跟你说,toString会自动执行,输出我们想要的结果16,但事实真的如此吗?

function add(...args) {
  let fn = function () {
    return add.apply(null, args.concat([...arguments]));
  };
  fn.toString = () => {
    console.log("toString");
    return args.reduce((a, b) => a + b);
  };
  return fn;
}
add(1)(3, 4)(3, 5)
  1. 首先我们把代码放到chrome控制台里面试一下

    image.png

  2. 咦?不对啊,为什么不是我们我们要的值啊,是不是这里没有用console触发隐式转换,那我们再试试

    image.png

  3. 从输出可以看到,我们的 toString 隐式转换是执行了的,可为什么结果不对呢?

    下面我们把代码分别丢进不同环境试试

    image.png

  4. 这次似乎对了,输出了16,但真的是16吗?我们可以看到16前面有个f,使用typeof检验一下,得到的依然是一个function,并不是我们想要的东西。

    并且如果我们在webstrom或者powershell里面直接使用node执行的时候,输出跟chrome一样,打印的都是function里面的字符。

结论

为什么结果不一样

通过查阅 文档 说明,得到了结论,Function.prototype.toString并不是标准的提案,所以针对不同环境的各种异常表现,可能是各家实现的不太一样导致的。

image.png

什么情况下可以输出我们期望的值

首先可以知道的是,这题是错的,笔者尝试了各种浏览器各种环境都没有得到 16。

如果想要获得16,我们需要主动去触发隐式转换

console.log(+add(1)(3, 4)(3, 5))

网上很多的文章都是相互copy的,很多都没有验证,大家看的时候一定要去亲自尝试,才能学到真正的东西。