JavaScript模板字符串字面量在哪些值的情况下会抛出错误?
模板字面量
${value}抛出TypeError的场景与通用规则 已知的抛出场景
- 当
value为Symbol类型时:try { `${Symbol('nope')}` } catch (error) { console.error(`${error.name}: ${error.message}`) } - 当
value是通过Object.create(null)创建的无继承空对象时:try { `${Object.create(null)}` } catch (error) { console.error(`${error.name}: ${error.message}`) // 此时错误信息为"No default value" }
其他会抛出错误的场景
- 自定义对象重写了
[Symbol.toPrimitive]方法,且该方法主动抛出错误:const badObj = { [Symbol.toPrimitive]() { throw new Error('手动触发错误'); } }; try { `${badObj}` } catch (error) { console.error(`${error.name}: ${error.message}`); } - 自定义对象的
toString和valueOf方法均抛出错误:const errObj = { toString() { throw new TypeError('toString执行出错'); }, valueOf() { throw new TypeError('valueOf执行出错'); } }; try { `${errObj}` } catch (error) { console.error(`${error.name}: ${error.message}`); } - Proxy对象的
get陷阱在获取[Symbol.toPrimitive]、toString或valueOf方法时抛出错误:const proxy = new Proxy({}, { get(target, prop) { if (prop === Symbol.toPrimitive || prop === 'toString' || prop === 'valueOf') { throw new TypeError('Proxy拦截触发错误'); } return Reflect.get(target, prop); } }); try { `${proxy}` } catch (error) { console.error(`${error.name}: ${error.message}`); }
通用规则
模板字面量处理${value}时,内部会执行抽象操作ToString(value),其逻辑顺序为:
- 优先调用
value的[Symbol.toPrimitive]方法(传入参数"string"),若该方法抛出错误或返回非原始值,触发TypeError。 - 若不存在
[Symbol.toPrimitive]或返回非原始值,则调用toString()方法;若该方法不存在、抛出错误或返回非原始值,进入下一步。 - 最后调用
valueOf()方法;若该方法不存在、抛出错误或返回非原始值,最终抛出TypeError。
简言之:当value无法通过[Symbol.toPrimitive]、toString()、valueOf()任一方法返回有效原始值时,${value}就会抛出TypeError。
比如Symbol的[Symbol.toPrimitive]会直接抛出错误;Object.create(null)创建的对象没有继承这三个方法,自然无法返回有效原始值,因此触发错误。
内容的提问来源于stack exchange,提问作者Parzh
相关产品推荐
相关产品推荐

