开发者社区> 云栖号资讯小哥> 正文

JS避坑-如何优雅地遍历对象

简介: 云栖号资讯:【点击查看更多行业资讯】在这里您可以找到不同行业的第一手的上云资讯,还在等什么,快来! 虽然已知for...in会遍历对象原型链上的属性,但心想用于字面量创建的对象应该没有什么大问题,于是便弃hasOwnProperty于不顾,最终被工单教做人了。
+关注继续查看

云栖号资讯:【点击查看更多行业资讯
在这里您可以找到不同行业的第一手的上云资讯,还在等什么,快来!


虽然已知for...in会遍历对象原型链上的属性,但心想用于字面量创建的对象应该没有什么大问题,于是便弃hasOwnProperty于不顾,最终被工单教做人了。在修复中总结了几个可以让遍历对象更加优雅的方法。

for...in踩坑复盘

能不能去掉hasOwnProperty?

for...in常用于遍历对象或者数组,比如

const obj = {
    a: 1,
    b: 2
};

for (const key in obj) {
    console.log(key, obj[key]);
}

// 输出
// a 1
// b 2

我们都知道for...in会遍历原型链上的属性,所以一般会结合hasOwnProperty来判断属性是否在对象自身上,而不是在原型链上。

for (const key in obj) {
    if (obj.hasOwnProperty(key)) {
        console.log(key, obj[key]);
    }
}

可每次都要多增加一行代码,多一个缩进,实在麻烦,能不能偷懒不加hasOwnProperty?

于是我动起了小心思,使用字面量创建的对象或者数组,不是类的实例,原型链上干干净净的,那遍历的时候也没必要判断了吧。于是就在遍历字面量对象时放心大胆地把hasOwnProperty抛弃了。

工单打脸

我负责的产品是API,用户在自己的页面应用中引入使用。某天,有用户反馈若同时引入我家API和另一个脚本库就会引发报错:

1

调试发现报错发生在:

2

renderLayers是一个数组,这里原本是遍历可渲染图层进行操作,而图层对象都有isHidden方法,为何报错呢?原因是用户另引入的脚本对Object、Array、String等基础引用类型的原型链做了扩展,加入了一些方法。所以在for...in遍历renderLayers时,也遍历到了addRange、clear这些属性,layer则赋值为一个function,而不是图层对象。

    for(var prop in source) {
        if(replace == false && dest[prop] != null) { continue; }
        dest[prop] = source[prop];
    }
    return dest;
};

Object.extend(Array.prototype, {
    addRange: function(items) {
        if(items.length > 0) {
            for(var i=0; i < items.length; i++) {
                this.push(items[i]);
            }
        }
    },
    clear: function() {
        this.length = 0;
        return this;
    },
    // ...
}, false);

避坑指南

如上所述,只能开始内部大清理,所有使用for...in而没有带hasOwnProperty的地方都需要进行改造。除了加上hasOwnProperty进行判断之外,视具体情况还可以使用以下方法,让你的代码更加优雅:

1. 数组尽量使用forEach进行遍历

比如引发报错的这一段,renderLayers是一个数组,直接使用forEach进行遍历即可:

3

2. 对象深拷贝尽量使用解构赋值

for...in可遍历对象属性实现一一赋值完成简单的对象深拷贝,这种操作可以用解构赋值来实现,更简单。

    return {...obj};
}

const obj = {
    a: 1
};
const objCopy = copy(obj);
console.log(objCopy);
// 输出:{a: 1}

3. 遍历键值可以结合Object.entries()和forEach

Object.entries()返回对象所有键值对组成的数组,再结合forEach即可完成遍历。若只是遍历对象的键或者值,可以使用Object.keys()和Object.values()。

在改造过程中,可以抽象出一个forIn方法作为工具函数,这样多处调用就可以省掉不少冗余代码啦~

    Object.entries(obj).forEach(entry => {
        callback(...entry);
    });
}

