如何(暂时)覆盖 Object.prototype.toString 或任何其他 JS 本机代码



在现代浏览器上下文中的JS中(特别是Chrome,但任何答案都很有趣)如何暂时覆盖Object.prototype.toString或任何其他本机代码方法,以便新实现在通过call调用时实际接收传递给它的值?

这是显而易见/直观的方法(在浏览器开发工具面板中运行),它不起作用:

console.log(Object.prototype.toString)
// (output) > ƒ toString() { [native code] }
Object.prototype.toString.call(new Date())
// (output) > "[object Date]"
Object.prototype.toString = function (value) {
console.log(`value is ${value}`)
return 'foo'
}
Object.prototype.toString.call(new Date())
// (output) > value is undefined
// (output) > "foo"

两个问题:

  1. 为什么上面value未定义?
  2. 有没有办法覆盖/猴子补丁Object.prototype.toString以便将函数参数传递给新的实现?

您可以在此处停止阅读,而不会错过与上述问题相关的任何内容

背景

/背景

肯定会有一些"你为什么要这样做"的回应。上下文是基于Selenium/量角器的生产验证套件,在真实API(无模拟数据)上运行,该套件需要将浏览器时间提前一个月,以便某些UI操作可用。

我最近发现任何替换 Date 对象的解决方案都不适用于 Angular 1.x,因为 Angular 有一个isDate方法可以调用 - 你猜对了 -Object.prototype.toString.call(dateCandidate)如果它没有返回确切的字符串[object Date]那么任何 Angular Date 格式代码都将不起作用。

有问题的角度代码:

  • is日期实现:https://github.com/angular/angular.js/blob/v1.5.11/src/Angular.js#L593
  • 角度日期筛选器将在模拟日期对象上中断:https://github.com/angular/angular.js/blob/v1.5.11/src/ng/filter/filters.js#L621

角度讨论为什么他们不会改变行为:https://github.com/angular/angular.js/issues/7143

这给我留下了几个糟糕的选择。这个问题正在推进"为什么我们不对 Angular 做一个单行补丁,然后按需覆盖Object.prototype.toString实现以在我们的 timeshift-js 模拟日期对象上返回[Object Date]"选项,这是我们糟糕解决方案列表中的当前领跑者。

你输入了错误的参数,call的第一个参数,bindapply的第一个参数是context,而不是被调用函数的参数

此代码:

Object.prototype.toString.call(new Date())
// (output) > value is undefined
// (output) > "foo"

应该是:

Object.prototype.toString.call(this, 'Bar')
// (output) > value is Bar
// (output) > "foo"
// this one also valid because you don't care about context
Object.prototype.toString.call(null, 'Bar')

本机.toString没有任何参数,因为它用于将触发它的Object解析为 String。例如,如果我想对本机执行相同的操作,我将像这样修改toString;

Object.prototype.toString = function() { 
return JSON.stringify(this);
}
var a = { foo : 'bar'}
Object.prototype.toString.call(a);
// or
a.toString()
// has the same output:
// "{"foo":"bar"}"

相关内容

最新更新