1、属性的简洁表示
允许直接引入变量和函数,作为对象的属性和方法
var x = 1;
var obj = {
x,
getname(){},
*m(){}
};
//等同于
var obj = {
x: x,
getname: function(){}
m: function*(){}
}
2、属性名可以是变量或表达式
var name = 'firstname';
var obj = {
['a' + 'bc']: 123,
[name]: 'li',
['h' + 'ello'](){}
}
//得到
obj={
abc: 123,
firstname: 'li',
hello: function(){}
}
var obj = {
[{a:'a'}]: 'xxx'
}
//得到
obj={
[object Object]: "xxx"
}
注意如果属性值是对象,得到'[object Object]'
3、方法的name属性
类似函数的name
(new Function()).name //"anonymous"
var doSomething = function() {};
doSomething.bind().name //"bound doSomething"
var key1 = Symbol();
var key2 = Symbol('key2');
var obj = {
[key1](){}
[key2](){}
}
obj[key1].name //''
obj[key2].name //'[key2]'
key1对应的 Symbol 值有描述,key2没有
4、可枚举性
var obj = {a: 'a'}
Object.getOwnPropertyDescripty(obj, 'a');
//得到
{
value: 'a',
writable: true,
enumerable: true,
configurable: true
}
(1)for...in循环只遍历对象自身的和继承的可枚举的属性
(2)Object.keys()返回对象自身的所有可枚举的属性的键名
(3)JSON.stringify()只串行化对象自身的可枚举的属性
(4)Object.assign()忽略enumerable为false的属性,只拷贝对象自身的可枚举的属性
如果enumerable=false,以上会忽略该属性。只有for...in会返回继承的属性,其他三个方法都会忽略继承的属性,只处理对象自身的属性。
总的来说,操作中引入继承的属性会让问题复杂化,大多数时候,我们只关心对象自身的属性。所以,尽量不要用for...in循环,而用Object.keys()代替
5、属性的遍历
(1)for...in循环遍历对象自身的和继承的可枚举属性(不含 Symbol 属性)
(2)Object.keys返回一个数组,包括对象自身的(不含继承的)所有可枚举属性(不含Symbol属性)的键名
(3)Object.getOwnPropertyNames返回一个数组,包含对象自身的所有属性((不含Symbol属性,但是包括不可枚举属性)的键名
(4)Object.getOwnPropertySymbols返回一个数组,包含对象自身的所有Symbol属性的键名
(5)Reflect.ownKeys返回一个数组,包含对象自身的所有键名,不管键名是 Symbol或字符串,也不管是否可枚举
6、super
7、对象的扩展运算符
解构赋值 对象的解构赋值用于从一个对象取值,将目标对象自身的所有可遍历的(enumerable)、但尚未被读取的属性,分配到指定的对象上面
var {x, y, ...z} = {x: 1, y: 2, a:'a', b:'b'};
x //1
y //2
z {a: 'a', b: 'b'}
注意,解构赋值的拷贝是浅拷贝,即如果一个键的值是复合类型的值(数组、对象、函数)、那么解构赋值拷贝的是这个值的引用,而不是这个值的副本。
const o = Object.create({ x: 1, y: 2 });
o.z = 3;
let { x, ...newObj } = o;
let { y, z } = newObj;
x // 1
y // undefined
z // 3
扩展运算符的解构赋值,不能复制继承自原型对象的属性。变量y和z是扩展运算符的解构赋值,只能读取对象o自身的属性,所以变量z可以赋值成功,变量y取不到值
扩展运算符
// 等同于 {...Object(1)}
{...1} // {}
// 等同于 {...Object(true)}
{...true} // {}
// 等同于 {...Object(undefined)}
{...undefined} // {}
// 等同于 {...Object(null)}
{...null} // {}
{...'hello'}
// {0: "h", 1: "e", 2: "l", 3: "l", 4: "o"}
上面的例子只是拷贝了对象实例的属性,如果想完整克隆一个对象,还拷贝对象原型的属性,可以采用下面的写法
// 写法一
const clone1 = {
__proto__: Object.getPrototypeOf(obj),
...obj
};
// 写法二
const clone2 = Object.assign(
Object.create(Object.getPrototypeOf(obj)),
obj
);
// 写法三
const clone3 = Object.create(
Object.getPrototypeOf(obj),
Object.getOwnPropertyDescriptors(obj)
)