Измените значение в карте и ссылку в закрытии в JavaScript - PullRequest
0 голосов
/ 25 декабря 2018

Технически, это 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".Изменение значения переменных в объекте не приводит к изменению значения в замыкании.

Мой вопрос: как мне также изменить значение в замыкании?Кажется, я не могу придумать способ, который не требует серьезных изменений в моей нынешней системе.

Детская площадка

1 Ответ

0 голосов
/ 25 декабря 2018

Используйте контекст методов, this.name вместо obj.name (будьте осторожны с this в Typescript, типизация может быть не точной из-за способа работы JavaScript).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...