为什么TypeScript toString方法未按需调用

2uluyalo  于 2023-06-24  发布在  TypeScript
关注(0)|答案(2)|浏览(160)

我有一个非常简单的代码。
有一个覆盖了toString的型号:
policy.ts:

export class Policy {
  public id: number;
  public name: string;
  public description: string;

  toString(): string {
    return this.name + ': ' + this.description;
  }
}

然后我用两种方式使用Policy模型。
绑定到create-policy.component.html

...
<input type="text" name="name" [(ngModel)]="policy.name" required>

并且它在分量create-policy.component.ts中:

import { Component, OnInit } from '@angular/core';
import { Policy } from '../models/policy';

@Component({
    selector: 'app-create-policy',
    templateUrl: './create-policy.component.html',
    styleUrls: ['./create-policy.component.css'],
})
export class CreatePolicyComponent implements OnInit {
    policy: Policy = {
        id: 0,
        name: '',
        description: '',
    };
    constructor() {}

    ngOnInit() {}
    onSubmitPostHttp() {
        console.log('Started onSubmitPostHttp');
        console.log('policy=' + this.policy.toString());
    }
}

仍然在控制台上,我不获取属性;它打印:
create-policy.component.ts:23 policy=[object Object]
直接日志记录属性工作正常:

console.log("policy=" + this.policy.name);

它打印:
策略=ss

xvw2m8pv

xvw2m8pv1#

policy不是Policy的示例,仍然使用原生toString方法。
Policy类像policy: Policy一样被用作接口,这一事实并没有示例化它。因为普通对象符合这个接口(它已经有了toString方法),所以这不会导致类型错误。
它可以是:

policy = Object.assign(new Policy, {
  id: 0,
  name: "",
  description: ""
});

在这一点上,很明显Policy类不是为它所使用的东西而设计的,最好将属性初始化移动到它的构造函数中:

export class Policy {
  constructor(
   public id: number,
   public name: string,
   public description: string
 ) {}

 toString(): string {
   return this.name + ': ' + this.description;
 }

}

和/或

policy = new Policy(
  id: 0,
  name: "",
  description: ""
);
a1o7rhls

a1o7rhls2#

您正在创建此.policy作为新对象,而没有重写toString()方法。这就是为什么它在记录结果时仍然使用默认实现的原因。
查看创建typescript类时生成的JavaScript代码:

TS编码:

export class Policy {
    public id: number;
    public name: string;
    public description: string;

    toString(): string {
        return this.name + ': ' + this.description;
    }
}

let pol: Policy = {
    id: 0,
    name: "",
    description: ""
};

JS编码:

define(["require", "exports"], function (require, exports) {
    "use strict";
    Object.defineProperty(exports, "__esModule", { value: true });
    var Policy = /** @class */ (function () {
        function Policy() {
        }
        Policy.prototype.toString = function () {
            return this.name + ': ' + this.description;
        };
        return Policy;
    }());
    exports.Policy = Policy;
    var pol = {
        id: 0,
        name: "",
        description: ""
    };
});

正如您在这里看到的,toString()方法被添加到Policy对象的原型中。关于prototypes in javascript,你可以读到很多,但这里的关键是,除非你使用new操作符,否则策略的原型不会被调用。
正如estus提到的; JavaScript中的所有对象都有一个toString方法it is included in the object prototype。这就是为什么当你直接创建你的对象时不会出现任何错误的原因,它具有策略对象的所有正确的属性和方法,这就是为什么typescript允许这种行为。

相关问题