JavaScript对象有趣的方法

211 阅读2分钟

遍历对象

let obj = {
  "id": 20201208,
  "name": "sunshine",
  "username": "sunshiny",
  "hobby": ["music", "photography", "travel"],
  "address": {
    "street": "xx",
    "city": {
      "main": "KM",
      "minor": "SZ"
    }
  }
}

for...in遍历

for (let item in obj) {
  console.log(item);    //item是对象属性名 id, name, username, hobby, address
}

Object.keys()

  • 返回对象属性名组成的数组,然后可以使用数组的遍历方法进行遍历
Object.keys(obj)   //["id", "name", "username", "hobby", "address"]

Object.getOwnPropertyNames()

  • 返回对象属性名组成的数组
Object.getOwnPropertyNames(obj)   //["id", "name", "username", "hobby", "address"]

Reflect.ownKeys()

  • 返回对象属性名组成的数组。Reflect是ES6为操作对象而提供的新API
Reflect.ownKeys(obj)   //["id", "name", "username", "hobby", "address"]

判断对象是否具有某属性

let obj = { name: 'sunshine' }

in Operator

  • 如果指定属性在指定对象或其原型链中,则 in Operator 返回 true。
console.log('name' in obj); // true
  • 但是 in Operator有个缺点,那就是:如果属性来自对象的原型,它仍然会返回 true。

image.png

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

Reflect.has() 方法

  • 检查属性是否在对象中,它像 in Operator 一样作为函数工作。
Reflect.has(obj, 'name'); // true
Reflect.has(obj, 'toString'); // true

hasOwnProperty() 方法

  • hasOwnProperty() 方法返回一个布尔值,指示对象是否具有指定的属性作为它自己的属性(而不是继承它)。它可以正确地区分对象本身的属性和其原型的属性。
obj.hasOwnProperty('name'); // true
obj.hasOwnProperty('toString'); // false
  • 但是这种写法有个缺点,就是如果对象是用Object.create(null)创建的话,那么就不能用这个方法了。
let obj = Object.create(null);
obj.name = 'sunshine';

obj.hasOwnProperty('name'); 

/* 报错
VM33043:1 Uncaught TypeError: obj.hasOwnProperty is not a function
    at <anonymous>:1:5 
*/

Object.prototype.hasOwnProperty() 方法

  • 该方法是直接调用内置的有效用函数,跳过原型链。
let obj = Object.create(null);
obj.name = 'sunshine';

Object.prototype.hasOwnProperty.call(obj, 'name'); // true
Object.prototype.hasOwnProperty.call(obj, 'toString'); // false

Object.hasOwn() 方法

  • 由于前面的几种方式都不优雅,ES2022有一个新的提议:Object.hasOwn

如果指定的对象具有指定的属性作为其自己的属性,则 Object.hasOwn() 静态方法返回 true。如果属性被继承或不存在,则该方法返回 false。

Object.hasOwn(obj, 'name'); // true
Object.hasOwn(obj, 'toString'); // false