js中几种遍历对象的方法,包括for.of、for
js中几种遍历对象的方法,包括for..of、for..in、Object.keys、Object.getOwnProperty,它们在使用场景方面各有不同。
js对象的属性中可直接用、可访问到的属性分为数据属性和访问器属性。
数据属性(实际存储属性值的属性)的四大特性:
{
- value: 属性值,
- writable: true/false, //控制是否可修改
- enumerable: true/false, //控制是否可被for in遍历
- configurable: true/false, //1. 控制是否可删除 2. 控制是否可修改前两个特性 3.一旦改为false不可逆
- }
-
访问器属性(不实际存储数据,专门提供对其它数据/变量的保护)的四大特性:
{
- get:function(){return this.隐藏属性;},
- set:function(val){
- //如果val符合条件
- this.隐藏属性=val
- //否则
- 报错
- },
- enumerable, configurable
-
for..in
返回的是所有能够通过对象访问的、可枚举的属性,既包括存在于实例中的属性,也包括存在于原型中的实例,不能保证属性按对象原来的顺序输出。(可枚举-自身-原型)
var obj = {a:1, b:2, c:3};
-
- for (var prop in obj) {
- console.log("obj." + prop + " = " + obj[prop]);
- }
- // Output:
- // "obj.a = 1"
- // "obj.b = 2"
-
Object.keys
用于获取对象自身所有的可枚举的属性值,但不包括原型中的属性,然后返回一个由属性名组成的数组。注意它同for..in一样不能保证属性按对象原来的顺序输出。(可枚举-自身)
// 数组
- var arr = ['a', 'b', 'c'];
- console.log(Object.keys(arr)); // console: ['0', '1', '2']
- // 类数组对象
- var obj = { 0: 'a', 1: 'b', 2: 'c' };
- console.log(Object.keys(obj)); // console: ['0', '1', '2']
- // 类数组对象-随机下标
- var anObj = { 100: 'a', 2: 'b', 7: 'c' };
- console.log(Object.keys(anObj)); // console: ['2', '7', '100']
- // 不可枚举属性getFoo
- var myObj = Object.create({}, {
- getFoo: {
- value: function () { return this.foo; }
- }
- });
- myObj.foo = 1;
-
Object.getOwnProperty
如果你想获取一个对象的所有属性js map 遍历对象数组,甚至包括不可枚举的,则可用该方法。其返回对象的所有自身属性的属性名组成的数组,但不会获取原型链上的属性。(可枚举&不可枚举-自身)
//获取不可枚举属性
- var my_obj = Object.create({}, {
- getFoo: {
- value: function() { return this.foo; },
- enumerable: false
- }
- });
- my_obj.foo = 1;
-
下面的例子演示了该方法不会获取到原型链上的属性:
function ParentClass() {}
- ParentClass.prototype.inheritedMethod = function() {};
- function ChildClass() {
- this.prop = 5;
- this.method = function() {};
- }
- ChildClass.prototype = new ParentClass;
- ChildClass.prototype.prototypeMethod = function() {};
- console.log(
- Object.getOwnPropertyNames(
- new ChildClass() // ["prop", "method"]
- )
-
for..of
es6新增方法,主要来遍历可迭代的对象(包括Array, Map, Set, arguments等),它主要用来获取对象value值,而for..in主要获取对象key值。
另外:可以由break, continue, throw 或return终止。在这些情况下,迭代器关闭。
let iterable = [10, 20, 30];
- for (let value of iterable) {
- value += 1;
- console.log(value);
- }
- // 11
- // 21
-
与for..in循环之间的区别:
Object.prototype.objCustom = function() {};
- Array.prototype.arrCustom = function() {};
- let iterable = [3, 5, 7];
- iterable.foo = 'hello';
- for (let i in iterable) {
- console.log(i); // 0, 1, 2, "foo", "arrCustom", "objCustom"
- }
- for (let i in iterable) {
- if (iterable.hasOwnProperty(i)) {
- console.log(i); // 0, 1, 2, "foo"
- }
- }
- for (let i of iterable) {
- console.log(i); // 3, 5, 7
-
小结
其实这几个方法之间的差异主要在属性是否可可枚举js map 遍历对象数组,是来自原型,还是实例。
开发中的实际应用
需求:将如下两个从后台不同端口获取的json对象数组整合处理成如下注释部分的json对象
var goodsSpecJSON = [{
- "SpecA": "颜色"
- }, {
- "SpecB": "容量"
- }, {
- "SpecC": "大小"
- }, {
- "SpecD": "尺寸"
- }, {
- "SpecE": "套餐"
- }];
- var goodsSpecList = [{
- c_id: 3133,
- costPrice: 0,
- discountPrice: 0,
- earn: 0,
- etime: null,
- flag: 0,
- goodsDetailCount: 199,
- goodsDetailId: "100PgQ2xy08121409mY27",
- goodsDetailInventory: 199,
- goodsDetailOff: 0,
- goodsDetailPic: "/upload/messageImage/1523281057461_Personal.jpg,/upload/messageImage/1523282906972_Personal.jpg,/upload/messageImage/1523283570897_Personal.jpg",
- goodsDetailPrice: 188,
- goodsDetailSpec: "",
- goodsId: "00Y1kR4r1029X822731o0",
- isHost: 0,
- managerEarn: 0,
- postage: 10,
- profit: 0,
- specA: "红色",
- specB: "32G",
- specC: "小",
- specD: "4.7寸",
- specE: "套餐一",
- unionEarn: 0,
- vipPrice: 0
- }, {
- c_id: 3134,
- costPrice: 0,
- discountPrice: 0,
- earn: 0,
- etime: null,
- flag: 0,
- goodsDetailCount: 199,
- goodsDetailId: "100PgQ2xy08121409mY27",
- goodsDetailInventory: 199,
- goodsDetailOff: 0,
- goodsDetailPic: "/upload/messageImage/1523281057461_Personal.jpg,/upload/messageImage/1523282906972_Personal.jpg,/upload/messageImage/1523283570897_Personal.jpg",
- goodsDetailPrice: 188,
- goodsDetailSpec: "",
- goodsId: "00Y1kR4r1029X822731o0",
- isHost: 0,
- managerEarn: 0,
- postage: 10,
- profit: 0,
- specA: "白色",
- specB: "64G",
- specC: "小",
- specD: "5寸",
- specE: "套餐二",
- unionEarn: 0,
- vipPrice: 0
- }, {
- c_id: 3135,
- costPrice: 0,
- discountPrice: 0,
- earn: 0,
- etime: null,
- flag: 0,
- goodsDetailCount: 199,
- goodsDetailId: "100PgQ2xy08121409mY27",
- goodsDetailInventory: 199,
- goodsDetailOff: 0,
- goodsDetailPic: "/upload/messageImage/1523281057461_Personal.jpg,/upload/messageImage/1523282906972_Personal.jpg,/upload/messageImage/1523283570897_Personal.jpg",
- goodsDetailPrice: 188,
- goodsDetailSpec: "",
- goodsId: "00Y1kR4r1029X822731o0",
- isHost: 0,
- managerEarn: 0,
- postage: 10,
- profit: 0,
- specA: "黑色",
- specB: "128G",
- specC: "小",
- specD: "4.7寸",
- specE: "套餐一",
- unionEarn: 0,
- vipPrice: 0
- }, {
- c_id: 3136,
- costPrice: 0,
- discountPrice: 0,
- earn: 0,
- etime: null,
- flag: 0,
- goodsDetailCount: 199,
- goodsDetailId: "100PgQ2xy08121409mY27",
- goodsDetailInventory: 199,
- goodsDetailOff: 0,
- goodsDetailPic: "/upload/messageImage/1523281057461_Personal.jpg,/upload/messageImage/1523282906972_Personal.jpg,/upload/messageImage/1523283570897_Personal.jpg",
- goodsDetailPrice: 188,
- goodsDetailSpec: "",
- goodsId: "00Y1kR4r1029X822731o0",
- isHost: 0,
- managerEarn: 0,
- postage: 10,
- profit: 0,
- specA: "蓝色",
- specB: "64GG",
- specC: "大",
- specD: "4.5寸",
- specE: "套餐二",
- unionEarn: 0,
- vipPrice: 0
- }];
- // var keys = {
- // '颜色': ['红色', '白色'],
- // '容量': ['8g', '16g', '32g', '64g'],
- // '尺寸': ['大', '小', '大'],
- // '套餐': ['套餐一', '套餐二', '套餐三']
- // };
- // //SKU,Stock Keeping Uint(库存量单位)
- // var sku_list = [{
- // 'attrs': '红色|16g|big|套餐二',
- // 'price': 120
- // }, {
- // 'attrs': '红色|8g|big|套餐一',
- // 'price': 10
- // }, {
- // 'attrs': '白色|16g|big|套餐二',
- // 'price': 28
- // }, {
- // 'attrs': '红色|64g|small|套餐三',
- // 'price': 220
- // }, {
- // 'attrs': '白色|32g|middle|套餐二',
- // 'price': 130
- // }, {
- // 'attrs': '红色|32g|big|套餐一',
- // 'price': 120
-
实现:主要利用Object.keys方法获取对象的key,value值,配上forEach循环实现最终想要的结果。
var keys = {};
- var sku_list = [];
- //原数据转换小写
- goodsSpecJSON = goodsSpecJSON.map(function (keyo) {
- var key = Object.keys(keyo)[0];
- var newkey = key.substring(0, 1).toLowerCase() + key.substring(1);
- var dic = {};
- dic[newkey] = keyo[key];
- return dic
- });
- //生成keys
- goodsSpecJSON.forEach(function (keyo) {
- var key = Object.keys(keyo)[0]; //['specA']
- var val = keyo[key]; //颜色
- if (!keys.hasOwnProperty(val)) {
- keys[val] = [];
- }
- var hash = {};
- goodsSpecList.forEach(function (item, i) {
- if (hash[item[key]] === undefined) {
- hash[item[key]] = true;
- keys[val].push(item[key]);
- }
- // if (keys[val].indexOf(item[key]) === -1) {
- // keys[val].push(item[key]);
- // }
- });
- });
- console.log(keys)
- //生成sku_list
- goodsSpecList.forEach(function (item) {
- var dic = {
- attrs: ''
- };
- goodsSpecJSON.forEach(function (keyo, j) {
- var key = Object.keys(keyo)[0];
- dic.attrs += item[key] + (j === goodsSpecJSON.length - 1 ? '' : '|');
- dic.price = item.goodsDetailPrice;
- dic.goodsDetailCount = item.goodsDetailCount;
- dic.goodsDetailId = item.goodsDetailId;
- });
- sku_list.push(dic);
- });
-
输出结果:
发表评论
热门文章
Spimes主题专为博客、自媒体、资讯类的网站设计....
仿制主题,Typecho博客主题,昼夜双版设计,可....
一款个人简历主题,可以简单搭建一下,具体也比较简单....
用于作品展示、资源下载,行业垂直性网站、个人博客,....
chenyu
4月7日
能不能支持deepseek