TypeScript 中的引用是怎么回事?
What's going on with references in 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
接口的一个实例传递给了 class c-tor,然后,我的 class 的一个字段填充了我传递的任何内容在 c-tor 中。
稍后在代码中我更改了传递给 c-tor 的变量,但是,当我调用 test
函数时 class 的 Runner
字段似乎没有反映在创建 TestDI
class.
的实例时对我传递的原始变量所做的任何更改
在 C# 中,我编写的代码将按照我的预期运行。但这里不是。
怎么回事?
尽量保持简单明了:您传递的是对象 new FooRunner()
的引用,而不是变量 runner
的引用,因此将新值赋给 runner
不会更改您传递给构造函数的内容,并且 SUT.Runner 保持不变。
In C# the code I've written would behave as I expect it to. But here it's not.
不是真的...如果您将上面的代码转换为 C# 代码并 运行 它,您会发现它的行为与您的 TypeScript 代码完全一样。
原因是你把runner
传给了TestDI
的构造函数。这里发生了什么......内容只是为构造函数的调用而复制,在这种情况下,这意味着指定对象的地址被复制。如果您现在将另一个对象的新地址分配给 runner
,为什么这会反映在您的 TestDI
实例中已经完成的副本中?我猜你脑子里有些东西搞混了 ;-)
Coming from C#, where objects are passed by reference (if they're not primitive types or structs). I've written some TypeScript code to test something:
嗯,是的,您可以将它们作为参考传递(例如,通过使用 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";
}
}
我对 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
接口的一个实例传递给了 class c-tor,然后,我的 class 的一个字段填充了我传递的任何内容在 c-tor 中。
稍后在代码中我更改了传递给 c-tor 的变量,但是,当我调用 test
函数时 class 的 Runner
字段似乎没有反映在创建 TestDI
class.
在 C# 中,我编写的代码将按照我的预期运行。但这里不是。
怎么回事?
尽量保持简单明了:您传递的是对象 new FooRunner()
的引用,而不是变量 runner
的引用,因此将新值赋给 runner
不会更改您传递给构造函数的内容,并且 SUT.Runner 保持不变。
In C# the code I've written would behave as I expect it to. But here it's not.
不是真的...如果您将上面的代码转换为 C# 代码并 运行 它,您会发现它的行为与您的 TypeScript 代码完全一样。
原因是你把runner
传给了TestDI
的构造函数。这里发生了什么......内容只是为构造函数的调用而复制,在这种情况下,这意味着指定对象的地址被复制。如果您现在将另一个对象的新地址分配给 runner
,为什么这会反映在您的 TestDI
实例中已经完成的副本中?我猜你脑子里有些东西搞混了 ;-)
Coming from C#, where objects are passed by reference (if they're not primitive types or structs). I've written some TypeScript code to test something:
嗯,是的,您可以将它们作为参考传递(例如,通过使用 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";
}
}