TypeError:“名称”是只读的

时间:2019-01-12 16:22:04

标签: reactjs typescript

我正在尝试在一个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>
    );
  }
}

但是我在控制台中遇到此错误:

我想念什么?

enter image description here

1 个答案:

答案 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。这可能是不可取的(请参见上面有关构造函数的注释)。