属性的简洁表示法
ES6允许直接写入变量和函数,作为对象的属性和方法。
const foo = 'bar';
const baz = { foo };
console.log(baz); // {foo: "bar"}
ES6允许在对象之中直接写变量,这时,属性名为变量名,属性值为变量值
属性简写
function f(x, y) {
return { x, y }
};
console.log(f(2, 3)); //{x: 2, y: 3}
方法简写
const o = {
method() {
return 'Mr'
}
}
console.log(o.method()); //Mr
举个🌰
let birth = '2001/01/01';
const Person = {
name: 'Mr Zhang',
//等同于 birth:birth
birth,
//等同于hello:function(){}
hello() {
console.log('My name is' + this.name)
}
}
ES6 允许字面量定义对象时,用表达式作为对象的属性名,即把表达式放在方括号内。
let lastName = 'lastName'
const obj = {
'first Name': 'Mr',
[lastName]: 'Wang'
}
console.log(obj.lastName); // Wang
console.log(obj["first Name"]); // Mr
console.log(obj[lastName]); //Wang
表达式还可以用于定义方法名。
let obj2 = {
['h' + 'ello']() {
return 'Hi'
}
}
console.log(obj2.hello()); //Hi
super关键字
this关键字总是指向函数所在的当前对象,ES6又增加了一个类似的关键字super,指向当前对象的原型对象
const proto = {
foo: 'hello'
}
const obj = {
foo: 'Mr',
find() {
return super.foo;
}
}
Object.setPrototypeOf(obj, proto);
console.log(obj.foo);// Mr
上面代码中,对象obj.find()方法中,通过super.foo引入了原型对象proto的foo属性
需要注意的是,super关键字表示原型对象时,只能用在对象的方法中,用在其他地方会报错
JavaScript引擎内部,super.foo等同于Object.getPrototypeOf(this).foo或Object.getPrototypeOf(this).foo.call(this)
const proto = {
x: 'Hello',
foo() {
console.log(this.x)
}
}
const obj = {
x: 'world',
foo() {
//super.foo指向原型对象的proto的foo方法,但绑定的this却还是当前对象obj
super.foo();
}
}
Object.setPrototypeOf(obj, proto);
//所以输出是world
obj.foo(); // world
对象的解构赋值
对象的解构赋值用于从一个对象取值,相当于将目标对象自身的所有可遍历的,但尚未被读取的属性,分配到指定的对象上面。
let { x, y, ...z } = { x: 1, y: 2, a: 3, b: 4 };
console.log(x); // 1
console.log(y); // 2
console.log(z); // {a: 3, b: 4}
解构赋值的拷贝是浅拷贝,即如果一个键的值是复合类型的值(函数,对象,数组),那么解构赋值拷贝的这个是的引用,而不是副本。
let obj = { a: { b: 1 } }
let {...x } = obj;
obj.a.b = 2;
console.log(x.a.b); // 2
注意:ES6中规定,变量声明语句之中,如果使用解构赋值,拓展运算符后面必须是一个遍历名,而不能是一个解构赋值表达式。
拓展运算符
对象的拓展运算符(...)用于取出参数对象的所有可遍历属性,拷贝到当前对象之后
let z = { a: 3, b: 4 };
let n = {...z };
console.log(n);//{a: 3, b: 4}
数组是特殊的对象,所以对象的拓展运算符也可以用于数组
let foo = {...['a', 'b', '3'] };
console.log(foo);//{0: "a", 1: "b", 2: "3"}
上面的例子都是拷贝了对象实例的属性,如果想克隆一个对象,还拷贝对象原型的属性,可以采用下面写法
//写法1
const clone1 = {
_proto_: Object.getPrototypeOf(obj),
...obj
}
//写法2
const clone2 = Object.assign(
Object.create(Object.getPrototypeOf(obj)),
obj
)
//写法3
const clone3 = Object.create(
Object.getPrototypeOf(obj),
Object.getOwnPropertyDescriptor(obj)
)
还以可用来合并两个对象
let a = { A: "A" };
let b = { B: "B" };
let ab = {...a, ...b };
console.log(ab); // {A: "A", B: "B"}
如果自定义的属性,放到拓展运算符的后面,则拓展运算符内部的同名属性会被覆盖
let a = { a: 'a', b: 'b' }
let na = {...a, b: '1' };
console.log(na);//{a: "a", b: "1"}
如果放到前面,就是新对象的默认属性值
let a = { a: 'a', b: 'b' }
let na = { b: '1', c: 'c', ...a };
console.log(na); //{b: "b", c: "c", a: "a"}