我正在尝试在一个Sharepoint Framework小示例中实现原型模式,我从这里获取了示例:
https://mertarauh.com/tutorials/typescript-design-patterns/prototype-pattern/
,并进行如下修改:
class Employee {
private totalperMonth: number;
constructor(public name: string, public hiredDate: Date, public dailyRate: number){
this.totalperMonth = dailyRate * 20 ;
}
public display(): string{
return "Employee " + this.name + " earns per month: " + this.totalperMonth;
}
public clone():Employee{
var cloned = Object.create(Employee || null);
Object.keys(this).map((key: string) => {
cloned[key]= this[key];
});
return <Employee>cloned;
}
}
export default Employee;
和组件
import * as React from 'react';
import styles from './Prototype.module.scss';
import { IPrototypeProps } from './IPrototypeProps';
import { escape } from '@microsoft/sp-lodash-subset';
import Employee from './Employee';
export default class Prototype extends React.Component<IPrototypeProps, {}> {
public render(): React.ReactElement<IPrototypeProps> {
const today = new Date();
let employee1: Employee = new Employee('Luis', today, 500);
let employee2 = employee1.clone();
employee2.dailyRate = 550;
return (
<div className={ styles.prototype }>
<div className={ styles.container }>
<div className={ styles.row }>
<div className={ styles.column }>
<span className={ styles.title }>Welcome to SharePoint!</span>
<p className={ styles.subTitle }>Customize SharePoint experiences using Web Parts.</p>
<p className={ styles.description }>{escape(this.props.description)}</p>
<span className={ styles.label }>{employee1.display()}</span>
<span className={ styles.label }>{employee2.display()}</span>
</div>
</div>
</div>
</div>
);
}
}
但是我在控制台中遇到此错误:
我想念什么?
答案 0 :(得分:1)
这种方法存在几个问题。
类是TypeScript中的一等公民,替代方法可以使类型安全性变得不那么直接。
Object.create
是低级工具,除非您知道自己在做什么以及为什么,否则使用它不是一个好主意。此处的实际错误是选择了错误的原型(Employee
而不是Employee.prototype
),因此name
属性引用了function name
property,这是只读的,不应设置为重新分配。实现clone
的正确方法是:
public clone():Employee{
return Object.assign(Object.create(Employee.prototype), this);
}
它忽略类构造函数的事实是一个令人怀疑的决定,因为构造函数可能包含与clone
中所应用的逻辑不同的逻辑。
React提倡功能性编程来替代OOP,将应用程序状态保持为纯对象而不是类实例是有益的,这可能有助于避免设计上的缺陷,而这些缺陷在将来将很昂贵。在这种情况下,没有什么真正需要一个类的。同一件事可以表示为:
const createEmployee = (name, hiredDate, dailyRate) => ({
name,
hiredDate,
dailyRate,
totalperMonth: dailyRate * 20
});
...
let employee1 = createEmployee('Luis', today, 500);
let employee2 = {...employee1, dailyRate: 550};
请注意,totalperMonth
类和Employee
工厂函数均未重新计算createEmployee
。这可能是不可取的(请参见上面有关构造函数的注释)。