JavaScript `this` and Arrow Function Code Traces
Six traces covering lost-`this` on extracted methods, arrow inherits-from-enclosing, function-as-constructor return, IIFE `this`, and static vs prototype methods.
1,063 views
34
What does the following code print, and what is the minimal fix?
Examples
Example 1:
Input: sayName()
Output: undefined
Explanation: Extracting student.getName into a bare reference detaches the method, so this is the global object (or undefined in strict mode) and this.name is undefined.let student = {
name: 'foo',
getName() {
return this.name;
},
};
let sayName = student.getName;
console.log(sayName());What is the output of the following code, and why does the IIFE break the binding?
Examples
Example 1:
Input: obj.innerMsg()
Output: undefined
Explanation: The inner IIFE is invoked as a plain function with no receiver, so its this is the global object (or undefined in strict mode) and this.msg is undefined.const obj = {
msg: 'Hi',
innerMsg: function () {
(function () {
console.log(this.msg);
})();
},
};
obj.innerMsg();What does the following code print? Why is the assignment Student.getName = ... the wrong approach?
Examples
Example 1:
Input: student1.getName()
Output: TypeError: student1.getName is not a function
Explanation: Student.getName attaches a static to the constructor function itself, not to Student.prototype, so instances cannot find getName.function Student(name) {
this.name = name;
}
Student.getName = function () {
console.log(this.name);
};
let student1 = new Student('foo');
student1.getName();What does the following code print, and why do the two methods disagree?
Examples
Example 1:
Input: student.getName(); student.getLastName();
Output: foo; undefined
Explanation: Regular methods bind this at the call site, while arrow methods capture this lexically at definition time, so the arrow cannot see student.const student = {
name: 'foo',
lastName: 'bar',
getName: function () {
return this.name;
},
getLastName: () => {
return this.lastName;
},
};
console.log(student.getName());
console.log(student.getLastName());What does this code print? What does the constructor-style function return when called WITHOUT new?
Examples
Example 1:
Input: studentScoreInfo.score; studentScoreInfo.name
Output: 100; undefined
Explanation: Without new the function returns the literal { score }, and this.name silently writes to the global object instead of the returned object.function studentScore() {
var score = 100;
this.name = 'John';
return { score };
}
var studentScoreInfo = studentScore();
console.log(studentScoreInfo.score);
console.log(studentScoreInfo.name);What is the output of each call below? Pay attention to which functions are method shorthand vs arrow expressions.
Examples
Example 1:
Input: student.getName_1(); student.getName_2(); student.getThis_1(); student.getThis_2().name
Output: undefined; foo; enclosing this (top-level {} or globalThis); foo
Explanation: Arrow methods capture the surrounding lexical this at definition, while regular method shorthands bind this to the receiver at the call site.const student = {
name: 'foo',
getName_1: () => this.name,
getName_2: function () { return this.name; },
getThis_1: () => this,
getThis_2() { return this; },
};
console.log(student.getName_1());
console.log(student.getName_2());
console.log(student.getThis_1());
console.log(student.getThis_2().name);