javascript - TypeScript 中的引用发生了什么?
问题描述
我对 JavaScript 和 TypeScript 还很陌生。
就我而言,TypeScript 被编译成常规的 JavaScript。
来自 C#,其中对象通过引用传递(如果它们不是原始类型或结构)。我写了一些 TypeScript 代码来测试一些东西:
interface IRunner {
run(): string;
}
class TestDI {
private readonly Runner: IRunner;
constructor(runner: IRunner) {
this.Runner = runner;
}
test(): void {
console.log('Result of runner: ' + this.Runner.run());
}
}
class FooRunner implements IRunner {
run(): string {
return 'Foo';
}
}
class BarRunner implements IRunner {
run(): string {
return 'Bar';
}
}
let runner: IRunner;
runner = new FooRunner();
const SUT: TestDI = new TestDI(runner);
// Expected output: Foo
// Actual output: Foo
console.log(runner.run());
// Expected output: Foo
// Actual output: Foo
SUT.test();
runner = new BarRunner();
// Expected output: Bar
// Actual output: Bar
console.log(runner.run());
// Expected output: Bar
// Actual output: Foo
SUT.test();
在上面的代码中,我将IRunner
接口的一个实例传递给了一个类 c-tor,然后,我的类的一个字段填充了我在 c-tor 中传递的任何内容。
稍后在代码中,我更改了传递给 c-tor 的变量,但是,当我调用类的test
函数Runner
字段时,似乎没有反映在创建类的实例时对传递的原始变量所做的任何更改TestDI
。
在 C# 中,我编写的代码会按照我的预期运行。但这里不是。
这是怎么回事?
解决方案
在 C# 中,我编写的代码会按照我的预期运行。但这里不是。
不是真的...如果您将上面的代码转换为 C# 代码并运行它,您将看到它的行为与您的 TypeScript 代码完全相同。
原因是您传递runner
给TestDI
. 这里发生了什么......内容只是为调用构造函数而复制,在这种情况下,这意味着复制指定对象的地址。如果您现在将另一个对象的新地址分配给runner
,为什么这会反映在您的TestDI
实例中已完成的副本中?我猜你在你的大脑中混杂了一些东西;-)
来自 C#,其中对象通过引用传递(如果它们不是原始类型或结构)。我写了一些 TypeScript 代码来测试一些东西:
是的,您可以将它们作为参考传递(ref
例如通过使用),但默认情况下,地址只是简单地复制(如上所述)。
为了让您更轻松:只需复制和粘贴并感到惊讶
class Program
{
static void Main(string[] args)
{
IRunner runner;
runner = new FooRunner();
TestDI SUT = new TestDI(runner);
// Expected output: Foo
// Actual output: Foo
Console.WriteLine(runner.Run());
// Expected output: Foo
// Actual output: Foo
SUT.Test();
runner = new BarRunner();
// Expected output: Bar
// Actual output: Bar
Console.WriteLine(runner.Run());
// Expected output: Bar
// Actual output: Foo
SUT.Test();
}
}
public interface IRunner
{
string Run();
}
public class TestDI
{
private readonly IRunner runner;
public TestDI(IRunner runner)
{
this.runner = runner;
}
public void Test()
{
Console.WriteLine("Result of runner: " + this.runner.Run());
}
}
public class FooRunner : IRunner
{
public string Run()
{
return "Foo";
}
}
public class BarRunner : IRunner
{
public string Run()
{
return "Bar";
}
}
推荐阅读
- bash - -bash:警告:命令替换:输入中忽略的空字节
- javascript - 配置项目 ':app' 时出现问题。> 无法创建任务 ':app:processDebugGoogleServices'。使用 mobilefirst 插件
- javascript - Intl-MessageFormat 中的“语言环境”如何工作?
- python - 使用 pip 的进度条
- laravel - laravel8 未定义变量:错误
- php - 在 WooCommerce 单品页面上仅显示“有货”相关产品
- python - Plotly Dash:无需回调即可访问 dcc.Store 组件
- java - 为什么会出现此崩溃且预期没有挂起的异常:java.lang.NoClassDefFoundError: androidx.core.view.ViewCompat$2
- javascript - react native:如何在进入内部页面时自动显示当前时间?
- java - 不带参数的 Setter Java OOP