对象
·
Yin灏
新方法
- assign 方法 (浅拷贝)
- 合并多个对象
与数组 concat
方法一样,assign 方法对于要合并多少个对象并没有限制,只要参数存在,就回去合并。
let obj1 = { x: 1 },
obj2 = { y: 1 },
obj3 = { z: 1 },
obj = Object.assign({}, obj1, obj2, obj3);
console.log(obj); // {x: 1, y: 1, z: 1}
- 重复的成员
在对象复制的过程中,出现重复的成员是比较常见的,assign 方法的处理方式是使用最后一个对象的值,和 … 的处理方式相同。
let obj1 = { x: 1 };
let obj2 = { x: 2 };
let obj3 = { x: 3 };
let obj = Object.assign({}, obj1, obj2, obj3);
console.log(obj); // {x: 3}
- 深度复制问题
如果要进行深度复制,就使用其他方法,不然会出现结果非预期的问题:
let obj1 = { a: 1, b: { y: 1 } }
let obj = Object.assign({}, obj1);
console.log(obj); // { a: 1, b: { y: 1 } }
obj1.b.y = 5;
console.log(obj); // { a: 1, b: { y: 5 } }
- 混入(
mixin
)功能
混入功能是 JavaScript 实现多重继承的常用方式,也就是将其他类的功能通过对象复制的方式复制到新类中。
class Observable {
on() { return 'on' }
un() { return 'un' }
}
class Floating {
float() {
return 'float'
}
}
class Component extends Observable {
setSize() {
return 'setSize'
}
}
Object.assign(Component.prototype, {float: Floating.prototype.float})
var cmp = new Component();
console.log(cmp.on()); // on
console.log(cmp.un()); // un
console.log(cmp.float()); // float
console.log(cmp.setSize()); // setSize
- 默认值
class MyClass {
constructor(options) {
let defaults = {x: 1, y:1};
this.options = Object.assign({}, defaults, options)
}
}
let c = new MyClass({x:2});
console.log(c.options)
- values 方法
获取一个对象的全部值。
let obj = {x: 1, y:2};
console.log(Object.values(obj)); // [1, 2]
- entries 方法
将对象的成员转变为数组。
let obj = {x: 1, y:2};
console.log(Object.entries(obj)); // [["x":1], ["y":2]]
getOwnPropertyDescriptors()
方法
获取对象所有属性的描述符。
let obj = {x: 1, y:2};
console.log(Object.getOwnPropertyDescriptors(obj));
/*
{
x: {value: 1, writable: true, enumerable: true, configurable: true}
y: {value: 2, writable: true, enumerable: true, configurable: true}
}
*/
- 对于 assign 方法,继承属性和不可枚举属性是不可复制的。
let obj = Object.create({x: 1}, { // x 是继承属性
y: {
value: 2 // y 是不可枚举属性
},
z: {
value: 3,
enumerable: true // z 是可枚举的属性
}
})
console.log(obj); // {z: 3, y: 2}
let obj2 = Object.assign({}, obj);
console.log(obj2); // {z: 3}
console.log(obj2.x); // undefined
console.log(obj2.y); // undefined
console.log(obj2.z); // 3
可以使用以下方法:
let obj = Object.create({
x: 1
}, {
// x 是继承属性
y: {
value: 2 // y 是不可枚举属性
},
z: {
value: 3,
enumerable: true // z 是可枚举的属性
}
});
console.log(obj); // {z: 3, y: 2}
let obj2 = Object.create(Object.getPrototypeOf(obj), Object.getOwnPropertyDescriptors(obj));
console.log(obj2.x); // 1
console.log(obj2.y); // 2
console.log(obj2.z); // 3
console.log(obj === obj2); // false
- 子类不能继承 getter 方法和 setter 方法
将子类的原型设置为超类的实例是常见的继承方式,但存在超类的 getter 方法和 setter 方法不能继承的问题
function superClass() {}
superClass.prototype = {
get color() {}
};
function subClass() {}
subClass.prototype = Object.create(superClass.prototype);
console.log(superClass.prototype); // {color: [Getter]}
console.log(subClass.prototype); // {}
subClass
并没有继承 superClass
的 color 方法,要解决这个问题,需要使用 getOwnPropertyDescriptors
方法,
function superClass() {}
superClass.prototype = {
get color() {}
};
function subClass() {}
subClass.prototype = Object.create(superClass.prototype, Object.getOwnPropertyDescriptors(superClass.prototype));
console.log(superClass.prototype); // {color: [Getter]}
console.log(subClass.prototype); // {}
原型
getPrototypeOf()
: 获取对象的原型。setPrototypeOf()
: 设置对象的原型。
class Car {
constructor(color) {
this.color = color;
}
getColor() {
return this.color;
}
}
let car = {};
Object.setPrototypeOf(car, Car.prototype);
console.log(Object.getPrototypeOf(car)); // {constructor: ƒ, getColor: ƒ}
super 关键字
引入 super 关键字来引用父类的方法。
class Vehicle {
constructor(color) {
this.color = color;
}
}
class Car extends Vehicle {
constructor(color, passengers) {
super(color);
this.passengers = passengers;
}
}
let car = new Car('blue', 4);
console.log(car); // Car {color: "blue", passengers: 4}