[英]TypeError: “name” is read-only
I am trying to implement the prototype pattern in a Sharepoint Framework small example, I took the sample from here: 我试图在一个Sharepoint Framework小示例中实现原型模式,我从这里获取了示例:
https://mertarauh.com/tutorials/typescript-design-patterns/prototype-pattern/ https://mertarauh.com/tutorials/typescript-design-patterns/prototype-pattern/
and adapted as below: 并修改如下:
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;
and the component 和组件
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>
);
}
}
However I get in the console this error: 但是我在控制台中遇到此错误:
What am I missing? 我想念什么?
There are several problems with this approach. 这种方法存在几个问题。
Classes are first-class citizens in TypeScript, alternative approaches to inheritance can make type safety much less straightforward. 在TypeScript中,类是一等公民,继承的替代方法可以使类型安全性变得不那么直接。
Object.create
is low-level tool, it isn't a good idea to use it unless you know what you're doing and why. Object.create
是低级工具,除非您知道自己在做什么以及为什么这么做,否则不要使用它。 The actual mistake here is that wrong prototype was chosen ( Employee
instead of Employee.prototype
), so name
property refers to function name
property , which is read-only and shouldn't be reassigned. 此处的实际错误是选择了错误的原型(
Employee
而不是Employee.prototype
),因此name
属性指向函数name
属性 ,该属性是只读的,不应重新分配。 A proper way to implement clone
would be: 实现
clone
正确方法是:
public clone():Employee{
return Object.assign(Object.create(Employee.prototype), this);
}
The fact that it ignores class constructor is a doubtful decision because a constructor may contain logic that differs from one applied in clone
. 它忽略类构造函数的事实是一个令人怀疑的决定,因为构造函数可能包含与
clone
应用的逻辑不同的逻辑。
React promotes functional programming as a substitute to OOP, it's beneficial to maintain application state as plain objects rather than class instances, this may help to avoid design flaws that will be costly to fix in future. React促进了函数式编程来代替OOP,将应用程序状态保持为纯对象而不是类实例是有益的,这可能有助于避免设计上的缺陷,而这些缺陷在将来将很昂贵。 There's nothing that would really require a class in this case.
在这种情况下,没有什么真正需要一个类的。 The same thing could be expressed as:
同一件事可以表示为:
const createEmployee = (name, hiredDate, dailyRate) => ({
name,
hiredDate,
dailyRate,
totalperMonth: dailyRate * 20
});
...
let employee1 = createEmployee('Luis', today, 500);
let employee2 = {...employee1, dailyRate: 550};
Notice that totalperMonth
isn't recalculated neither in Employee
class nor in createEmployee
factory function. 请注意,
totalperMonth
即不是重新计算Employee
类也不createEmployee
工厂函数。 This may be undesirable (see the note on a constructor above). 这可能是不可取的(请参见上面有关构造函数的注释)。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.