js中每个对象的属性(js里万物皆属性,对象的属性也是对象)都有一个属性叫enumerable(可枚举性),这个属性true/false决定了该对象的属性是否可枚举(就是让一些方法访问到这个属性)。

js中哪些属性可枚举,哪些不可枚举?

1、可枚举属性:可以用obj.propertyIsEnumerable(prop)方法来判断,返回Boolean,但是通过原型链继承的属性除外。

2、js基本数据类型自带的原型属性不可枚举。

3、通过Object.defineProperty()方法指定enumeralbe为false的属性不可枚举。

针对第一点看这个:我们把可用propertyIsEnumberable()检测“lastName”,返回 true,检测“firstName”属性是通过原型链继承得到,所以检测的时候是 false,,说明检测继承得到的属性的时候会失效,所以用这个方法的时候要注意不可用于继承得到的属性是否是可枚举属性,for in 遍历可枚举属性的就不会发生这样的情况,大可方法去用for in 检测一个对象的可枚举属性。

针对第二点,看个例子:

var obj = new Object();
for(var key in obj) {
console.log("obj." + key + " = " + obj[key]);
}
// 输出为空

Object, Array, Number等,这种js内置的原型属性不可枚举。

再看第三个例子,定义了某个属性的enumberable属性为false,这样会让for in 也遍历不到,外界就无法对这个属性读写了:

function Person() {
this.name = "zhangsan";
}
Person.prototype = {
constructor: Person,
job: "student",
}; var person = new Person();
Object.defineProperty(person , "sex", {
value: "man",
enumerable: false // 定义了一个不可枚举的属性
});
for(var key in person) {
console.log("person." + key + " = " + person[key]);
}

结果我们只看到了name、constructor、job属性,我们定义的“sex”属性设置了enumberable: false,是不可枚举属性,所以for in 遍历不到。

不可枚举属性影响了for in 的结果,它还能影响什么操作结果呢?

Object.keys()和JSON.stringify

可见,这两种方法,Object.keys()只能返回对象本身具有的可枚举属性
JSON.stringify()只能返回对象本身的可枚举属性,并序列化为JSON字符串对象。

再来看看for in 和for of 循环的异同:

for...in,es5标准,遍历一个object所有的可枚举属性。遍历(当前对象及其原型上的)每一个属性名称key;循环起来无法终止;遍历数组时,会把数组序列号转成字符串:1,2,3 => ‘1’,‘2’,‘3’。

for...of,es6标准,提供了[Symbol.Interator]()方法遍历具有iterator接口(类似数组,比如ArrayMapSetStringTypedArray,arguments 对象等等)的数据结构,遍历(当前对象上的)每一个属性值value。只遍历具有数字键名的属性;可以终止循环breakcontinuereturn。

所以这里,你得弄明白什么是可枚举属性,什么是iterator接口???Iterator接口主要供for...of消费。

考别人的代码,说明自己的问题:

Object.prototype.objCustom = function() {};
Array.prototype.arrCustom = function() {}; let iterable = [3, 5, 7];
iterable.foo = 'hello';

每个对象将继承objCustom属性,并且作为Array的每个对象将继承arrCustom属性,因为将这些属性添加到Object.prototypeArray.prototype。由于继承和原型链,对象iterable继承属性objCustomarrCustom

for (let i in iterable) {
console.log(i); // 0, 1, 2, "foo", "arrCustom", "objCustom"
}

此循环仅以原始插入顺序记录iterable 对象的可枚举属性。它不记录数组元素357 或hello,因为这些不是枚举属性。但是它记录了数组索引以及arrCustomobjCustom

for (let i in iterable) {
if (iterable.hasOwnProperty(i)) {
console.log(i); // 0, 1, 2, "foo"
}
}

这个循环类似于第一个,但是它使用hasOwnProperty() 来检查,如果找到的枚举属性是对象自己的(不是继承的)。如果是,该属性被记录。记录的属性是0, 1, 2和foo,因为它们是自身的属性(不是继承的)。属性arrCustom和objCustom不会被记录,因为它们是继承的。

for (let i of iterable) {
console.log(i); // 3, 5, 7
}

该循环迭代并记录iterable作为可迭代对象定义的迭代值,只检测具有数组键名的属性值,这里就是数组元素 357,而不是任何不具有数据键名的属性。

for (var n of [1,2,3,4,5,6]) {
if (n > 3)
break;
console.log(n);
}

结果:

当n > 3的时候,终止of 循环。

所以for of使用起来比for in要更好一些。大家在工作中,多多使用,掌握好它。

