#toString只有当我(尝试)通过missingMethod-like访问它时才会发生这种情况trap。
我有一个工厂createIterface,它返回一个Proxy具有大量方法的对象。在这些方法中,我有#toString()和#id()。#id返回interface与调用者具有相同属性的 a 并且工作得很好;#toString应该将 my 转换interface为字符串,但它失败了。所有interface的方法——包括#id和#toString——都在一个#Symbol.for("__methods")属性内。我这样做是为了调试目的:
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
抛出的错误表示它不能(隐式)将 Symbol 转换为 String(这是真的)。事情是,#toString不是一个符号。但是,有一个众所周知的 Symbol#toStringTag来定义Object#toString()行为。当我用其他方法实现它时,我#toString()被忽略并interface返回'[object 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]'
如果我对外部的方法进行编码,__methods则一切正常:
// 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),我不知道为什么会发生这种情况或如何修复它。
有人可以帮忙吗?