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())代码>