I have two pieces of code that each work as expected:
function Test() {}
let tmp = function() {
console.log(this)
}
tmp.call(Test)
and
function Test() {}
(function() {
console.log(this)
}).call(Test)
They both produce the expected output: [Function: Test]
.
However, when these independent code fragments are combined, it produces an error. So, running the following code
function Test() {}
let tmp = function() {
console.log(this)
}
tmp.call(Test)
(function() {
console.log(this)
}).call(Test)
results in
TypeError: tmp.call(...) is not a function
I found a non-elegant fix for this, which is adding a delay to the second code fragment. So, the following would produce the desired output ([Function: Test]
twice):
function Test() {}
let tmp = function() {
console.log(this)
}
tmp.call(Test)
setTimeout(() => {
(function() {
console.log(this)
}).call(Test)
}, 100);
The fact that the timeout seems to fix it makes me think it's related to some asynchronous stuff, but I can't explain exactly why it's happening.
You're falling victim to an automatic semicolon insertion trap. The code
tmp.call(Test)
(function() {
console.log(this)
}).call(Test)
is interpreted as if it were written
tmp.call(Test)(function() { console.log(this) }).call(Test)
If a semicolon is introduced:
tmp.call(Test);
(function() {
console.log(this)
}).call(Test)
then it will work.
The precise rules involve some "legalese" that's somewhat hard to digest, but the basic idea (in this case) is that a semicolon won't be inserted when an expression can syntactically work when the newline is considered to be a simple space character.
This is how your code snippet is interpreted:
function Test() {}
let tmp = function() {
console.log(this)
}
tmp.call(Test)(function() {
console.log(this)
}).call(Test)
To fix it, add a semi-colon after tmp.call(Test)
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