const obj = {
    a: 1
};
forIn(obj, (key, value) => {
    console.log(key, value);
});
// 输出:a 1

4. 若要使用break、return提前结束循环,需结合for...of

方法3虽好,但使用forEach没办法中断循环,这时候可以使用for...of,也是非常简洁的。

    a: 1,
    b: 2
};
for (let [key, value] of Object.entries(obj)) {
    if (value > 1) {
        break;
    }
    console.log(key, value);
}
// 输出:a 1

【云栖号在线课堂】每天都有产品技术专家分享!
课程地址:https://yqh.aliyun.com/live

立即加入社群,与专家面对面,及时了解课程最新动态!
【云栖号在线课堂 社群】https://c.tb.cn/F3.Z8gvnK

原文发布时间:2020-06-03
本文作者:多多洛爱学习
本文来自:“掘金”,了解相关信息可以关注“掘金”

版权声明:本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《阿里云开发者社区用户服务协议》和《阿里云开发者社区知识产权保护指引》。如果您发现本社区中有涉嫌抄袭的内容,填写侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。

相关文章
阿里云服务器如何登录?阿里云服务器的三种登录方法
购买阿里云ECS云服务器后如何登录?场景不同,大概有三种登录方式:
9059 0
Json字符串转换为java对象的各种实现方法【json_lib框架、Gson、org.json】
原创作品,允许转载,转载时请务必以超链接形式标明文章 原始出处 、作者信息和本声明。否则将追究法律责任。http://mengzhengbin520.blog.51cto.com/7590564/1283361 JSON(JavaScript Object Notation) 是一种轻量级的数据交换格式。
1222 0
阿里云服务器端口号设置
阿里云服务器初级使用者可能面临的问题之一. 使用tomcat或者其他服务器软件设置端口号后,比如 一些不是默认的, mysql的 3306, mssql的1433,有时候打不开网页, 原因是没有在ecs安全组去设置这个端口号. 解决: 点击ecs下网络和安全下的安全组 在弹出的安全组中,如果没有就新建安全组,然后点击配置规则 最后如上图点击添加...或快速创建.   have fun!  将编程看作是一门艺术,而不单单是个技术。
17986 0
阿里云服务器如何登录?阿里云服务器的三种登录方法
购买阿里云ECS云服务器后如何登录?场景不同,阿里云优惠总结大概有三种登录方式: 登录到ECS云服务器控制台 在ECS云服务器控制台用户可以更改密码、更换系.
24792 0
阿里云OSS对象存储服务上传失败问题之一
OSS是阿里云提供一个对象存储服务,有着稳定高效的特点,但在操作时有些问题还是必须要注意一下的
202 0
JavaScript 检查一个 JSON 对象中是否对存指这下的 Key
JavaScript 检查一个 JSON 对象中是否对存指定的 Key 太阳火神的美丽人生 (http://blog.csdn.net/opengl_es) 本文遵循“署名-非商业用途-保持一致”创作公用协议 转载请保留此句:太阳火神的美丽人生 -  本博客专注于 敏捷开发及移动和物联设备研究:iOS、Android、Html5、Arduino、pcDuino,否则,出自本博客的文章拒绝转载或再转载,谢谢合作。
860 0
bboss序列化cglib代理对象方法介绍
本文介绍bboss序列化cglib代理对象方法。经过cglib代理过的po类对象实例是原来po对象的子类对象,bboss在序列化这种对象时,需要经过特殊处理,否则会出现不可预知的错误,导致序列化失败,典型的例子就是hibernate查询操作返回的po对象就是cglib代理对象。
1013 0
+关注
云栖号资讯小哥
云栖号小编在此 ^o^
1403
文章
0
问答
文章排行榜
最热
最新
相关电子书
更多
OceanBase 入门到实战教程
立即下载
阿里云图数据库GDB,加速开启“图智”未来.ppt
立即下载
实时数仓Hologres技术实战一本通2.0版(下)
立即下载