Skip to content

Latest commit

 

History

History
281 lines (228 loc) · 5.25 KB

6.Arrow-Function.md

File metadata and controls

281 lines (228 loc) · 5.25 KB

6. Arrow Function

Problem

https://bigfrontend.dev/quiz/6-Arrow-Function

Problem Description

What does the code snippet below output by console.log?

const obj = {
  dev: 'bfe',
  a: function () {
    return this.dev;
  },
  b() {
    return this.dev;
  },
  c: () => {
    return this.dev;
  },
  d: function () {
    return (() => {
      return this.dev;
    })();
  },
  e: function () {
    return this.b();
  },
  f: function () {
    return this.b;
  },
  g: function () {
    return this.c();
  },
  h: function () {
    return this.c;
  },
  i: function () {
    return () => {
      return this.dev;
    };
  },
};

console.log(obj.a());
console.log(obj.b());
console.log(obj.c());
console.log(obj.d());
console.log(obj.e());
console.log(obj.f()());
console.log(obj.g());
console.log(obj.h()());
console.log(obj.i()());

Answer

const obj = {
  dev: 'bfe',
  a: function () {
    return this.dev;
  },
  b() {
    return this.dev;
  },
  c: () => {
    return this.dev;
  },
  d: function () {
    return (() => {
      return this.dev;
    })();
  },
  e: function () {
    return this.b();
  },
  f: function () {
    return this.b;
  },
  g: function () {
    return this.c();
  },
  h: function () {
    return this.c;
  },
  i: function () {
    return () => {
      return this.dev;
    };
  },
};

console.log(obj.a()); // "bfe"
console.log(obj.b()); // "bfe"
console.log(obj.c()); // undefined
console.log(obj.d()); // "bfe"
console.log(obj.e()); // "bfe"
console.log(obj.f()()); // undefined
console.log(obj.g()); // undefined
console.log(obj.h()()); // undefined
console.log(obj.i()()); // "bfe"

Explanation

const obj = {
  dev: 'bfe',
  a: function () {
    return this.dev;
  },
};

console.log(obj.a()); // "bfe"

obj.a() return "bfe", because a() is a normal function and we invoke it through obj, so a()'s this refers to obj.


const obj = {
  dev: 'bfe',
  b() {
    return this.dev;
  },
};

console.log(obj.b()); // "bfe"

obj.b() return "bfe", because b() is a method and we invoke it through obj, so b()'s this refers to obj.


const obj = {
  dev: 'bfe',
  c: () => {
    return this.dev;
  },
};

console.log(obj.c()); // undefined

obj.c() returns undefined, because arrow functions use lexical scoping for this binding, which means they adopt the this binding from the enclosed (function or global) scope.


const obj = {
  dev: 'bfe',
  d: function () {
    return (() => {
      return this.dev;
    })();
  },
};

console.log(obj.d()); // "bfe"

obj.d() returns "bfe", because the arrow function that d() returns lexically captures whatever its enclosed scope d()'s this is at its call time, and since we invoke d() through obj, d()'s this refers to obj.


const obj = {
  dev: 'bfe',
  b() {
    return this.dev;
  },
  e: function () {
    return this.b();
  },
};

console.log(obj.e()); // "bfe"

obj.e() returns "bfe", because e() is a normal function and we invoke it through obj, so its this refers to obj. e() returns this.b(), since e()'s this points to obj, so it essentially returns obj.b(), b() is also invoked through obj, so its this refers to obj.


const obj = {
  dev: 'bfe',
  b() {
    return this.dev;
  },
  f: function () {
    return this.b;
  },
};

console.log(obj.f()()); // undefined

obj.f()() returns undefined, because obj.f() returns a reference to the function b(), when we invoke b(), it is a plain, undecorated function invocation, so this refers to the global object.


const obj = {
  dev: 'bfe',
  c: () => {
    return this.dev;
  },
  g: function () {
    return this.c();
  },
};

console.log(obj.g()); // undefined

obj.g() returns undefined, because for normal functions this binding is based entirely on how the function is called, whereas arrow functions use lexical scoping for this binding. Although c() is called inside g() which is a normal function and is invoked through obj, c() is not defined within g(), its enclosed scope is global, thus it returns undefined:

const obj = {
  dev: 'bfe',
  g: function () {
    const c = () => {
      return this.dev;
    };

    return c();
  },
};

console.log(obj.g()); // "bfe"

const obj = {
  dev: 'bfe',
  c: () => {
    return this.dev;
  },
  h: function () {
    return this.c;
  },
};

console.log(obj.h()()); // undefined

obj.h()() returns undefined, because obj.h() returns a reference to the function c(), since c() is an arrow function, its this binding is based on the lexical scoping rather than call-site (how it is called), which means it adopts the this binding from its enclosed scope.


const obj = {
  dev: 'bfe',
  i: function () {
    return () => {
      return this.dev;
    };
  },
};

console.log(obj.i()()); // "bfe"

obj.i()() returns "bfe", because the arrow function defined inside i() lexically captures whatever its enclosed scope i()'s this is at its call time, in other words, the arrow function's this binding is not based on how it is called.

Reference

this All Makes Sense Now!