详解js中的遍历 问题

本篇文章给大家分享的内容是关于详解js中的遍历 问题,有着一定的参考价值,有需要的朋友可以参考一下

实例属性和原型属性

JavaScript中对象的属性分为两种: 数据属性访问器属性

根据具体的上下文环境的不同,又可以将属性分为: 原型属性实例属性

原型属性 是定义在对象的原型prototype 中的属性,

实例属性 一方面来自构造的函数中,然后就是构造函数实例化后添加的新属性。

js的枚举

JavaScript中遍历一个对象的属性并不太简单,主要有两个原因:

JavaScript中的对象通常都处在某个原型链中,它会从一个或多个的上层原型上继承一些属性

JavaScript中的属性不光有值,它还有一些除了值以外的其他特性,其中一个影响属性遍历的特性就是Enumerable(一个属性描述符) ,如果该值为 true ,则这个属性是可枚举的,否则反之

属性描述符

属性描述符 主要有两种形式:数据描述符和存取描述符。

使用Object.getOwnPropertyDescriptor 与 Object.getOwnPropertyDescriptors两个方法获取对象的属性描述符。

  1. var obj = {  name: '10',  _age: 25,  get age(){    return this._age;  },  set age(age){    if(age
    value

    该属性的值(仅针对数据属性描述符有效)

    writable

    writable属性设置为false时,该属性被称为“不可写”。它不能被重新分配。

    get

    获取该属性的访问器函数(getter)。如果没有访问器, 该值为undefined。(仅针对包含访问器或设置器的属性描述有效)

    set

    获取该属性的设置器函数(setter)。 如果没有设置器, 该值为undefined。(仅针对包含访问器或设置器的属性描述有效)

    configurable

    configurable特性表示对象的属性是否可以被删除,以及除writable特性外的其他特性是否可以被修改。

    enumerable

    enumerable定义了对象的属性是否可以在 for...in 循环和 Object.keys() 中被枚举。

登录后复制

name、_age拥有 ‘configurable’、’enumerable’、’value’、’writable’四个属性描述符,统称数据描述符

age拥有’configurable’、’enumerable’、’get’、’set’四个属性描述符,统称存取描述符

分类 ‘configurable’ ‘enumerable’ ‘value’ ‘writable’ ‘get’ ‘set’

数据描述符yesyesyesyesnono存取描述符yesyesnonoyesyes

对象的属性描述符,可以通过Object.defineProperty和Object.defineProperties来修改(configurable为true的条件下)

常用的遍历方法

for…in…遍历

遍历自身及原型链上所有可枚举的属性

使用 for…in 循环遍历对象属性时返回的属性会因为各个 浏览器不同 导致对象属性遍历的顺序有可能不是当初构建时的顺序。

Chrome Opera 的 JavaScript 解析引擎遵循的是新版 ECMA-262 第五版规范。因此,使用 for-in 语句遍历对象属性时遍历书序并非属性构建顺序。而 IE6 IE7 IE8 Firefox Safari 的 JavaScript 解析引擎遵循的是较老的 ECMA-262 第三版规范,属性遍历顺序由属性构建的顺序决定。

for-in 语句无法保证遍历顺序,应尽量避免编写依赖对象属性顺序的代码。如果想顺序遍历一组数据,请使用数组并使用 for 语句遍历。

  1. var Animal = function({name='none', age=3, weight=80}={}){  this.name = name;  this.age = age;  this.weight = weight;}Animal.prototype = {  color: 'red'}var dog = new Animal()// 将weight属性设置为 不可枚举Object.defineProperty(dog, 'weight', {  enumerable: false})for(let i in dog){  console.log(n);}//原型链上的color同样被遍历出来了,并且由于weight属性被设置成了enumerable:false,所以不可被遍历//name //age //color

登录后复制

for…of遍历

一个数据结构只要部署了Symbol.iterator属性,就被视为具有 iterator 接口,就可以用for…of循环遍历它的成员。也就是说,for…of循环内部调用的是数据结构的Symbol.iterator方法。

for…of循环可以使用的范围包括数组、Set 和 Map 结构、某些类似数组的对象(比如arguments对象、DOM NodeList 对象)、Generator 对象,以及字符串。

如果不太清楚iterator,请去看看阮一峰大神的这篇文章,里面关于for…of以及iterator都讲的非常详细!

其实for…of和for…in都是迭代一些东西,它们之间的主要区别在于它们的迭代方式。

for…in语句以原始插入顺序迭代对象的可枚举属性。

for…of 语句遍历可迭代对象定义要迭代的数据。

请仔细看以下实例,理解其中的区别

  1. Object.prototype.objCustom = function() {}; Array.prototype.arrCustom = function() {};let iterable = [3, 5, 7];iterable.foo = 'hello';for (let i in iterable) {  console.log(i); //  0, 1, 2, "foo", "arrCustom", "objCustom"}for (let i in iterable) {  if (iterable.hasOwnProperty(i)) {    console.log(i); //  0, 1, 2, "foo"  }}for (let i of iterable) {  console.log(i); //  3, 5, 7}

登录后复制

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

登录后复制

在这段代码里面,由于继承和原型链,对象iterable继承属性objCustom和arrCustom。

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

登录后复制

在这段代码里面,此循环仅以原始插入顺序记录iterable 对象的可枚举属性。它不记录数组元素3, 5, 7 或hello,因为这些不是枚举属性。但是它记录了数组索引以及arrCustom和objCustom(为何记录arrCustom和objCustom在本文for…in里面有讲过)。

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

登录后复制

hasOwnProperty()用来检查找到的枚举属性是不是对象自己的(即是不是继承的)

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

登录后复制

该循环迭代并记录iterable作为可迭代对象定义的迭代值,这些是数组元素 3, 5, 7,而不是任何对象的属性。

Object.keys遍历

Object.keys() 方法会返回一个由一个给定对象的自身可枚举属性组成的数组,数组中属性名的排列顺序和使用 for…in 循环遍历该对象时返回的顺序一致 (两者的主要区别是 一个 for-in 循环还会枚举其原型链上的属性)。

Object.getOwnPropertyNames()遍历

Object.getOwnPropertyNames()方法返回一个由指定对象的所有自身属性的属性名(包括不可枚举属性但不包括Symbol值作为名称的属性)组成的数组,此方法不会获取原型链上的属性。

  1. var Animal = function({name='', age=1, weight=70}={}){  this.name = name;  this.age = age;  this.weight = weight;}Animal.prototype = {  type: 'Animal'}var dog = new Animal()// 将height属性设置为 不可枚举Object.defineProperty(dog, 'weight', {  enumerable: false})var keys = Object.getOwnPropertyNames(dog);console.log(keys)// ['name', 'age', 'weight']

登录后复制

结语

这篇文章希望能让大家更加理解js中的遍历,写的不好多多见谅并指出!

相关推荐:

实例详解AngularJS遍历获取数组元素

JS遍历对象属性的方法示例

JS遍历页面所有对象属性及实现方法

以上就是详解js中的遍历 问题的详细内容,更多请关注【创想鸟】其它相关文章!

声明:本站所有文章,如无特殊说明或标注,均为本站原创发布。任何个人或组织,在未征得本站同意时,禁止复制、盗用、采集、发布本站内容到任何网站、书籍等各类媒体平台。如若本站内容侵犯了原著者的合法权益,可联系我们进行处理。

点点赞赏,手留余香

给TA打赏
共0人
还没有人赞赏,快来当第一个赞赏的人吧!
    编程技术

    node结合swig渲染摸板

    2025-3-8 13:59:45

    编程技术

    JavaScript创建对象

    2025-3-8 13:59:53

    0 条回复 A文章作者 M管理员
    欢迎您,新朋友,感谢参与互动!
      暂无讨论,说说你的看法吧
    个人中心
    购物车
    优惠劵
    今日签到
    私信列表
    搜索