Ways to iterate through objects

Relevant basic concepts

Property accessors

let obj = {
  a: 'b'
};

// dot notation
console.log(obj.a); // 'b'
// bracket notation
console.log(obj['a']); // 'b'
// through prototype chain
console.log(obj.toString, obj.toString === Object.prototype.toString); // ƒ toString() { [native code] } true

Check whether an property exists in object

  • in operator: returns true if the specified property is in the specified object or its prototype chain.
  • hasOwnProperty: returns a boolean indicating whether the object has the specified property as its own property (as opposed to inheriting it).
let obj = {
  a: 'b'
};

console.log('a' in obj); //true
console.log('toString' in obj); //true
console.log(obj.hasOwnProperty('a')); //true
console.log(obj.hasOwnProperty('toString')); //false

Object.defineProperty && Object.defineProperties - defines new or modifies existing properties directly on an object, returning the object.

let obj = {
  a: "b"
};

Object.defineProperties(obj, {
  c: {
    value: 'd'
  },
  e: {
    value: 'f'
  }
});
console.log(obj); // {a: "b", c: "d", e: "f"}

getter and setter

We can use getters and setters to generate computed property. E.g.

let people = {
  firstName: 'michael',
  lastName: 'zheng',
  get fullName() {
    return `${this.firstName} ${this.lastName}`
  },
  set fullName(val) {
    [this.firstName, this.lastName] = val.split(' ');
  }
}

console.log(people.firstName, people.lastName, people.fullName);
//"michael", "zheng", "michael zheng"
people.fullName = 'hello world';
console.log(people.firstName, people.lastName, people.fullName);
//"hello", "world", "hello world"

There are three ways to iterate through objects

let student = {
  name: "michael"
};

Object.defineProperties(student, {
  age: {
    enumerable: false,
    value: 18
  },
  grade: {
    value: 6,
    enumerable: true
  },
  sex: {
    value: "male",
    enumerable: false
  }
});

Object.prototype.x = "inherited";

In the sample above, we create an object student. student has following properties:

  • name: self enumerable property
  • age: self non-enumerable property
  • grade: self enumerable property
  • sex: self non-enumerable property

as well as a custom property from prototype chain:

  • x: enumerable

for...in iterates over enumerable properties of an object, including prototype chain.

for (let prop in student) {
  console.log(prop); //'name', 'grade', 'x'
}

for (let prop in student) { // self properties only
  if (student.hasOwnProperty(prop)) {
    console.log(prop); // 'name', 'grade'
  }
}

Object.keys returns an array of a given object's property names, only iterate through self enumerable properties.(i.e. not including prototype chain)

console.log(Object.keys(student)); // [‘name’, 'grade']

//check whether is plain object:
Object.keys(student).length === 0; //false

Object.keys({}).length === 0; //true

Object.getOwnPropertyNames returns an array of all self properties (including non-enumerable properties) found directly upon a given object.

// will not iterate through prototype chain
console.log(Object.getOwnPropertyNames(student)); // [‘name’, ‘age’, 'grade', 'sex']

Summarize

methods through prototype chain enumerable only
for...in Y Y
Object.keys N Y
Object.getOwnPropertyNames N N

你可能感兴趣的:(Ways to iterate through objects)