大括号里面,直接写入变量和函数,作为对象的属性和方法。
以下是属性简写:直接写属性名(就自己等于属性值)
const foo = 'bar';
const baz = {foo};
baz // {foo: "bar"}
// 等同于
const baz = {foo: foo};
以下是方法简写:直接省略冒号“:”和关键字function
const o = {
method() {
return "Hello!";
}
};
// 等同于
const o = {
method: function() {
return "Hello!";
}
};
案例:对象的简写:属性名=属性名:方法去除关键字和冒号
function getPoint() {
const x = 1;
const y = 10;
return {x, y};
}
getPoint()
// {x:1, y:10}
注意:对象中简写的函数不能当作构造函数使用
const obj = { f() { this.foo = 'bar'; } }; new obj.f() // 报错
但是在通过对象定义属性时候:允许通过表达式(被【】包裹的表达式作为属性名)
// 方法一
obj.foo = true;
// 方法二
obj['a' + 'bc'] = 123;
在创建字面量对象定义属性时候:ES5中只允许使用标识符进行作为属性名
var obj = {
// foo和zbc都是标识符
foo: true,
abc: 123
};
但是在ES6创建字面量定义属性:可以使用表达式(一定被【】或者‘’包裹起来)
let lastWord = 'last word';
const a = {
'first word': 'hello',
[lastWord]: 'world'
};
a['first word'] // "hello"
a[lastWord] // "world"
a['last word'] // "world"
注意:属性名的表达式和简介表达式 同时使用会报错
// 报错
const foo = 'bar';
const bar = 'abc';
const baz = { [foo] };
// 正确
const foo = 'bar';
const baz = { [foo]: 'abc'};
for...in
for...in
循环遍历对象自身的和继承的可枚举属性
Object.keys(obj)
返回一个数组,包括对象自身的(不含继承的)所有可枚举属性
this
关键字总是指向函数所在的当前对象,ES6 又新增了另一个类似的关键字super
,指向当前对象的原型对象注意:只能用在对象的方法之中,用在其他地方都会报错。
const proto = {
foo: 'hello'
};
const obj = {
foo: 'world',
find() {
return super.foo;
}
};
Object.setPrototypeOf(obj, proto);
obj.find() // "hello"
// 报错
const obj = {
foo: super.foo
}
// 报错
const obj = {
foo: () => super.foo
}
// 报错
const obj = {
foo: function () {
return super.foo
}
}
let { x, y, ...z } = { x: 1, y: 2, a: 3, b: 4 };
x // 1
y // 2
z // { a: 3, b: 4 }
解构赋值时候:
- 如果等号右边是
undefined
或null
,就会报错,因为它们无法转为对象- 解构赋值必须是最后一个参数,否则会报错。
let { ...z } = null; // 运行时错误
let { ...z } = undefined; // 运行时错误
解构赋值的拷贝是浅拷贝,即如果一个键的值是复合类型的值(数组、对象、函数)、那么解构赋值拷贝的是这个值的引用,而不是这个值的副本
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
比较两个值是否严格相等:
- 弥补NaN不等于自身问题
- 弥补-0不等于+0问题
Object.is('foo', 'foo')
// true
Object.is({}, {})
// false
对象的合并
注意:属性同名后面覆盖前面
const target = { a: 1, b: 1 };
const source1 = { b: 2, c: 2 };
const source2 = { c: 3 };
Object.assign(target, source1, source2);
target // {a:1, b:2, c:3}
//数组替换案例:
Object.assign([1, 2, 3], [4, 5])
// [4, 5, 3]
不是对象转为对象
typeof Object.assign(2) // "object"
实行的是浅拷贝:源对象某个属性的值是对象,那么目标对象拷贝得到的是这个对象的引用
常见用途
- 为对象添加属性
- 为对象添加方法
- 合并多个对象
- 克隆对象
function clone(origin) { return Object.assign({}, origin); }
如果一个对象本身部署了
__proto__
属性,该属性的值就是对象的原型
Object.getPrototypeOf({ __proto__: null })
// null
返回对象的键名返回为数组
var obj = { foo: 'bar', baz: 42 };
Object.keys(obj)
// ["foo", "baz"]
返回对象的键值返回为数组
const obj = { foo: 'bar', baz: 42 };
Object.values(obj)
// ["bar", 42]
返回对象的键值对返回为数组(嵌套)
const obj = { foo: 'bar', baz: 42 };
Object.entries(obj)
// [ ["foo", "bar"], ["baz", 42] ]
将数组嵌套转为对象
Object.fromEntries([
['foo', 'bar'],
['baz', 42]
])
// { foo: "bar", baz: 42 }