js의 순회 문제에 대한 자세한 설명

不言
풀어 주다: 2018-04-10 16:55:04
원래의
1436명이 탐색했습니다.

이 글에서 공유한 내용은 js의 순회 문제에 대한 자세한 설명입니다. 특정 참조 값이 있으므로 필요한 친구가 참조할 수 있습니다.

인스턴스 속성 및 프로토타입 속성

  • JavaScript의 객체 속성 데이터 속성접속자 속성의 두 가지 종류로 나뉩니다.

  • 특정 컨텍스트에 따라 속성은 프로토타입 속성인스턴스 속성으로 나눌 수 있습니다.

  • Prototype 속성 은 객체의 프로토타입 prototype에 정의된 속성이고, prototype 中的属性,

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

js的枚举

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

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

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

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

  • 使用Object.getOwnPropertyDescriptorObject.getOwnPropertyDescriptors两个方法获取对象的属性描述符

var obj = {
  name: '10',
  _age: 25,
  get age(){
    return this._age;
  },
  set age(age){
    if(age<1){
      throw new Error(&#39;Age must be more than 0&#39;);
    }else{
      this._age = age;
    }
  }
};

var des = Object.getOwnPropertyDescriptors(obj);
console.log(des);
/**
 * des: {
 *  name: {
 *    configurable: true,
 *    enumerable: true,
 *    value: "10",
 *    writable: true,
 *    __proto__: Object
 *  },
 *  _age: {
 *    configurable: true,
 *    enumerable: true,
 *    value: 25,
 *    writable: true,
 *    __proto__: Object
 *  },
 *  age: {
 *    configurable: true,
 *    enumerable: true,
 *    get: f age(),
 *    set: f age(age),
 *    __proto__: Object
 *  },
 *  __proto__: Object
 * }
*/
로그인 후 복사
value

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

writable

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

get

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

set

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

configurable

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

enumerable

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

  • name、_age拥有 &#39;configurable&#39;&#39;enumerable&#39;&#39;value&#39;&#39;writable&#39;四个属性描述符,统称数据描述符

  • age拥有&#39;configurable&#39;&#39;enumerable&#39;&#39;get&#39;&#39;set&#39;四个属性描述符,统称存取描述符

인스턴스 속성 JavaScript의 속성에는 값이 있을 뿐만 아니라 속성 탐색에 영향을 미치는 기능 중 하나가 Enumerable(속성 설명자)입니다. ), 값이 true이면 이 속성은 열거 가능하고, 그렇지 않으면
속성 설명자
var Animal = function({name=&#39;none&#39;, age=3, weight=80}={}){
  this.name = name;
  this.age = age;
  this.weight = weight;
}

Animal.prototype = {
  color: &#39;red&#39;
}

var dog = new Animal()

// 将weight属性设置为 不可枚举
Object.defineProperty(dog, &#39;weight&#39;, {
  enumerable: false
})

for(let i in dog){
  console.log(n);
}

//原型链上的color同样被遍历出来了,并且由于weight属性被设置成了enumerable:false,所以不可被遍历
//name 
//age 
//color
로그인 후 복사
로그인 후 복사
value
writable
get
이 속성의 접근자 함수(getter)를 가져옵니다. 접근자가 없으면 값은 정의되지 않음입니다. (접근자 또는 설정자가 포함된 속성 설명에만 유효합니다.)
set
configurable
열거 가능
은 생성된 함수에서 나온 다음 생성자에서 나옵니다. 인스턴스화 후에 새 속성이 추가되었습니다. js 열거형JavaScript에서 객체의 속성을 탐색하는 것은 그리 간단하지 않습니다. 주로 두 가지 이유 때문입니다. JavaScript의 객체는 일반적으로 특정 프로토타입 체인에 있으며 일부 속성 상속에서 시작됩니다. 또는 여러 상위 계층 프로토타입
속성 설명자는 주로 두 가지로 나타납니다. 양식: 데이터 설명자액세스 설명자. Object.getOwnPropertyDescriptorObject.getOwnPropertyDescriptors 메서드를 사용하여 개체의 속성 설명자를 가져옵니다. 이 속성의 값(데이터 속성 설명자에만 유효함)writable 속성이 다음으로 설정된 경우 false인 경우 해당 속성은 "쓰기 불가능"하다고 합니다. 재할당할 수 없습니다.
속성의 설정자 함수(setter)를 가져옵니다. setter가 없으면 값은 정의되지 않음입니다. (접근자 또는 설정자가 포함된 속성 설명에만 유효)configurable 속성은 개체의 속성을 삭제할 수 있는지 여부를 나타내며 쓰기 가능은 제외됩니다. code> 속성 이외의 속성을 수정할 수 있는지 여부입니다. 열거 가능은 개체의 속성을 for...in 루프 및 Object.keys에서 사용할 수 있는지 여부를 정의합니다. () code>가 열거됩니다. name 및 _age에는 'configurable', 'enumerable', 'value', 'writable'</code가 있습니다. > >총칭하여 <code>데이터 설명자age라고 하는 4개의 속성 설명자에는 'configurable', 'enumerable', 가 있습니다. >' get', 'set' 4개의 속성 설명자(총칭하여 액세스 설명자
🎜🎜🎜 classification🎜🎜'configurable'🎜라고 함) 🎜 '열거 가능'🎜🎜'값'🎜🎜'쓰기 가능'🎜🎜'get'🎜🎜'set'🎜🎜🎜🎜🎜🎜데이터 설명자🎜🎜예🎜🎜예🎜🎜예🎜🎜 응🎜🎜 아니야🎜🎜아니야 🎜🎜🎜🎜액세스 설명자🎜🎜yes🎜🎜yes🎜🎜no🎜🎜no🎜🎜yes🎜🎜yes🎜🎜🎜🎜

