Description:
I'm not sure if this is an intended feature.
When x is called with this keyword, it gives you an undefined.
I've tried to find the reason for this in ecma-interantional.org but don't know where I could find it.
Could someone provide me a link I can convince myself for why this isn't a bug?
Output:
const x = 1;
console.log(this.x); // undefined
This isn't a bug because variables aren't the same as properties (except when you're in the global scope of a Script).
Could someone provide me a link I can convince myself for why this isn't a bug?
It might help to reframe the question mentally if you’re still trying to see where this does/doesn’t occur. Rather than trying to figure out why it doesn’t happen here, you may have an easier time picking through the spec to figure out why it _does_ happen under specific conditions involving var and function declared bindings in scripts or undeclared bindings in sloppy mode scripts.
(That is, binding declarations leading to global-this property setting or with-statement property setting are the special case. Bindings declared with let, const, and class are purely lexical afaik, so I don’t think you’ll find any steps that ‘stop’ them from setting properties; rather, you’ll find steps that cause specific other cases to set properties for historical reasons.)
Unfortunately I don’t think there’s a single key part of the spec one can point to that explains all this in depth. The behaviors arise from a number of algorithms working together. Some key bits to look at:
VariableDeclaration : BindingIdentifier Initializer[opt], which use GetIdentifierReference indirectly through ResolveBinding and end with a PutValue call.TBH it’s a bit confusing (and a note in the second-to-last item’s linked op seems to reference a non-existent sixth step...), so I’m not sure I’ve nailed the right/best spots to look at, but hopefully it gives you a handhold for further investigation.
a note in the second-to-last item’s linked op seems to reference a non-existent sixth step
Interesting, looks like the note was correct in ES2018 but became invalid in ES2019. And it's not alone. Will create a PR to fix, but this makes referring to step numbers seem like a really dangerous practice...
Most helpful comment
It might help to reframe the question mentally if you’re still trying to see where this does/doesn’t occur. Rather than trying to figure out why it doesn’t happen here, you may have an easier time picking through the spec to figure out why it _does_ happen under specific conditions involving
varandfunctiondeclared bindings in scripts or undeclared bindings in sloppy mode scripts.(That is, binding declarations leading to global-this property setting or with-statement property setting are the special case. Bindings declared with
let,const, andclassare purely lexical afaik, so I don’t think you’ll find any steps that ‘stop’ them from setting properties; rather, you’ll find steps that cause specific other cases to set properties for historical reasons.)Unfortunately I don’t think there’s a single key part of the spec one can point to that explains all this in depth. The behaviors arise from a number of algorithms working together. Some key bits to look at:
VariableDeclaration : BindingIdentifier Initializer[opt], which use GetIdentifierReference indirectly through ResolveBinding and end with a PutValue call.TBH it’s a bit confusing (and a note in the second-to-last item’s linked op seems to reference a non-existent sixth step...), so I’m not sure I’ve nailed the right/best spots to look at, but hopefully it gives you a handhold for further investigation.