我是否应该始终使用instanceof和typeof来检查类型,例如
addRow : function(rowBefore) {
if(rowBefore instanceof Y.PopulateList.makeRow) {
this.allRows[row.toString()] = row;
row.altered = true;
Y.DragAndDrop.addNewDrag(row.rowDiv);
node.insert(row.rowDiv, 'after');
}
else {
console.log('not adding a makeRow');
}
},
或者是否可以忽略instanceof并相信该参数是有效的?我想知道因为这是我用过的唯一一种弱类型的语言,所以我不知道对象的类型并不总是很不舒服。
答案 0 :(得分:7)
所有情况都没有“正确”的答案。您的代码是否应该检查传入参数的类型取决于许多事情:
错误论证的可能性有多大?如果您是该功能的唯一客户,那么您可以决定您的功能是否需要保护自己免受您自己的编程错误的影响。如果它只是一个常规网页而不是该功能所属的特别重要的操作,则可能没有实际的理由来添加额外的代码,因为您可以控制确保正确使用此功能并传递适当的数据。另一方面,如果您正在编写许多人将使用的API,并且您的代码成功或遵循记录的错误路径非常重要,那么您很可能想要检查您的参数,以便您可以如果出现错误,可以100%预测路径..
如果您发现错误类型,您能做一些特别有用的事吗?如果您只是提前几行代码失败而且失败的方式与您没有任何不同如果您先检查了类型,那么很快就可以检查它。
该论证类型错误的后果是什么?如果后果(考虑到这个函数试图做的范围)并不那么重要,那么再次,它可能不值得额外的代码。另一方面,如果您希望完成一项重要的事务并且您绝对希望保护该操作免受可能意外错误的尽可能多的事情的影响,那么请务必检查每个参数的类型和范围。 / p>
数据来自哪里?如果数据来自最终用户或来自您无法控制的外部来源,那么您几乎总是想要检查在消费之前它。
许多不同开发人员会在很多情况下使用此代码吗?如果是这样,那么您可能希望尽早失败并使用正确的错误通知/调试消息来告诉你的功能的消费者在他们的开发中尽可能早地传递他们没有传递正确的数据。
你是否特意允许在参数列表中的给定位置传递不同类型的数据?在javascript中重载函数的一种常见方法是允许相同的函数采用几种不同的函数根据传递的内容,可能会做稍微不同的事情的参数类型。例如,jQuery一直这样做。如果你这样做,那么你将不得不检查参数类型,以区分允许调用此函数的不同方式。并且,在这样做时,您也可能发现不受支持的参数类型。
这个级别函数有多低/高?如果这是一个非常低级的函数,远离原始数据源,那么你可能想要进行类型检查在更接近原始数据源的更高级别,而不是在每个中间级别的函数调用中进行类型检查。
性能有多重要?如果这个函数的性能非常重要,因为它经常被调用并经常从循环结构中调用,那么你可能需要确保任何必要的类型检查在更高级别完成,而不是在您的一个瓶颈主要功能中完成。
这个函数的概念应该是严格的还是宽容的?根据它们的上下文的性质,如果一些函数尽可能地从任何输入中产生有用的值,那么它们就会更有用。给出。其他功能只有在它们完全按照预期完成时才有用,而不会试图将可疑数据强制转换成有用的东西。如果你正在计算一个胰岛素剂量,你真的不希望任何机会输入并不完全是你所解释的那样。但是,如果您正计算一个仅用于临时显示给最终用户的操作的时间估计,您可能只是尽力提供所提供的数据。
如果您想要对您的普通网页类型进行快速回答,我通常会检查来自外部来源或来自最终用户的所有数据,并且我将信任来自我自己代码的其他部分的数据。显然,中间存在许多灰色区域或某些不同类型的代码,这就是我让这些其他因素影响决策的地方。
答案 1 :(得分:6)
如果需要特定类型的东西,否则它会中断,然后检查其类型或将其强制转换为正确的类型。如果价值也是一个问题,你应该检查它的价值,显然。
这真的归结为你的论点的来源。如果它只是你的代码,那么如果你的代码写得正确,就没有理由检查类型。如果它是一个外部源(即你正在编写一个库函数或一个需要用户输入的函数),那么应该验证该参数。
简单地说,如果您有理由期望它们不是正确的类型,请检查类型。否则,只需编写代码,以免发生类型不匹配。
放弃动态输入会让你最终战斗语言而不是利用它。
答案 2 :(得分:4)
默认情况下,请相信。如果您必须快速失败,请仅检查类型。
在JS(以及Ruby和Python以及类似的动态类型语言)等语言中,duck typing非常常见。通过明确检查类型,您的函数变得不那么通用,因此不太有用。
举例来说,Array.prototype
中的许多标准JS函数虽然设计用于Array
个实例,但是有意编码为允许任何对象支持与要传入的数组相同的操作,即使实际上不是Array
。 (在ECMA-262 standard中搜索短语"故意通用"。)
答案 3 :(得分:2)
正确记录您的代码,其他将使用您的代码的开发人员将知道您的函数支持哪种类型。如果你没有提供可靠的后备,那么就不需要检查对象的类型,因为JavaScript会设法自己抛出错误。显然,如果最终安全退出程序没有数据丢失的危险。