一.对象属性和方法的简洁表示法
对象属性
const foo = 'bar';
const baz = {foo};
baz // {foo: "bar"}
对象方法
const o = {
method() {
return "Hello!";
}
};
二.对象属性名和方法表达式
属性名和方法名表达式不能和简洁表示法同时使用,否则报错
属性名表达式
let lastWord = 'last word';
const a = {
'first word': 'hello',
[lastWord]: 'world'
};
a['first word'] // "hello"
a[lastWord] // "world"
a['last word'] // "world"
方法表达式
let obj = {
['h' + 'ello']() {
return 'hi';
}
};
obj.hello() // hi
三.属性的可枚举性和遍历
Object.getOwnPropertyDescriptor(obj, ‘foo’);能获取对象的属性的描述,enumerable代表是否可被枚举
let obj = { foo: 123 };
Object.getOwnPropertyDescriptor(obj, 'foo');
// {
// value: 123,
// writable: true,
// enumerable: true,
// configurable: true
// }
目前es6的5中对象的属性遍历方法
(1)for ... in
遍历自身属性和继承的可枚举属性,但是不包括Symbol属性
(2)Object.keys(obj)
遍历自身的属性,但是不包含不可枚举的和Symbol属性
(3)Object.getOwnPropertyNames(obj);
遍历自身的属性,包含不可枚举属性,但是不包含Symbol属性
(4)Object.getOwnPropertySymbols()
遍历自身的所有Symbol属性
(5)Reflect.ownKeys(obj)
遍历自身的所有属性,包含不可枚举的,包含Symbol属性
四.对象中方法的name属性
类似于函数的name属性
const person = {
sayName() {
console.log('hello!');
},
};
person.sayName.name // "sayName"
对象的方法上使用getter或者setter,则name属性不在这个方法上,而是在该方法的描述对象上
const obj = {
get foo() {},
set foo(x) {}
};
obj.foo.name
// TypeError: Cannot read property 'name' of undefined
const descriptor = Object.getOwnPropertyDescriptor(obj, 'foo');
descriptor.get.name // "get foo"
descriptor.set.name // "set foo"
对象方法是Symbol值,则方法的name返回Symbol的描述
const key1 = Symbol('description');
const key2 = Symbol();
let obj = {
[key1]() {},
[key2]() {},
};
obj[key1].name // "[description]"
obj[key2].name // ""
五.对象的super关键字
指向当前对象的原型对象,只能用在对象的方法中
const proto = {
foo: 'hello'
};
const obj = {
foo: 'world',
find() {
console.log(this.foo);
return super.foo;
}
};
// es6提供的用于设置对象的原型的方法,下面的是将obj的原型对象设置为proto
Object.setPrototypeOf(obj, proto);
obj.find()
// world
// "hello"
下面的是反例
// 报错,没在对象方法中使用
const obj = {
foo: super.foo
}
// 报错,没在对象方法中使用
const obj = {
foo: () => super.foo
}
// 报错,没在对象方法中使用
const obj = {
foo: function () {
return super.foo
}
}
六.对象的扩展运算符
1.解构赋值
let { x, y, ...z } = { x: 1, y: 2, a: 3, b: 4 };
x // 1
y // 2
z // { a: 3, b: 4 }
- 等号右边不能是undefined和null,否则报错
- 解构赋值必须是最后一个,否则报错
- 解构赋值是浅拷贝
- 解构赋值不能拷贝对象的原型属性
// 浅拷贝
let obj = { a: { b: 1 } };
let { ...x } = obj;
obj.a.b = 2;
x.a.b // 2
// 不拷贝原型对象属性
let o1 = { a: 1 };
let o2 = { b: 2 };
o2.__proto__ = o1;
let { ...o3 } = o2;
o3 // { b: 2 }
o3.a // undefined
// 另一个不拷贝原型对象属性的例子,变量x是单纯的解构赋值,所以可以读取对象o继承的
属性;变量y和z是扩展运算符的解构赋值,只能读取对象o自身的属性,所以变量z可以赋值
成功,变量y取不到值。
const o = Object.create({ x: 1, y: 2 });
o.z = 3;
let { x, ...{ y, z } } = o;
x // 1
y // undefined
z // 3
2.扩展运算符
let z = { a: 3, b: 4 };
let n = { ...z };
n // { a: 3, b: 4 }
完整的克隆一个对象,包含原型对象,可以使用如下方法,推荐第二种和第三种
// 写法一
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)
)
七.对象的方法
(1)Object.is(p1,p2);
行为类似 === 号
不同如下:
+0 === -0 //true
NaN === NaN // false
Object.is(+0, -0) // false
Object.is(NaN, NaN) // true
(2)Object.assign(target,p1,p2),
将p1和p2等对象合并到target对象中,但是使用微信公众号项目注意,这里会不支持,被坑过
具体用法和用处请看文档: http://es6.ruanyifeng.com/#docs/object#Object-assign
(3)Object.getOwnPropertyDescriptors() ,
返回指定对象的所有自身属性的描述对象,不包括继承属性,
const obj = {
foo: 123,
get bar() { return 'abc' }
};
Object.getOwnPropertyDescriptors(obj)
// { foo:
// { value: 123,
// writable: true,
// enumerable: true,
// configurable: true },
// bar:
// { get: [Function: get bar],
// set: undefined,
// enumerable: true,
// configurable: true } }
(4)Object.setPrototypeOf(),Object.getPrototypeOf()
Object.setPrototypeOf方法的作用与proto相同,用来设置一个对象的prototype对象,返回参数对象本身。它是 ES6 正式推荐的设置原型对象的方法。
“__proto__”标准上只有浏览器才会部署,因此要采用上述2中方法设置原型对象
function Rectangle() {
// ...
}
const rec = new Rectangle();
Object.getPrototypeOf(rec) === Rectangle.prototype
// true
Object.setPrototypeOf(rec, Object.prototype);
Object.getPrototypeOf(rec) === Rectangle.prototype
// false
(5)Object.keys(),Object.values(),Object.entries()
Object.keys() , 返回对象自身的可遍历属性的键数组,不包含继承属性,供for … of使用
Object.values() , 返回对象自身的可遍历属性的键数组,不包含继承属性,供for … of使用
Object.entries() , 返回对象自身的可遍历属性的键数组,不包含继承属性,供for … of使用
const obj = { foo: 'bar', baz: 42 };
Object.entries(obj)
// [ ["foo", "bar"], ["baz", 42] ]