JS对象及遍历

JS对象

一、创建对象

let obj = {};
let createObj = Object.create({});
let createNull = Object.create(null);

前两种是拥有原型的,第三种是一个没有任何携带的空对象,no properties,无指针无原型。

二、对象的判空

对象为空的判断,数据使用要做兼容防止报错,此处延伸一个try{}catch(){}的问题,在代码中用此方法来防止代码报错显然是愚蠢的,在代码中过多try{}catch(){}会造成程序的压力,会造成代码质量过低

//第一种判空方法
let obj = {};
let result = true;
for (let key in obj) {
  result = false;
}
//第二种判空方法
let obj = {};
Object.keys(obj).length === 0
//第三种判空方法
let obj = {};
JSON.stringify(obj) === '{}'

三、对象属性的顺序

JS 对象是简单的键值映射,因此,对象中属性的顺序是微不足道的, 在大多数情况下,不应该依赖它。
在ES5和早期标准中,根本没有指定属性的顺序。
然而,从ES6开始,属性的顺序是基于一个特殊的规则的,除非特指按照时间排序。

数字:当属性的类型时数字类型时,会按照数字的从大到小的顺序进行排序;
字符串:当属性的类型是字符串时,会按照时间的先后顺序进行排序;
Symbol:当属性的类型是Symbol时,会按照时间的先后顺序进行排序。
如果需要有序集合,建议将数据存储到数组或Set中。

JS遍历对象

1:使用Object.keys()遍历

Object.keys()方法可以将一个对象作为参数,然后把这个对象[key,value]对中的key值以数组的形式遍历出来。
返回一个数组,包括对象自身的(不含继承的)所有可枚举属性(不含Symbol属性)。
数组中属性名的排列顺序和使用 for…in 循环遍历该对象时返回的顺序一致 。如果对象的键-值都不可枚举,那么将返回由键组成的数组。

var obj = {
        a: 1,
        b: 2,
        c: 3
    }
//输出一个数组,数组元素是对象属性的集合
console.log(Object.keys(obj)); //['a','b','c']
//根据属性取属性对应的值
Object.keys(obj).forEach((key) => {
   console.log(obj[key])
})

在这里插入图片描述

来看看一个对象拥有自身和继承属性的例子,Object.keys()只返回自己的属性键:

let simpleColors = {
  nameA: 'a',
  nameB: 'b'
};
let natureColors = {
  colorC: 'green',
  colorD: 'yellow'
};
Object.setPrototypeOf(natureColors, simpleColors);
Object.keys(natureColors); // => ['colorC', 'colorD']
natureColors['nameA'];    // => 'a'
natureColors['nameB'];    // => 'b'

Object.setPrototypeOf() 方法——设置一个指定的对象的原型 ( 即内部[[Prototype]]属性)到另一个对象或 null。
Object.keys(natureColors)返回natureColors对象的自身可枚举属性键:[‘colorC’,‘colorD’]。
natureColors包含从simpleColors原型对象继承的属性,但是Object.keys()函数会跳过它们。

2:使用for…in循环:含可继承的属性

(循环可枚举的属性,自身的和继承的)(不含Symbol属性)

for(var i in obj){
    console.log(i)    //输出属性
    console.log(obj[i])    //输出属性对应的值
}

在这里插入图片描述
for…in不仅可以循环枚举自身属性还可以枚举原型链中的属性:

let enumerableKeys = [];
for (let key in natureColors) {
  enumerableKeys.push(key);
}
enumerableKeys; // => ['colorC', 'colorD', 'nameA', 'nameB']

enumerableKeys数组包含natureColors自身属性键: ‘colorC’和’colorD’。
for…in也遍历了从simpleColors原型对象继承的属性。

3:使用Object.getOwnPropertyNames()遍历:包括不可枚举的属性

返回一个数组,包含对象自身的所有属性(不含Symble属性),包括不可枚举属性

var obj = {
        a: 1,
        b: 2,
        c: 3
    }
console.log(Object.getOwnPropertyNames(obj)); //['a','b','c']
Object.getOwnPropertyNames(obj).forEach((key)=>{
	console.log(key,obj[key])     //a 1     b 2     c 3
})

4:Reflect.ownKeys:包括Symble属性

