Javascript `代理`this[toString]`与`this[Symbol.toStringTag]`

Javascript `代理`this[toString]`与`this[Symbol.toStringTag]`,javascript,google-chrome,tostring,symbols,proxy-pattern,Javascript,Google Chrome,Tostring,Symbols,Proxy Pattern,它只发生在#toString上,并且只发生在我(尝试)通过missing方法访问它时,比如trap 我有一个名为createIterface的工厂,它返回具有大量方法的对象的代理。在这些方法中,我有#toString()和#id()#id返回一个接口,该接口与调用者具有相同的属性,工作正常#toString应将我的接口转换为字符串,但失败。 所有接口的方法-包括#id和#toString-都在#符号内。对于(“u方法”)属性。我这样做是为了调试的目的: const __methods = Sym

它只发生在
#toString
上,并且只发生在我(尝试)通过
missing方法访问它时,比如
trap

我有一个名为
createIterface
的工厂,它返回具有大量方法的对象的
代理。在这些方法中,我有
#toString()
#id()
#id
返回一个
接口
,该接口与调用者具有相同的属性,工作正常
#toString
应将我的
接口
转换为字符串,但失败。 所有
接口
的方法-包括
#id
#toString
-都在
#符号内。对于(“u方法”)
属性。我这样做是为了调试的目的:

const __methods = Symbol.for("__methods");

const missingMethod = ({
    get: (obj, prop) => Reflect.has(obj, prop)
        ? Reflect.get(obj, prop)
        : Reflect.has(obj[__methods], prop)
            ? Reflect.get(obj[__methods], prop)
            : console.log(`No #${prop} property exists.`)
});

const createInterface = (...props) => new Proxy({
    ...props,
    [__methods]: {
        id: () => createInterface (...props),
        toString: () => `Interface(${ props.toString() })`
    }
}, missingMethod);

const interface = createInterface(0, 1, 2);
interface.id(); //works
interface.toString(); //error: Cannot convert a Symbol value to a string
抛出的错误表示它不能(隐式地)将符号转换为字符串(这是真的)。事情是,
#toString
不是一个符号。然而,有一个名为
#toStringTag
的著名符号定义了
对象#toString()
行为。当我用其他方法实现它时,我的
#toString()
被忽略,
接口
返回
'[object]'

// see code above
const createInterface = (...props) => new Proxy({
    ...props,
    [__methods]: {
        id: () => createInterface (...props),
        toString: () => `Interface(${ props.toString() })`,
        [Symbol.toStringTag]: () => "Interface"
    }
}, missingMethod);

const interface = createInterface(0, 1, 2);
interface.id(); //works
interface.toString(); //bug: '[object Object]'
如果我在
\u方法
之外对方法进行编码,则一切正常:

// see code above
const createInterface = (...props) => new Proxy({
    ...props,
    id: () => createInterface (...props),
    toString: () => `Interface(${ props.toString() })`
}, missingMethod);

const interface = createInterface(0, 1, 2);
const copycat = interface.id();
interface.toString() === copycat.toString(); //true
除了一些奇怪的浏览错误(我运行的是最新的Chrome,在本文撰写之日是v.71.0.3578.98),我不知道为什么会发生这种情况,也不知道如何修复它


有人能帮忙吗?

问题是首先要访问
接口.toString

get: (obj, prop) => Reflect.has(obj, prop)
    ? Reflect.get(obj, prop)
    : Reflect.has(obj[__methods], prop)
        ...
您希望
接口。toString
在这里通过三元结构,并使用
\u方法
,但是
Reflect.has(obj,'toString')
将由于
Object.prototype.toString
而计算为
true
。然后,在对象上调用该函数再次执行代理的getter操作,搜索要调用的
#toStringTag
。getter遍历了所有的ternaries,但什么也没找到,所以它抛出了一条线

console.log(`No #${prop} property exists.`)
因为
prop
是一个符号,不能连接

一种可能是使用不从
对象继承的对象。prototype

const obj = Object.create(null);
const createInterface = (...props) => new Proxy(
  Object.assign(obj, {
    ...props,
    [__methods]: {
      id: () => createInterface (...props),
      toString: () => `Interface(${ props.toString() })`
    }
  })
  , missingMethod
);
const\uuuu methods=Symbol.for(“\uuu methods”);
常量丢失方法=({
get:(obj,prop)=>Reflect.has(obj,prop)
?反射。获取(obj,道具)
:Reflect.has(obj[\uu方法],prop)
?Reflect.get(obj[\uu方法],prop)
:console.log(`No#${prop}属性不存在。`)
});
const obj=Object.create(null);
const createInterface=(…道具)=>新代理(
对象分配(obj{
…道具,
[方法]:{
id:()=>createInterface(…道具),
toString:()=>`接口(${props.toString()})`
}
})
,丢失方法
);
const interface=createInterface(0,1,2);
interface.id()//作品
log(interface.toString())