javascript - 为什么会出现`undefined`
PHPz
PHPz 2017-04-11 11:05:02
0
4
349

题目要求:

我们有一个对象数组,里面存储着通讯录。
函数 lookUp 有两个预定义参数:firstName值和prop属性 。
函数将会检查通讯录是否存在一个联系人的firstName属性等于firstName值,还会检查对应联系人是否存在 prop属性。
如果它们都存在,函数返回prop属性对应的值。
如果firstName 值不存在,返回 "No such contact"。
如果prop 属性不存在,返回 "No such property"。

我的代码:

//Setup
var contacts = [
    {
        "firstName": "Akira",
        "lastName": "Laine",
        "number": "0543236543",
        "likes": ["Pizza", "Coding", "Brownie Points"]
    },
    {
        "firstName": "Harry",
        "lastName": "Potter",
        "number": "0994372684",
        "likes": ["Hogwarts", "Magic", "Hagrid"]
    },
    {
        "firstName": "Sherlock",
        "lastName": "Holmes",
        "number": "0487345643",
        "likes": ["Intriguing Cases", "Violin"]
    },
    {
        "firstName": "Kristian",
        "lastName": "Vos",
        "number": "unknown",
        "likes": ["Javascript", "Gaming", "Foxes"]
    }
];


function lookUp(firstName, prop){
// Only change code below this line
  var name = false;
  var pro = false;
  for(var i =0 ;i<4;i++){
    if((contacts[i].firstName==firstName) && (contacts[i][prop]!=="")){
      name = true;
      pro = true;
      return contacts[i][prop];
    }
   
    else{
     if(contacts[i].firstName==firstName)
       name = true;
     if(contacts[i][prop]!=="")
       pro = true;
    }
  }
  if(!name)
    return "No such contact";
  if(!pro)
    return "No such property";
// Only change code above this line
}

// Change these values to test your function
lookUp("Akira", "address");

为什么不能通过?
在浏览器中调试的时候,在属性为空的判断这会返回undefined,如果我这种判断是错的,但是前面的if((contacts[i].firstName==firstName) && (contacts[i][prop]!==""))又正确。
很无语

PHPz
PHPz

学习是最好的投资!

全部回复(4)
洪涛

你这个问题的关关键原因是你的判断 == "" 只能匹配变量值是 "" 的情况,但实际上 undefinednull 也应该作为无属性的情况处理,这里可以假设只有字符串值的情况出现,直接用 !contacts[i][prop] 来判断。

另外,你的代码里有些地方可以优化,我注释出来了

function lookUp(firstName, prop) {
    // Only change code below this line
    var name = false;
    var pro = false;

    // [J.Fan> 这里为什么是 i < 4,对于一个已知数组数据,
    // 应该用 contacts.length 来取其长度以适应数据的变化
    for (var i = 0; i < 4; i++) {
        if ((contacts[i].firstName == firstName) && (contacts[i][prop] !== "")) {
            name = true;
            pro = true;

            // 这里既然已经 return 了,就不会执行到下面对 name 和 pro 的判断
            // 所以上面两句赋值可以不要
            return contacts[i][prop];
        } else {
            // 再次判断 contacts[i].firstName == firstName
            // 可以考虑单独把这个条件提出来作为外层 if,内层再进行 contacts[i][prop] 的判断
            if (contacts[i].firstName == firstName)
                name = true;
            if (contacts[i][prop] !== "")
                pro = true;
        }
    }
    if (!name)
        return "No such contact";
    if (!pro)
        return "No such property";
    // Only change code above this line
}

如果我来写,我会想到用数组的 filter 方法先按 firstName 把对象找出来再来取其属性

// es6 语句
function lookUp2(firstName, prop) {
    // filter 过程出来是一个数组,取其第 0 个元素就是找到的第一个对象
    // 如果没有对象被找到,返回 [],其第 0 个元素是 undefined,不会引发异常
    const contact = contacts.filter(c => c.firstName === firstName)[0];
    if (!contact) {
        return "No such contact";
    }
    
    // 当 contact[prop] 是 undefined、null或 "" 等可以判 false 的值时
    // 通过 || 运算符,取第二个操作数
    return contact[prop] || "No sch property";
}

这里用 filter 是一个全遍历的过程,对于数组数据量大的时候,效率会比较低。实际用 find() 更合适,找到即返回该对象,否则返回 undefined。不过 find() 还在试验阶段,所以当前我没有使用它。如果使用它,代码会是这样

// es6
function lookUp3(firstName, prop) {
    // find 返回的是找到的对象本身或 undefined,而不是数组,所以不需要再取 [0]
    const contact = contacts.find(c => c.firstName === firstName);
    if (!contact) {
        return "No such contact";
    }
    return contact[prop] || "No sch property";
}
小葫芦

因为Akira的确是没有address这个属性的啊

if((contacts[i].firstName==firstName) && && (contacts[i][prop]!==""))又正确。

这个本来就正确啊..因为undefined本来就不等于""

建议:
(contacts[i][prop]!=="") 改成(contacts[i][prop])

Ty80

修改:

`
if(contacts[i][prop]){
   pro = true;
}
`
大家讲道理

离开了看见

热门教程
更多>
最新下载
更多>
网站特效
网站源码
网站素材
前端模板
关于我们 免责声明 Sitemap
PHP中文网:公益在线PHP培训,帮助PHP学习者快速成长!