【发布时间】:2019-04-11 18:23:09
【问题描述】:
function createElement (type, { attrs = {}, children = [] }) {
if (Object.prototype.toString.call(arguments[1]) !== '[object Object]') {
throw Error('The options argument must be an object');
}
return {
type,
attrs,
children
}
}
我有一个函数,它接受两个参数:一个字符串和一个对象。在函数声明中,我通过解构解包对象的值。
当谈到确保第二个参数是一个对象时,我知道我可以做这个检查:Object.prototype.toString.call(arguments[1] !== 'object Object')。
但如果null 或undefined 作为参数传递,则会出现此错误:Uncaught TypeError: Cannot destructure property 'attrs' of 'undefined' or 'null'.。这是可以理解的,因为null 和undefined 不能被强制转换为对象。我能做些什么来防止这种情况发生?
如果 array、number 等作为第二个参数传递,则不会引发错误,因为它们可以被强制转换,然后我可以在函数体中处理这些值。在处理null 或undefined 时,函数中的代码永远不会执行。
// expected behaviour
createElement('div', []); // Uncaught Error: The options argument must be an object
createElement('div', function(){}); // Uncaught Error: The options argument must be an object
createElement('div', false); // Uncaught Error: The options argument must be an object
createElement('div', new Date()); // Uncaught Error: The options argument must be an object
createElement('div', 4); // Uncaught Error: The options argument must be an object
// unwanted behaviour
createElement('div', null); // Uncaught TypeError: Cannot destructure property `attrs` of 'undefined' or 'null'
createElement('div', undefined); // Uncaught TypeError: Cannot destructure property `attrs` of 'undefined' or 'null'
编辑以提供最终解决方案:阅读 cmets 后,似乎唯一的解决方案是允许引发异常或解构函数体中的代码并处理错误。这是我选择的解决方案:
createElement (type, opts) {
if (arguments[1] !== undefined && Object.prototype.toString.call(opts) !== '[object Object]') {
throw Error('The options argument must be an object');
}
const { attrs = {}, children = [] } = opts || {};
return {
type,
attrs,
children
}
}
【问题讨论】:
-
请添加一些调用示例和想要的结果。
-
如果你想处理错误为什么不尝试捕获?
-
完成 - 感谢您强调这一点。
-
@JRK try/catch 将不起作用,因为在我描述的场景中,函数体中的代码永远不会执行。
-
你为什么还要提防这个?你想抛出一个异常,对吧?