You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何从函数装饰器输出消息?调用toString时显示咖啡尺寸

解决咖啡类toString显示尺寸及函数装饰器的问题

我看了你的代码,发现几个小细节问题导致需求没实现,咱们一步步修正,同时搞定你两个核心需求——让toString()输出带咖啡尺寸的消息,以及通过函数装饰器输出提示信息。

先说说原代码的几个问题

  • small函数里用this.size不对:普通函数直接调用时this不指向咖啡实例,得直接给传入的对象加属性
  • 变量名混乱:small里的coffe没定义,应该用传入的参数,建议把参数名改成coffee避免和全局变量重名
  • 逻辑顺序错误:先给size赋值再修改成本才合理,不然原成本计算会有问题
  • toString没处理size未定义的情况,会显示undefined

修正后的完整代码

// 定义咖啡构造函数
function Coffee(name) {
  this.name = name;
  this.cost = function () {
    return 5;
  };
  // 完善toString方法,支持显示尺寸,无尺寸时也有友好提示
  this.toString = function () {
    return `${this.name} ${this.cost()} USD ${this.size ? `(${this.size})` : '(未设置尺寸)'}`;
  };
}

// 小型咖啡装饰器:接收咖啡实例,增强其功能
const smallDecorator = function (coffee) {
  // 给咖啡实例添加尺寸属性
  coffee.size = "small";
  // 保存原成本,避免重写cost后无法获取初始值
  const originalCost = coffee.cost();
  // 重写cost方法,实现降价
  coffee.cost = function () {
    return originalCost - 1;
  };
  // 装饰器内输出提示消息
  console.log(`✅ 已完成装饰:咖啡变为small尺寸,原成本${originalCost}USD,新成本${coffee.cost()}USD`);
};

// 创建拿铁实例
const myCoffee = new Coffee('Latte');
// 用装饰器增强实例
smallDecorator(myCoffee);
// 触发toString方法(String()会自动调用对象的toString)
console.log(String(myCoffee));

代码说明

  1. toString方法优化:
    用模板字符串让输出更清晰,同时判断this.size是否存在,避免显示undefined。当实例被装饰器添加size属性后,toString会自动带上尺寸信息。

  2. 函数装饰器的正确用法:

    • 装饰器接收咖啡实例作为参数,直接给实例添加size属性,这样toString就能访问到这个属性
    • 先保存原cost的返回值,再重写cost方法实现降价,这是装饰器的核心——在不修改原构造函数的前提下,增强对象的功能
    • 在装饰器内部直接用console.log输出装饰完成的提示,满足你从装饰器输出消息的需求

运行结果

执行代码后会先输出装饰器的提示:

✅ 已完成装饰:咖啡变为small尺寸,原成本5USD,新成本4USD

然后输出toString的结果:

Latte 4 USD (small)

如果需要其他尺寸的装饰器(比如medium、large),直接复制smallDecorator修改size值和折扣逻辑就行,扩展性拉满~

内容的提问来源于stack exchange,提问作者Igor Shvets

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.27 07:20:16