有没有一种方法可以对Javascript中的值调用toPrimitive?
为什么?
我在项目中使用代理。
function makeProxy(unknown_value) {
let proxy_target = ()=>{};
proxy_target.inner = unknown_value;
proxy_target.my_data = 123456;
return new Proxy(proxy_target, some_proxy_handler);
}
let proxied_value = makeProxy(<? something unknown ?>);
此代理将所有呼叫重定向到“内部”。 最终我被这样的事情感动了:
console.log(1+proxied_value);
此处有Javascript调用
(1)
proxied_value.get(proxy_target, Symbol.toPrimitive)
因为Javascript想要尝试将proxied_value转换为某个值以对其执行“ +”。对于proxy_target.inner,此操作是可能的
所以我想将此呼叫(1)重定向到:
(something like)
Object.toPrimitive( proxy_target.inner );
但是我发现没有办法直接调用toPrimitive。 有办法吗?
答案 0 :(得分:2)
不幸的是,基于在规范中搜索到的所有对ToPrimitive的引用,除了乏味地在javascript中重新实现该算法之外,似乎没有其他选择。
(大多数未经测试的)示例实现可能是:
const isPrimitive = ( value ) =>
value === null || ( typeof value !== 'object' && typeof value !== 'function' );
const toPrimitive = ( value, hint='default' ) => {
if( isPrimitive( value ) )
return value;
let method = value[ Symbol.toPrimitive ];
if( method != undefined ) { // using != instead of !== is intentional
let result = Reflect.apply( method, value, [ hint ] );
if( isPrimitive( result ) )
return result;
} else {
method = value[ hint === 'string' ? 'toString' : 'valueOf' ];
if( typeof method === 'function' ) {
let result = Reflect.apply( method, value, [] );
if( isPrimitive( result ) )
return result;
}
method = value[ hint === 'string' ? 'valueOf' : 'toString' ];
if( typeof method === 'function' ) {
let result = Reflect.apply( method, value, [] );
if( isPrimitive( result ) )
return result;
}
}
throw new TypeError("Cannot convert object to primitive value");
};
如果您不需要完全精确的ToPrimitive实现,而只需要在功能上与应用程序等效时,就可以简化实现为:
const toPrimitive = ( value, hint='default' ) => {
if( isPrimitive( value ) )
return value;
let method = value[ Symbol.toPrimitive ];
if( method != undefined ) // using != instead of !== is intentional
return Reflect.apply( method, value, [ hint ] );
method = value[ hint === 'string' ? 'toString' : 'valueOf' ];
if( typeof method === 'function' ) {
let result = Reflect.apply( method, value, [] );
if( isPrimitive( result ) )
return result;
}
method = value[ hint === 'string' ? 'valueOf' : 'toString' ];
if( typeof method === 'function' )
return Reflect.apply( method, value, [] );
return value;
};
并将抛出异常留给调用方。
您也许还可以将hint === 'string'
的情况优化为:
const toPropertyKey = ( value ) => {
return Reflect.ownKeys( { [value]: 0 } )[0];
};
因为我认为应该与ToPrimitive的所有用法兼容,并且提示在规范中目前为 ,但将来可能会中断(例如,如果将来的规范引入了类似于python3的bytes
类型的字节串)。我也不知道这实际上是否更快,需要测试。
答案 1 :(得分:0)
proxy_target[Symbol.toPrimitive]("number")
在get处理程序内部,您可以只使用Reflect:
get(...args) {
// ...
return Reflect.get(...args);
}