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 |