javascript - 在 JavaScript 中更改 map 中的值和闭包中的引用
问题描述
从技术上讲,这是 TypeScript,但问题在于 JS。
我有一个名为 的接口Animal
,如下所示:
interface Animal {
name: string;
speak(): void;
}
function animal(name: string): Animal {
return {
name,
speak() {
console.log('This animal does not know how to speak!');
},
};
}
我有Dog
另一个Animal
接口Dog
.
interface Dog extends Animal {
breed: string;
}
function dog<T extends Animal>(animal: T, breed: string): T & Dog {
const obj = {
breed,
...animal,
speak() {
console.log(`${obj.name} says Woof!`);
},
};
return obj;
}
我还有另一个接口叫做Competition
,代表所有参加比赛的动物。这不仅限于狗。
interface Competition extends Animal {
prize: number;
}
function competition<T extends Animal>(animal: T, prize: number): T & Competition {
return {
prize,
...animal,
};
}
到这里为止一切都很好。但是现在,我需要一个Map
存储动物及其所有者的名称(假设一个人只能拥有一只动物)。
const map: Map<string, Animal> = new Map();
现在有一个叫约翰的人,他有一只名叫Foo的西伯利亚哈士奇。
map.set('John', dog(animal('Foo'), 'Siberian Husky'));
约翰让 Foo 参加比赛,Foo 获得了第二名。
map.set('John', competition(map.get('John'), 2));
然而,在比赛中,约翰看到另一只狗也被命名为 Foo,因此决定重新命名他的狗。
map.get('John').name = 'Timmy';
map.get('John').speak(); // Foo says Woof!
问题是在我调用时speak
访问闭包中的对象,在这种情况下,。更改对象中变量的值不会修改闭包中的值。name
dog(...)
"Foo"
我的问题是,我如何也改变闭包中的值?我似乎想不出一种不需要对当前系统进行重大更改的方法。
解决方案
使用方法上下文,this.name
而不是obj.name
(在 Typescript 中要小心,this
由于 JavaScript 的工作方式,输入可能不准确)。