Неверная ссылка на машинопись
Я пытался определить какое-то свойство для 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>