在日常开发中,经常会见到检测一个变量是数组(特殊的对象)还是普通的对象,以便我们执行不同的动作。看下面一个例子:
function getListOfMarathonNames (marathons) { if (marathons instanceof Object) { // Return an array containing the name of the only // marathon given. return [marathons.name]; } else if (marathons instanceof Array) { // Return an array containing all marathon names. return marathons.map(function(race) { return race.name; }); } }
上例代码咋一看比较合理,但是它存在一个大的bug,我们来做如下测试:
var londonMarathon = { name: "London Marathon", date: "April 13, 2014" }; //Outputs: ["London Marathon"] console.log(getListOfMarathonNames(londonMarathon)); var moreMarathons = [ { name: "New York City Marathon", date: "November 2, 2014" }, { name: "Chicago Marathon", date: "October 12, 2014" } ]; //Outputs: [undefined] console.log(getListOfMarathonNames(moreMarathons));
出现上述问题的原因是,我们上例的检测逻辑是相反的,数组本就是一个特殊的对象,代码直接进入到了if语句,而没有走else if。我们调整下原先的代码,则可以输出我们预期的结果,如下:
function getListOfMarathonNames (marathons) { if (marathons instanceof Array) { // Return an array containing all marathon names. return marathons.map(function(race) { return race.name; }); } else if (marathons instanceof Object) { // Return an array containing the name of the only // marathon given. return [marathons.name]; } } var londonMarathon = { name: "London Marathon", date: "April 13, 2014" }; //Outputs: ["London Marathon"] console.log(getListOfMarathonNames(londonMarathon)); var moreMarathons = [ { name: "New York City Marathon", date: "November 2, 2014" }, { name: "Chicago Marathon", date: "October 12, 2014" } ]; //Outputs: ["New York City Marathon", "Chicago Marathon"] console.log(getListOfMarathonNames(moreMarathons));
这个问题解决,但是这种情况还会出现在其他特殊的对象上,如Date、RegExp等,解决此种问题的一般规则是先检测特殊类型的对象,然后再检测普通对象。关于各类型对象的封装可以参考文章javascript 全类型检查type.js。
感谢您的阅读,文中不妥支持还望批评斧正。
下面是「FED实验室」的微信公众号二维码,欢迎扫描关注:

转载声明:
本文标题:Javascript中检测数组和对象
本文链接:http://www.fedlab.tech/archives/782.html,转载请注明转自FED实验室-专注WEB端开发和用户体验