解釋:獲取對對象屬性的描述對象。
let obj = { foo: 123 };
console.log(Object.getOwnPropertyDescriptor(obj, 'foo'))
顯示結果:
{ configurable: true enumerable: true value: 123 writable: true __proto__: Object }
目前,有四個操作會忽略enumerable為 false 的屬性。
- for...in循環:只遍歷對象自身的和繼承的可枚舉的屬性。
- Object.keys():返回對象自身的所有可枚舉的屬性的鍵名。使用這個遍歷對象!
- JSON.stringify():只串行化對象自身的可枚舉的屬性。
- Object.assign(): 忽略enumerable為false的屬性,只拷貝對象自身的可枚舉的屬性
Object.getOwnPropertyDescriptor(Object.prototype, 'toString').enumerable // false Object.getOwnPropertyDescriptor([], 'length').enumerable // false // toString和length屬性的enumerable都是false,因此for...in不會遍歷到這兩個繼承自原型的屬性。
const obj = { foo: 123, get bar() { return 'abc' } }; Object.getOwnPropertyDescriptors(obj) // { foo: // { value: 123, // writable: true, // enumerable: true, // configurable: true }, // bar: // { get: [Function: bar], // set: undefined, // enumerable: true, // configurable: true } }
// 格式 Object.setPrototypeOf(object, prototype) // 用法 const o = Object.setPrototypeOf({}, null); // 該方法等同於下面的函數。 function (obj, proto) { obj.__proto__ = proto; return obj; }
例子:
let proto = {}; let obj = { x: 10 }; Object.setPrototypeOf(obj, proto); proto.y = 20; proto.z = 40; obj.x // 10 obj.y // 20 obj.z // 40
-
如果第一個參數不是對象,會自動轉為對象。但是由於返回的還是第一個參數,所以這個操作不會產生任何效果。
-
由於undefined和null無法轉為對象,所以如果第一個參數是undefined或null,就會報錯。
4.
Object.getPrototypeOf(obj);
-
-
如果參數是undefined或null,它們無法轉為對象,所以會報錯。
5.
const proto = { foo: 'hello' }; const obj = { find() { return super.foo; } }; Object.setPrototypeOf(obj, proto); obj.find() // "hello" // 上面代碼中,對象obj的find方法之中,通過super.foo引用了原型對象proto的foo屬性。
JavaScript 引擎內部,super.foo等同於Object.getPrototypeOf(this).foo(屬性)或Object.getPrototypeOf(this).foo.call(this)(方法)。
例題:
const proto = { x: 'hello', foo() { console.log(this.x); }, }; const obj = { x: 'world', foo() { super.foo(); } } Object.setPrototypeOf(obj, proto); obj.foo() // "world" // 上面代碼中,super.foo指向原型對象proto的foo方法,但是綁定的this卻還是當前對象obj,因此輸出的就是world。
6.
var obj = { foo: 'bar', baz: 42 }; Object.keys(obj) // ["foo", "baz"]
Object.values方法返回一個數組,成員是參數對象自身的(不含繼承的)所有可遍歷(enumerable)屬性的鍵值。
const obj = { 100: 'a', 2: 'b', 7: 'c' }; Object.values(obj) // ["b", "c", "a"]
上面代碼中,屬性名為數值的屬性,是按照數值大小,從小到大遍歷的,因此返回的順序是b、c、a。
Object.entries方法返回一個數組,成員是參數對象自身的(不含繼承的)所有可遍歷(enumerable)屬性的鍵值對數組。
const obj = { foo: 'bar', baz: 42 }; Object.entries(obj) // [ ["foo", "bar"], ["baz", 42] ]
除了返回值不一樣,該方法的行為與Object.values基本一致。
遍歷語法的比較
對於數組來說:
for循環:最原始的寫法;
forEach:無法中途跳出forEach循環,break命令或return命令都不能奏效;
for...in...:遍歷可以獲得數組的鍵名,有以下缺點:
數組的鍵是number,而遍歷出來的鍵是字符串;
for...in循環不僅遍歷數字鍵名,還會遍歷手動添加其他鍵,甚至包括原型鏈上的鍵
在某些情況下,for...in循環會以任意順序遍歷鍵名
總之,for...in循環主要是為了遍歷對象而設計的,不適用於遍歷數組
for...of:遍歷數組
有着同for..in樣簡單語法,但是沒有for...in那些缺點,
不同於 forEach 方法,它可以與 break 、 continue 和 return 配合使用。
提供了遍歷所有數據結構的統一操作接口。