从技术上讲,这是 TypeScript,但问题在于 JS。
我有一个名为 Animal
的接口(interface),像这样:
interface Animal {
name: string;
speak(): void;
}
function animal(name: string): Animal {
return {
name,
speak() {
console.log('This animal does not know how to speak!');
},
};
}
我有另一个接口(interface),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;
}
我还有另一个接口(interface)叫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();
现在有一个叫 John 的人,他有一只名叫 Foo 的西伯利亚雪橇犬。
map.set('John', dog(animal('Foo'), 'Siberian Husky'));
John 让 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 的工作方式而准确)。
关于javascript - 在 JavaScript 中更改映射中的值和闭包中的引用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53924246/