https://bigfrontend.dev/quiz/this-II
What does the code snippet below output by console.log
?
const obj = {
a: 1,
b() {
return this.a
}
}
console.log(obj.b())
console.log((true ? obj.b : a)())
console.log((true, obj.b)())
console.log((3, obj['b'])())
console.log((obj.b)())
console.log((obj.c = obj.b)())
const obj = {
a: 1,
b() {
return this.a
}
}
console.log(obj.b()) // 1
console.log((true ? obj.b : a)()) // undefined
console.log((true, obj.b)()) // undefined
console.log((3, obj['b'])()) // undefined
console.log((obj.b)()) // 1
console.log((obj.c = obj.b)()) // undefined
()
is grouping operator. It overrides the normal precedence of evaluation in expressions, so that expressions with lower precedence can be evaluated before an expression with higher priority.
-
In
(true ? obj.b : a)()
, the condition expression is going to be evaluated first. The evaluation returns the functionfunction() { return this.a }
, thatobj.b
points to. Thenfunction() { return this.a }
is invoked. Since it is a plain, undecorated invocation,this
points to the global object and we getundefined
as result. -
In
(true, obj.b)()
, we have a comma sequence expression. Comma sequence expression evaluates its operands from left to right and returns the evaluation of last operand:let x = 1; x = (x++, x); console.log(x); // output: 2 x = (2, 3); console.log(x); // output: 3
In our case, the comma sequence expression returns
function() { return this.a }
, which is the value of the last operandobj.b
. Thenfunction() { return this.a }
gets called and it is a plain, undecorated invocation.The same logic applies to
(3, obj['b'])()
and(obj.c = obj.b)()
. -
(obj.b)()
is identical toobj.b()
, because the grouping operator()
only changes expression priority and doesn't trigger extra expression value return. In(true, obj.b)()
, it is the comma sequence expression that triggers the expression value, and in(obj.c = obj.b)()
, it is the assignment operator=
.