对象的拓展
Json对象
1.js对象(数组) --> json对象(数组)
JSON.stringify(obj/arr)
2.json对象(数组) --> js对象(数组)
JSON.parse(json)
以上两个方法是ES5提供的.Json字符串就只有两种: Json对象,json数组
Object的拓展
一.对象属性的简洁写法
1.属性简写
var foo = "bar";
var baz = { foo };
baz; // { foo: "baz" }
// 等价于
var baz = { foo: foo };
ES6允许在对象中只写属性名,不写属性值。这是,属性值等于属性名所代表的变量。
function f(x, y) {
return { x, y };
// 等价于: return { x: x, y: y };
}
f(1, 2); // {x: 1, y: 2}
2.方法简写
var obj = {
method() {
return "yuan is an animal";
}
}
// 等价于
var obj = {
method: function() {
return "yuan is an animal";
}
}
二、属性名表达式
1.属性名定义方法:
let monkey = {
['yuan']() {
return "yuan is a monkey";
}
}
monkey.yuan(); // yuan is a monkey"
三、Object.is()
因在ES5中,并不能处理比较两个值是否严格相等,对于NaN,+0,-0等并不能做出严格相等来判断。
Object.is() 这个方法就是来弥补上述的缺陷的:
+0 === -0; // true
NaN === NaN; // false
Object.is(+0, -0); // false
Object.is(NaN, NaN); // true
三、Object.assign()
1.基本用法
定义:将源对象(sourceN,不知一个源对象)的所有可枚举属性复制到目标对象上(target)。 使用方式:Object.assign(target, source1, source2, ..., sourceN) 使用方式:Object.assign(target, source1, source2, ..., sourceN)
let target = { x: 1};
let s1 = { y: 2 };
let s2 = { z: 3 };
Object.assign(target, s1, s2); // {x: 1, y: 2, z: 3}
2、注意点
(1)、如果目标对象与源对象用同名属性,或多个源对象具有同名属性,则后面的属性会覆盖前面的属性:
let target2 = { x: 1};
let s3 = { x: 3, y: 2 };
let s4 = { y: 4, z: 3 };
Object.assign(target2, s3, s4); // {x: 3, y: 4, z: 3}
(2)如果参数不是对象,则会先转成对象,在返回:
typeof Object.assign(3); // "object"
(3)、若参数中有undefined 或者 null,这两个参数不能放在目标对象的位置,否则会报错:
Object.assign(undefined); // Cannot convert undefined or null to object at Function.assign (<anonymous>)
Object.assign(null); // Cannot convert undefined or null to object at Function.assign (<anonymous>)
(4)、除了字符串会以数组的形式复制到目标对象上,其他值都不会产生效果:
let a1 = 'yuan';
let a2 = true;
let a3 = 11;
let a4 = NaN;
Object.assign({}, a1, a2, a3, a4); // {0: "y", 1: "u", 2: "a", 3: "n"}
(5)、Object.assign()这个方法是对对象引用的复制,即是浅复制,而不是深复制。这里需要规避同名属性替换带来的问题:
var obj1 = { a: { b: 3, c: 4 } };
var obj2 = { a: { b: "yuan" } } ;
Object.assign(obj1, obj2); // { a: { b: "yuan" } }
obj1.a.b; // "yuan"
3、基本用途
(1)、给对象添加属性
class Geo {
constructor(x, y) {
Object.assign(this, x, y);
}
}
(2)、给对象添加方法
Object.assig(SomeClass.prototype, {
someMethod(arg1, arg2) { ... },
anotherMethod() { ... }
})
(3)、克隆对象
function clone(originObj) {
return Object.assign({}, originObj); // 将原始对象复制给空对象
}
(4)、合并多个对象
const mergeObjs = {
(target, ...sources) => Object.assign(target, ...sources);
}
(5)、为属性指定默认值
const DEFAULTS = {
logleve: 0,
outputFormat: 'html'
};
function processContent(options) {
retrun Object.assign({}, DEFAULTS, options);
}
四 Object.keys(),Object.values(),Object.entries()
1.Object.keys(obj)
返回一个数组,是由参数对象自身的(不含继承)所有可遍历属性的键名:
1.Array对象
/* Array 对象 */
let arr = ["a", "b", "c"];
console.log(Object.keys(arr));
// ['0', '1', '2']
2.Object 对象
let obj = { foo: "bar", baz: 42 },
keys = Object.keys(obj);
// CCAC: Chrome Console Auto Copy
copy(keys);
// ["foo","baz"]
3. 类数组 对象
let obj = { 0 : "a", 1 : "b", 2 : "c"};
console.log(Object.keys(obj));
// ['0', '1', '2']
4.类数组 对象, 随机 key 排序 (遵循上述的属性的遍历顺序)
let anObj = { 100: 'a', 2: 'b', 7: 'c' };
console.log(Object.keys(anObj));
// ['2', '7', '100']
2、Object.values(obj)
返回一个数组,是由参数对象自身的(不含继承)所有可遍历属性的键值:
普通对象
var obj = { foo: "bar", baz: 42 };
console.log(Object.values(obj)); // ['bar', 42]
类数组对象
var obj = { 0: 'a', 1: 'b', 2: 'c' };
console.log(Object.values(obj)); // ['a', 'b', 'c']
随机键值的类数组对象 (遵循上述的属性的遍历顺序)
var an_obj = { 100: 'a', 2: 'b', 7: 'c' };
console.log(Object.values(an_obj)); // ['b', 'c', 'a']
参数是非对象会转变成对象
console.log(Object.values("foo")); // ['f', 'o', 'o']
3.Object.entries(obj)
返回一个数组,是由参数对象自身的(不含继承)所有可遍历属性的键值对数组:
对象
const obj = { foo: 'bar', baz: 42 };
console.log(Object.entries(obj)); // [ ['foo', 'bar'], ['baz', 42] ]
类数组对象
const obj = { 0: 'a', 1: 'b', 2: 'c' };
console.log(Object.entries(obj)); // [ ['0', 'a'], ['1', 'b'], ['2', 'c'] ]
随机键值的类数组对象 (遵循上述的属性的遍历顺序)
const anObj = { 100: 'a', 2: 'b', 7: 'c' };
console.log(Object.entries(anObj)); // [ ['2', 'b'], ['7', 'c'], ['100', 'a'] ]
getFoo 是不可枚举属性
const myObj = Object.create({}, { getFoo: { value() { return this.foo; } } });
myObj.foo = 'bar';
console.log(Object.entries(myObj)); // [ ['foo', 'bar'] ]
参数是非对象会转变成对象
console.log(Object.entries('foo')); // [ ['0', 'f'], ['1', 'o'], ['2', 'o'] ]
优雅地遍历键值
const obj = { a: 5, b: 7, c: 9 };
for (const [key, value] of Object.entries(obj)) {
console.log(`${key} ${value}`); // "a 5", "b 7", "c 9"
}
Object.entries() 的另一个用处:将对象转为真正的Map 数据结构:
var obj = { foo: "bar", baz: 42 };
var map = new Map(Object.entries(obj));
console.log(map); // Map { foo: "bar", baz: 42 }
五、属性的遍历
在ES6 中有五种方法来遍历对象的属性:
1、for...in
返回对象自身的和继承的可枚举属性(不含 Symbol 属性)。
2、Object.keys(ob)
返回一个数组,包括对象自身的(不含继承)所有可枚举属性(不含 Symbol 属性)。
3、Object.getOwnPropertyNames(obj)
返回一个数组,包括自身的所有属性(不含Symbol属性,但包括不可枚举属性)。
4、Object.getOwnPropertySymbols(obj)
返回一个数组。包含对象自身的所有 Symbol 属性。
5、Object.ownKeys(obj)
返回一个数组,包含对象所有的属性.。
以上五种方法都遵循同样的遍历顺序:
(1)、首先遍历所有属性名为数值的属性,按数字排序;
(2)、其次遍历所有属性名为字符串的属性,按照生成时间排序;
(3)、最后遍历所有属性名为 Symbol 的属性,按照生成时间排序。