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

TypeScript如何按引用传递函数类型成员变量?

解决函数类型成员变量的Setter封装问题

当前代码中setDelegateToPrint无法修改myFoo.delegated,本质原因是JS/TS中函数参数按值传递:你传入的myFoo.delegated是当前函数引用的副本,在函数内部修改delegate变量只是改变了局部变量的指向,完全不会影响原对象的属性。

要求是Setter函数不能依赖Foo类的具体定义,只需要知道存在符合签名的成员函数,以下是两种可行方案:

方案一:传递属性设置回调

让调用者传入一个能修改目标属性的回调函数,Setter只负责把目标函数传递给这个回调,完全不需要知晓对象的具体类型:

class Foo {
    public delegated: (param: string) => void 
        = () => { console.log("Default value, was not set to anything else."); };
}

function printAllCaps(s: string): void {
    console.log(s.toUpperCase());
}

// 接收一个设置回调,直接传递目标函数
function setDelegateToPrint(setter: (fn: (param: string) => void) => void) {
    setter(printAllCaps);
}

let myFoo: Foo = new Foo();

// 传入修改myFoo.delegated的回调
setDelegateToPrint((fn) => { myFoo.delegated = fn; });

myFoo.delegated("hello!"); // 输出 HELLO!

方案二:使用类型约束定义通用对象类型

定义一个接口描述拥有指定签名delegated属性的对象,Setter接收这个接口类型的参数,既保证类型安全,又不需要依赖具体的Foo类:

// 定义通用接口,描述符合要求的对象结构
interface HasStringDelegate {
    delegated: (param: string) => void;
}

class Foo {
    public delegated: (param: string) => void 
        = () => { console.log("Default value, was not set to anything else."); };
}

function printAllCaps(s: string): void {
    console.log(s.toUpperCase());
}

// 接收符合HasStringDelegate接口的对象,直接修改其delegated属性
function setDelegateToPrint(obj: HasStringDelegate) {
    obj.delegated = printAllCaps;
}

let myFoo: Foo = new Foo();

setDelegateToPrint(myFoo); // Foo自动满足HasStringDelegate接口

myFoo.delegated("hello!"); // 输出 HELLO!

两种方案的对比

  • 方案一更灵活:适用于无法直接访问对象属性的场景,或者属性设置需要额外逻辑的情况
  • 方案二更直观:代码更简洁,适合常规的属性赋值场景

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.11 15:51:02