I tried to define some property for String.Prototype
in TypeScript:
Object.defineProperty(String.prototype, 'test', {
value: () => {
console.log("this is a test over text " + this);
}
})
in javaScript prototypes, this
refers to the object which called the method (in this case the string value). But compiled output of the file is:
var _this = this;
Object.defineProperty(String.prototype, 'test', {
value: function () {
console.log("this is a test over text " + _this);
}
});
TypeScript compiler adds variable _this
and refers to it.
Is that a bug or there is a problem in my implementation?
Is that a bug or there is a problem in my implementation?
No, it's how TypeScript's arrow functions work: In arrow functions, this
is inherited from the context in which the function is created, rather than being set by how it's called. (Arrow functions are also in ES2015, inspired at least in part by CoffeeScript's "fat arrow" functions; I don't know the history of TypeScript and whether it was also part of the inspiration for ES2015's arrow functions or vice-versa.)
Here's a quote from the spec link above:
A function expression introduces a new dynamically bound this, whereas an arrow function expression preserves the this of its enclosing context.
Arrow function expressions are particularly useful for writing callbacks, which otherwise often have an undefined or unexpected this.
In the example
class Messenger { message = "Hello World"; start() { setTimeout(() => alert(this.message), 3000); } }; var messenger = new Messenger(); messenger.start();
the use of an arrow function expression causes the callback to have the same this as the surrounding 'start' method.
If you want this
to depend on how the function was called, don't use an arrow function, use function
:
Object.defineProperty(String.prototype, 'test', function() {
console.log("this is a test over text " + this);
})
Also note that as nils points out the third argument to Object.defineProperty
should be a property descriptor, not a function. You may have meant:
Object.defineProperty(String.prototype, 'test', {
value: function() {
console.log("this is a test over text " + this);
}
});
The TypeScript transpiler doesn't change that at all; calling "testing".test()
outputs "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>
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With