Skip to content

Latest commit

 

History

History
81 lines (57 loc) · 2.49 KB

33.this-II.md

File metadata and controls

81 lines (57 loc) · 2.49 KB

33. this II

Problem

https://bigfrontend.dev/quiz/this-II

Problem Description

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)())

Answer

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

Explanation

() 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 function function() { return this.a }, that obj.b points to. Then function() { return this.a } is invoked. Since it is a plain, undecorated invocation, this points to the global object and we get undefined 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 operand obj.b. Then function() { 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 to obj.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 =.

Reference

Understanding this, one example at a time