在现代浏览器上下文中的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"
两个问题:
- 为什么上面
value
未定义? - 有没有办法覆盖/猴子补丁
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
的第一个参数,bind
,apply
的第一个参数是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"}"