js 对象可枚举属性以及for in 循环和for of 循环的更多相关文章

  1. js对象可扩展性和属性的四个特性(上)

    # js对象可扩展性和属性的四个特性(上) 一.前言 再次花时间回顾一下基础,毕竟要想楼建的好,地基就要牢固,嘻嘻! 在开始之前需要具备对prototype.__proto__.constructor ...

  2. js对象可扩展性和属性的四个特性(下)

    # js对象可扩展性和属性的四个特性(下) 一.前言 再次花时间回顾一下基础,毕竟要想楼建的好,地基就要牢固,嘻嘻! 在开始之前需要具备对prototype.__proto__.constructor ...

  3. 遍历js对象中的属性

    可以使用js自带的for in.也可以使用Ext JS中的方法来遍历js对象中的属性 代码如下: /** 遍历对象 */ var person = {name:'张泰松',age:28}; //js方 ...

  4. js对象—类型和属性特性

    前言 权威指南中摘要的,工作中用不到的,重要的js基础. 三类对象两类属性 内置对象(native object) 是由ECMScript规范定义的对象或者类.例如:函数,数组,日期,正则... 宿主 ...

  5. js 对象的_proto_属性 和函数的prototype属性分析

    bill是 Employee类型的实例,_proto_指向Employee.prototype Employee.prototype有一个constructor属性,指向Employee函数自身 fu ...

  6. 怎样判断JS对象中的属性

    // 如何在不访问属性值的情况下判断对象中是否存在这个属性 var obj = { a: 2 }; Object.defineProperty( obj, 'b', // 让 b 不可枚举 { enu ...

  7. [转]js对象中取属性值(.)和[ ]的区别

    原文地址:https://www.jianshu.com/p/6a76530e4f8f 今天在写js的过程中遇到这么一个问题,取一个对象的属性值,通过obj.keys怎么都取不出来,但是用obj[ke ...

  8. js对象数组按属性快速排序

    前一篇<关于selector性能比赛>中提到,目测觉得在$("div,p,a")这样有逗号时,sizzle耗时异常(600多个元素,花了200ms),说是它可能没有优化 ...

  9. js对象动态添加属性,方法

    1. 动态添加属性,方法 var object = new Object(); object.name = "name"; object.age = 19; >>> ...

随机推荐

  1. oracle11g参数的简单查看方法

    1.查看processes和sessions参数show parameter processesshow parameter sessions 2.修改processes和sessions值alter ...

  2. MySQL数据库(5)_MySQL数据库视图、触发器

    一.视图 视图是一个虚拟表(非真实存在),其本质是[根据SQL语句获取动态的数据集,并为其命名],用户使用时只需使用[名称]即可获取结果集,并可以将其当作表来使用. SELECT * FROM ( S ...

  3. 17南宁区域赛 J - Rearrangement 【规律】

    题目链接 https://nanti.jisuanke.com/t/19976 题意 给出 一个n 然后 给出 2*n 个数 可以重新排列成两行 然后 相邻的两个数 加起来 不能被三整除 可以上下相邻 ...

  4. IM协议

    四种协议英文全称与简称 1->IMPP(Instant Messaging And PresenceProtocol):即时信息和空间协议 2->PRIM(Presence and Ins ...

  5. 获取文件的MD5值,比较两个文件是否完全相同

    代码: public class MD5Test { public static void main(String[] args) { String s1 = MD5Test.MD5Operation ...

  6. css系列(6)css的运用(二)

        本节继续介绍css在html页面重的应用实例.     (1)div的border-style属性: none: 无样式 hidden: 除了同表格的边框发生冲突的时候,其它同none dot ...

  7. 20165101刘天野 2017-2018-2 《Java程序设计》第3周学习总结

    20165101刘天野 2017-2018-2 <Java程序设计>第3周学习总结 编程语言的几个发展阶段 类 构造方法与对象的创建 类与程序的基本结构 参数传值 对象的组合 实例成员与类 ...

  8. Java public class 与 class 区别

    在编写类的时候可以使用两种定义方式: public class 定义类 class 定义类 1.public class 定义类 如果一个类声明的时候使用了public class,则类名必须与文件名 ...

  9. Bootstrap3组件--2

    目录 1. 分页 2. 标签 3. 徽章 4. 巨幕 5. 页头 6. 缩略图 7. 警告框 8. 进度条 9. 列表组 10. 面板 11.Well 1. 分页 <!doctype html& ...

  10. centos_mysql5.6.21_rpm安装

    1.查看操作系统相关信息.[root@linuxidc ~]# cat /etc/issue CentOS release 6.5 (Final) Kernel \r on an \m [root@l ...