https://bigfrontend.dev/quiz/6-Arrow-Function
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()());
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"
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.