对象的属性描述符,可以通过Object.definePropertyObject.defineProperties来修改(configurabletrue的条件下)

常用的遍历方法

for...in...遍历

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

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

Chrome Opera 的 JavaScript 解析引擎遵循的是新版 ECMA-262 第五版规范。因此,使用 for-in 语句遍历对象属性时遍历书序并非属性构建顺序。而 IE6 IE7 IE8 Firefox Safari 的 JavaScript 解析引擎遵循的是较老的 ECMA-262 第三版规范,属性遍历顺序由属性构建的顺序决定。
for-in 语句无法保证遍历顺序,应尽量避免编写依赖对象属性顺序的代码。如果想顺序遍历一组数据,请使用数组并使用 for 语句遍历。
var Animal = function({name=&#39;none&#39;, age=3, weight=80}={}){
  this.name = name;
  this.age = age;
  this.weight = weight;
}

Animal.prototype = {
  color: &#39;red&#39;
}

var dog = new Animal()

// 将weight属性设置为 不可枚举
Object.defineProperty(dog, &#39;weight&#39;, {
  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循环可以使用的范围包括数组、SetMap 结构、某些类似数组的对象(比如arguments对象、DOM NodeList 对象)、Generator 对象,以及字符串。

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

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

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

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

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

Object.prototype.objCustom = function() {}; 
Array.prototype.arrCustom = function() {};

let iterable = [3, 5, 7];
iterable.foo = &#39;hello&#39;;

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
}
로그인 후 복사
Object.prototype.objCustom = function() {};
Array.prototype.arrCustom = function() {}; 

let iterable = [3, 5, 7]; 
iterable.foo = &#39;hello&#39;;
로그인 후 복사

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

for (let i in iterable) {
  console.log(i); // 0, 1, 2, "foo", "arrCustom", "objCustom" 
}
로그인 후 복사

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

for (let i in iterable) {
  if (iterable.hasOwnProperty(i)) {
    console.log(i); //  0, 1, 2, "foo"
  }
}
로그인 후 복사

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

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值作为名称的属性)组成的数组,此方法不会获取原型链上的属性。

var Animal = function({name=&#39;&#39;, age=1, weight=70}={}){
  this.name = name;
  this.age = age;
  this.weight = weight;
}

Animal.prototype = {
  type: &#39;Animal&#39;
}

var dog = new Animal()

// 将height属性设置为 不可枚举
Object.defineProperty(dog, &#39;weight&#39;, {
  enumerable: false
})

var keys = Object.getOwnPropertyNames(dog);
console.log(keys)
// [&#39;name&#39;, &#39;age&#39;, &#39;weight&#39;]
로그인 후 복사

结语

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

相关推荐:

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

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

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

위 내용은 js의 순회 문제에 대한 자세한 설명의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

관련 라벨:
원천:php.cn
본 웹사이트의 성명
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.
인기 튜토리얼
더>
최신 다운로드
더>
웹 효과
웹사이트 소스 코드
웹사이트 자료
프론트엔드 템플릿