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

时间:2017-10-25 01:38:36

标签: javascript

在现代浏览器上下文中的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,以便将函数参数传递给新的实现?
  3. 您可以在此处停止阅读而不会遗漏与上述问题相关的任何内容

    背景/背景

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

    我最近发现replaces the Date object无法使用Angular 1.x的任何解决方案,因为Angular有一个isDate方法可以调用 - 你猜对了 - Object.prototype.toString.call(dateCandidate)如果不是返回确切的字符串[object Date],然后任何角度日期格式代码都不起作用。

    有问题的角色代码:

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

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

1 个答案:

答案 0 :(得分:1)

您输入了错误的参数,callbindapply的第一个参数是context,而不是被调用的函数' s参数

此代码:

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"}" ;

def password():
    userPassword = str(input("Type Your Password: "))
    if userPassword == storedPassword:
        print 'Access Granted'
    else:
        print 'Access Denied'
        password()