【问题标题】:Should I worry when overriding function.toString in JavaScript?在 JavaScript 中覆盖 function.toString 时我应该担心吗?
【发布时间】:2013-01-11 16:45:29
【问题描述】:

当我在 JavaScript 中编写函数包装器(例如:throttledebounce 函数)时,我希望能够检查“装饰”函数并且仍然能够知道底层函数是什么。以throttle 的实现为例:

function throttle(fn, time) {
  var handle;

  var execute = function() {
    handle = null;
    fn.apply(this, arguments);
  };

  var throttled = function() {
    if(!handle) {
      handle = setTimeout(execute.bind(this), time);
    }
  };

  throttled.toString = function() {
    return fn.toString() + "\n// throttled to " + time + "ms";
  };

  return throttled;
}

var makeAjax = throttle(function(callback) {
  $.getJSON("/path", callback);
}, 500);

console.log(makeAjax);

console.log 呼叫显示:

function (callback) {
  $.getJSON("/path", callback);
}
// throttled to 500ms

作为throttle 的用户,我更关心我赋予它的功能,而不是其内部throttled

但是,在覆盖原生函数时,我总是感到有些不安。在执行此操作时,我是否应该担心任何合规性和/或性能问题?

【问题讨论】:

  • 隐式转换可能是个问题。但是您可能不会遇到隐式强制转换函数的情况。
  • 任何会调用fn.toString() 的东西要么用于日志记录,要么用于动态重新编译,所以我认为你会很好。特别是因为您没有覆盖Function.prototype.toString
  • @Esailija 动态重新编译是什么意思?
  • @RenatoZannon 通过.toString() 读取函数体,修改它,eval 结果。这不是任何正常的事情,所以不要担心。它可以用于元编程。

标签: javascript function overloading


【解决方案1】:

在 Mozilla 开发者小组中,他们更多地讨论了覆盖 toString()。 https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Object/toString

我认为这里可能存在的问题是创建自动化单元测试(我的经验仅限于 NUnit Selenium),您可能无法使用私有 .toString() 或者它可能导致不稳定的测试结果?调试也可能是个问题!

对于覆盖其他具有方法的本地 js 函数,您可能还需要手动扩展所有方法以替换被覆盖的内容。

Addy Osmani 在他的《学习 JavaScript 设计模式》一书中进一步讨论了这一点,http://addyosmani.com/resources/essentialjsdesignpatterns/book/#modulepatternjavascript

【讨论】:

  • 目标是协助调试,因为在处理装饰过的函数时通常无法使用原始函数......我想它可能会在throttle nastier 中找到错误.我不明白你在第三段中的意思,你能扩展一下或举个例子吗?谢谢!
  • mdn 文章是关于Object.prototype.toString,而不是Function.prototype.toString。对象 toString 在这里根本不相关。
  • @Esailija 默认情况下,javascript 中的函数是对象。所以当你创建一个函数时,它会自动继承 Object 的属性。如需进一步阅读,请查看developer.mozilla.org/en-US/docs/JavaScript/Reference/…
  • @Esailija 我认为您需要为此评论创建一个新线程,它开始偏离主题。
  • @RenatoZannon 例如,假设你有这个变量,var x = Math.min(12, 5).toString(); 如果你要覆盖 Math.min() 函数它也不会自动继承 .toString(),你需要手动扩展它.
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多