FED实验室 - 专注WEB端开发和用户体验

Javascript中检测数组和对象

点滴Javascript 煦涵 2808℃ 0评论

在日常开发中,经常会见到检测一个变量是数组(特殊的对象)还是普通的对象,以便我们执行不同的动作。看下面一个例子:

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实验室」的微信公众号二维码,欢迎扫描关注:

FED实验室

行文不易,如有帮助,欢迎打赏!

赞赏支持or喜欢 (0)or分享 (0)
捐赠共勉
发表我的评论
取消评论

表情

Hi,您需要填写昵称和邮箱!

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址
(2)个小伙伴在吐槽