函数代理.toString()错误

时间:2016-07-08 06:03:34

标签: javascript ecmascript-6 tostring es6-proxy

我试图在函数代理上调用.toString()。

简单地创建一个函数代理并调用toString会导致“TypeError:Function.prototype.toString不是通用的”,将toString设置为返回原始源会导致“RangeError:超出最大调用堆栈大小”,但创建一个get forString的陷阱有效。

为什么简单地设置toString函数不起作用,但是设置get陷阱呢?

function wrap(source) {
 return(new Proxy(source, {}))
}
wrap(function() { }).toString()

function wrap(source) {
 let proxy = new Proxy(source, {})
 proxy.toString = function() {
  return(source.toString())
 }
 return(proxy)
}
wrap(function() { }).toString()

function wrap(source) {
 return(new Proxy(source, {
  get(target, key) {
   if(key == "toString") {
    return(function() {
     return(source.toString())
    })
   } else {
    return(Reflect.get(source, key))
} } })) }
wrap(function() { }).toString()

2 个答案:

答案 0 :(得分:1)

TypeError: Function.prototype.toString is not generic

Seems like Function.prototype.toString is not supposed to be called on Proxy.

proxy.toString = function() {

This assignment to proxy is passed to the source object as you do not have trap for assignment. If you check source.hasOwnProperty('toString') you'll get true. When you add get trap, you don't change toString method and don't add it into source object, so it works.

The other possible solution is

function wrap(source) {
  let proxy = new Proxy(source, {})
  proxy.toString = Function.prototype.toString.bind(source)
  return proxy
}

答案 1 :(得分:0)

我遇到了同样的问题。我终于发现这是this的一个问题。向您的处理程序添加get陷阱,如果它是this,则将代理对象绑定到代理属性function,并且它似乎正常工作:

function wrap(source) {
    return new Proxy(source, {
        get: function (target, name) {
            const property = target[name];
            return (typeof property === 'function') 
                ? property.bind(target)
                : property;
        }
    });
}

console.log(wrap(function () {}).toString());