Неверная ссылка на машинопись

Я пытался определить какое-то свойство для String.Prototype в TypeScript:

Object.defineProperty(String.prototype, 'test', {
    value: () => {
        console.log("this is a test over text " + this);
    }
})

в прототипах javaScript, this ссылается на объект, вызвавший метод (в данном случае строковое значение). Но скомпилированный вывод файла:

var _this = this;
Object.defineProperty(String.prototype, 'test', {
    value: function () {
        console.log("this is a test over text " + _this);
    }
});

Компилятор TypeScript добавляет переменную _this и относится к этому.

Это ошибка или проблема в моей реализации?

1 ответ

Решение

Это ошибка или проблема в моей реализации?

Нет, так работают функции стрелок TypeScript: в функциях стрелок this наследуется от контекста, в котором создается функция, а не от того, как она вызывается. (Функции стрелок также есть в ES2015, вдохновленные, по крайней мере частично, функциями "жирной стрелки" CoffeeScript; я не знаю историю TypeScript и была ли она частью вдохновения для функций стрелок ES2015 или наоборот.)

Вот цитата из спецификации по ссылке выше:

Выражение функции вводит новое динамически связанное this, тогда как выражение функции arrow сохраняет this своего окружающего контекста.

Выражения функций со стрелками особенно полезны для написания обратных вызовов, которые в противном случае часто имеют неопределенное или непредвиденное значение.

В примере

class Messenger {  
    message = "Hello World";  
    start() {  
        setTimeout(() => alert(this.message), 3000);  
    }  
};

var messenger = new Messenger();  
messenger.start();

использование выражения функции стрелки приводит к тому, что обратный вызов имеет то же значение, что и окружающий метод start.

Если ты хочешь this зависеть от того, как была вызвана функция, не используйте функцию стрелки, используйте function:

Object.defineProperty(String.prototype, 'test', function() {
    console.log("this is a test over text " + this);
})

Также обратите внимание, что, как nils указывает на третий аргумент Object.defineProperty должен быть дескриптором свойства, а не функцией. Вы могли иметь в виду:

Object.defineProperty(String.prototype, 'test', {
    value: function() {
        console.log("this is a test over text " + this);
    }
});

Транспортер TypeScript совсем не меняет это; призвание "testing".test() выходы "this is a test of text testing":

Object.defineProperty(String.prototype, 'test', {
    value: function() {
        snippet.log("this is a test over text " + this);
    }
});
"testing".test();
<!-- Script provides the `snippet` object, see http://meta.stackexchange.com/a/242144/134069 -->
<script src="//tjcrowder.github.io/simple-snippets-console/snippet.js"></script>

Другие вопросы по тегам