,我在Todo
类中添加了一个构造函数:
export class Todo {
id: number;
title: string;
complete: boolean = false;
editMode: boolean = false;
constructor(values: Object = {}) {
Object.assign(this, values);
}
}
我不明白构造函数中代码的用途。
我的应用程序似乎可以使用和不使用它,但我对删除代码犹豫不决
在这个构造函数中,Object.assign(...( 的目的是什么?
这是一种轻松地将类的参数值添加到其各自的类字段中的方法,其中类实现该接口或至少具有该接口的部分植入。
interface IPerson {
firtName: string;
lastName: string;
}
class Person implements IPerson {
public firtName!: string;
public lastName!: string;
constructor(params: IPerson) {
Object.assign(this, params);
}
}
您的应用程序之所以有效,是因为您似乎已经以这样一种方式实现了这一点,即 values
的回调值也足够了。
这个Hack的主要问题是Object.assignment不是类型安全的。因此,以这种方式使用它与TypeScript的观点背道而驰。
如果要以类型安全的方式执行此操作,最好使用正确检查类型的自定义实现。像这样:
type PDM = PropertyDescriptorMap;
export class ClassSAssign<T> {
constructor(private objectToSpread: T, private klass: T) {}
private propertyDescriptorOptions = {
enumerable: true,
writable: true
};
public apply(): void {
const map = this.getPropertiesDescriptorMap();
Object.defineProperties(this.klass, map);
}
private getPropertiesDescriptorMap(): PDM {
return Object.entries(this.objectToSpread).reduce(
(obj: PDM, entry) => this.getPropertyDescriptorMap(obj, entry),
{}
);
}
private getPropertyDescriptorMap(obj: PDM, [key, value]: [string, any]): PDM {
return {
...obj,
[key]: {
value,
...this.propertyDescriptorOptions
}
};
}
}
您可以像这样使用此实用程序:
class Person implements IPerson {
public firtName!: string;
public lastName!: string;
constructor(params: IPerson) {
new ClassSAssign(params, this).apply();
}
}
如果你不想/不能使用上述内容,我建议你至少添加一些类型严谨性来保护你的类免受可以传递给它的值的影响。
interface IToDo {
id?: number;
title?: string;
}
export class Todo implements IToDo {
public id?: number;
public title?: string;
public complete: boolean = false;
public editMode: boolean = false;
constructor(values?: IToDo) {
Object.assign(this, values);
}
}
Object.assign
将第二个参数的所有属性分配给第一个参数。
代码的作用是,如果将对象传递到构造函数中,它将把这些属性分配给正在创建的对象。例如:
const todo = new Todo({ id: 1, title: 'hello' });
console.log(todo.title); // 'hello'
编辑:由于Object.assign
不是类型安全的,因此您可能应该让构造函数接受比Object
更具体的内容。我建议为它创建一个接口。
Object.assign
没有类型检查。另一种选择是:
const assign = <T, K extends keyof T>(...args: T[]): T =>
args.reduce( (result, current) =>
(Object.keys(current) as K[]).reduce((target, key) => {
target[key] = current[key];
return target;
}, result)
, args[0])
;
请注意,如果 T 的属性不是可选的,则传入的每个对象都必须包含每个属性。如果可以保证函数返回后每个属性的存在,则可以将参数作为Partial<T>
传入,然后在完成后强制结果。
它只是将两个对象this
和values
组合在一起。根据MDN
Object.assign()
方法用于将所有可枚举的自己的属性的值从一个或多个源对象复制到目标对象。它将返回目标对象。
它用于创建对象的浅表副本并将其属性与this
合并,是Todo
的实例。在给定的代码中this
目标对象。考虑以下示例
let target = {a:1,b:2};
Object.assign(target,{x:"new prop 1",y:"new prop 2"});
console.log(target)