包含所有的(自身+继承的)

 var obj = {
        a: 1,
        b: 2,
        c: 3
    }
console.log(Reflect.ownKeys(obj)); //['a','b','c']
Reflect.ownKeys(obj).forEach((key)=>{
    console.log(key,obj[key])     //a 1     b 2     c 3
})

5:Object.getOwnPropertySymbols()

不常见,返回一个数组,包含给定对象所有自有的Symbol值的属性(包括不可枚举的Symbol值属性)。

6:Object.values() 和 Object.entries()

都是返回一个给定对象自身可枚举属性的键值对数组。

Object.values(natureColors); 
// => ['green', 'yellow']
Object.entries(natureColors);
// => [ ['colorC', 'green'], ['colorD', 'yellow'] ]
①Object.values()

Object.values()方法可以将一个对象作为参数,然后把这个对象[key,value]对中的value值以数组的形式遍历出来,返回一个给定对象自身的所有可枚举属性值的数组,值的顺序与使用for…in循环的顺序相同 ( 区别在于 for-in 循环枚举原型链中的属性 )。
例如,使用Object.keys()收集keys,然后通过 key 去获取对象取对应的值:

let meals = {
  mealA: 'Breakfast',
  mealB: 'Lunch',
  mealC: 'Dinner'
};
for (let key of Object.keys(meals)) {
  let mealName = meals[key];
  // ... do something with mealName
  console.log(mealName);
}
// 'Breakfast' 'Lunch' 'Dinner'

meal是一个普通对象。 使用Object.keys(meals)和枚举的for…of循环获取对象键值。
代码看起来很简单,但是,let mealName = meals[key] 可以进一步优化,如下:

let meals = {
  mealA: 'Breakfast',
  mealB: 'Lunch',
  mealC: 'Dinner'
};
for (let mealName of Object.values(meals)) {
  console.log(mealName);
}
// 'Breakfast' 'Lunch' 'Dinner'
②Object.entries()

返回一个给定对象自身可枚举属性的键值对数组,其排列与使用 for…in 循环遍历该对象时返回的顺序一致(区别在于 for-in 循环也枚举原型链中的属性)。
Object.entries() 返回键值对数组,如 [ [key1, value1], [key2, value2], …, [keyN, valueN] ]。
可能直接使用这些键值对不怎么方便,但可以通过数组解构赋值方式访问键和值就变得非常容易,如下所示:

let meals = {
  mealA: 'Breakfast',
  mealB: 'Lunch',
  mealC: 'Dinner'
};
for (let [key, value] of Object.entries(meals)) {
  console.log(key + ':' + value);
}
// 'mealA:Breakfast' 'mealB:Lunch' 'mealC:Dinner'

当普通对象要转换成 Map 时Object.entries() 就很有用,因为Object.entries() 返回的格式与Map构造函数接受的格式完全相同:(key,value)。

使用常规的Map构造函数可以将一个二维键值对数组转换成一个Map对象。

let greetings = {
  morning: 'Good morning',
  midday: 'Good day',
  evening: 'Good evening'
};
let greetingsMap = new Map(Object.entries(greetings));
greetingsMap.get('morning'); // => 'Good morning'
greetingsMap.get('midday');  // => 'Good day'
greetingsMap.get('evening'); // => 'Good evening'

Map 对象保存键值对。任何值(对象或者原始值) 都可以作为一个键或一个值
,Map提供了与Object.values()和Object.entries() 等效的方法(只是它们返回Iterators),以便为Map实例提取属性值或键值对:
Map.prototype.values() 等价于Object.values()
Map.prototype.entries() 等价于Object.entries()`

map是普通对象的改进版本,可以获取 map 的大小(对于普通对象,必须手动获取),并使用任意对象类型作为键(普通对象使用字符串基元类型作为键)。
让我们看看返回.values()和.entries()的map的方法:

[...greetingsMap.values()];
// => ['Good morning', 'Good day', 'Good evening']
[...greetingsMap.entries()];
// => [ ['morning', 'Good morning'], ['midday', 'Good day'], 
//      ['evening', 'Good evening'] ]

greetingsMap.values()和greetingsMap.entries()返回迭代器对象。若要将结果放入数组,扩展运算符…是必要的。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值