资讯专栏INFORMATION COLUMN

利用Object.keys遍历(forEach/map)对象数组,合并

浠ラ箍 / 1273人阅读

摘要:中几种遍历对象的方法,包括它们在使用场景方面各有不同。注意它同一样不能保证属性按对象原来的顺序输出。其返回对象的所有自身属性的属性名组成的数组,但不会获取原型链上的属性。另外可以由或终止。在这些情况下,迭代器关闭。

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"
// "obj.c = 3"
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;
console.log(Object.keys(myObj)); // console: ["foo"]
Object.getOwnProperty

如果你想获取一个对象的所有属性,甚至包括不可枚举的,则可用该方法。其返回对象的所有自身属性的属性名组成的数组,但不会获取原型链上的属性。(可枚举&不可枚举-自身)

//获取不可枚举属性
var my_obj = Object.create({}, {
  getFoo: {
    value: function() { return this.foo; },
    enumerable: false
  }
});
my_obj.foo = 1;

console.log(Object.getOwnPropertyNames(my_obj).sort()); // ["foo", "getFoo"]

下面的例子演示了该方法不会获取到原型链上的属性:

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
// 31

与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
}
小结

其实这几个方法之间的差异主要在属性是否可可枚举,是来自原型,还是实例。

开发中的实际应用

需求:将如下两个从后台不同端口获取的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);
});
console.log(sku_list)

输出结果:

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/94452.html

相关文章

  • es6 Map和set

    摘要:返回一个布尔值,表示该值是否为的成员。清除所有成员,没有返回值。该数组中的每一项也必须是数组,内部数组的首个项会作为键,第二项则为对应值。返回所有成员的遍历器需要特别注意的是,的遍历顺序就是插入顺序。 Js大部分历史时期都只存在一种集合类型,也就是数组类型。数组在 JS 中的使用正如其他语言的数组一样,但缺少更多类型的集合导致数组也经常被当作队列与栈来使用。数组只使用了数值型的索引,而...

    superPershing 评论0 收藏0
  • JavaScript中 for、for in、for of、forEach等使用总结

    摘要:等内置的方法和属性都是不可枚举的北京北京可以遍历可枚举但对象,包括不是它本身但存在于原型链上的属性。北京循环可迭代对象循环可迭代对象包括,,,,,类数组的对象比如对象对象以及生成器对象等。 在JavaScript中,我们经常需要去循环迭代方法操作数组对象等,常见等循环方法有 for、for in、for of、forEach等。 1.for循环 for循环是最基础常见的一种循环,圆括号...

    hlcc 评论0 收藏0
  • 【深度长文】JavaScript数组所有API全解密

    摘要:关于我的博客掘金专栏路易斯专栏原文链接深度长文数组全解密全文共字,系统讲解了数组的各种特性和。构造器构造器用于创建一个新的数组。中声明的数组,它的构造函数是中的对象。 本文首发于CSDN网站,下面的版本又经过进一步的修订。 关于 我的博客:louis blog 掘金专栏:路易斯专栏 原文链接:【深度长文】JavaScript数组全解密 全文共13k+字,系统讲解了JavaScrip...

    Mr_zhang 评论0 收藏0
  • JS中几种包含for的遍历方式

    摘要:区别遍历数组常用调用数组的每个元素,并将元素传递给回调函数这种循环的问题在于无法中途跳出循环,和命令不能奏效和都返回数组,返回的与原数组长度相同只返回符合条件的结果一个值和返回布尔值遍历对象所有的可枚举属性主要是为了遍历对象而设计的,不适 forEach,map,filter区别 forEach 遍历数组常用(调用数组的每个元素,并将元素传递给回调函数) let arr = [1,2...

    jcc 评论0 收藏0
  • es6 Map和WeakMap

    摘要:事实上,不仅仅是数组,任何具有接口且每个成员都是一个双元素的数组的数据结构都可以当做构造函数的参数。返回所有成员的遍历器需要特别注意的是,的遍历顺序就是插入顺序。转为转为,正常情况下,所有键名都是字符串。 Map JavaScript 的对象(Object),本质上是键值对的集合(Hash 结构),但是传统上只能用字符串当作键。这给它的使用带来了很大的限制。为了解决这个问题,ES6 提...

    sPeng 评论0 收藏0

发表评论

0条评论

浠ラ箍

|高级讲师

TA的文章

阅读更多
最新活动
阅读需要支付1元查看
<