How does JavaScript work? Part 1. The execution environment, synchronous and asynchronous execution
By: Sean Hs
Tags: Front End Development, JavaScript, Software Development, Algorithms, ES6

6. This

What will this refer to?

The value of this is set based on how the function is called. There are four conditions.

Called by the normal function

“This” will refer to the global object. (window)

var person = {

firstname: 'Sean',

lastname: 'Hsieh',

getFullName: function() {

var name = function() {

return console.log(this.firstname + ' ' + this.lastname);

}

return name()

}

} person.getFullName() //undefined undefined

It will be undefined in the strict mode

'use strict'; var person = {

firstname: 'Sean',

lastname: 'Hsieh',

getFullName: function() {

var name = function() {

return console.log(this.firstname + ' ' + this.lastname);

}

return name()

}

} person.getFullName() //undefined undefined

2. A context object (Called by the object’s function)

“This” will refer to the object.

var person = {

firstname: 'Sean',

lastname: 'Hsieh',

getFullName: function() {

return console.log(this.firstname + ' ' + this.lastname);

}

} person.getFullName() //Sean Hsieh

“This” will refer to the global object when the method is assigned to a global object.

var fullname = 'allen' var obj ={

fullname: 'sean',

prop:{

fullname:'jack',

getFullname: function(){

return this.fullname;

}

}

} var test = obj.prop.getFullname

console.log(test()) //allen

console.log(obj.prop.getFullname()) //jack

3. A new object (Constructor)

It refers to the object

var person = function(){

this.firstname = 'Sean';

this.lastname = 'Hsieh';

this.getFullName = function() {

return console.log(this.firstname + ' ' + this.lastname);

}

} var p = new person()

console.log(p.firstname) //Sean

4. A specific object (Function.prototype.call, Function.prototype.apply)

Call or apply can change this dynamically.

var person = {

firstname: 'Sean',

lastname: 'Hsieh',

getFullName: function() {

return console.log(this.firstname + ' ' + this.lastname);

}

} var person2 = {

firstname: 'other',

lastname: 'other',

} person.getFullName.call(person2) //other

There are some methods to solve this problem. What’s the differences between call, apply, and bind?

1.apply: it invokes the function immediately and allows you to pass in arguments as an array. The first parameter is the given this value.

let numbers = [1, 2, 3];

let person = {firstName: 'sean', lastName: 'hsieh'};

function sum(num1, num2, num3) {

console.log(this.firstName + ' has ' + num1 + num2 + num3);

} sum.apply(person, numbers) //sean has 123

2.call: it invokes a function immediately with a given this value and arguments provided one by one.

let person = {firstName: 'sean', lastName: 'hsieh'};

function sum(num1, num2, num3) {

console.log(this.firstName + ' has ' + num1 + num2 + num3);

} sum.call(null, 1, 2, 3) //sean has 123

3.bind: it returns a new function instead of the result.

let person = {firstName: 'sean', lastName: 'hsieh'};

function sum(num1, num2, num3) {

console.log(this.firstName + ' has ' + num1 + num2 + num3);

} var newSum = sum.bind(person); newSum(1, 2, 3) //sean has 123

How to solve undefined?

1.Use Closure (self)

var person = {

firstname: 'Sean',

lastname: 'Hsieh',

getFullName: function() {

var self = this;

var name = function() {

return console.log(self.firstname + ' ' + self.lastname);

}

return name()

}

} person.getFullName() //Sean Hsieh

2.Use bind

var person = {

firstname: 'Sean',

lastname: 'Hsieh',

getFullName: function() {

var name = function() {

return console.log(this.firstname + ' ' + this.lastname);

}.bind(this)

return name()

}

} person.getFullName() //Sean Hsieh

3.Use arrow function (ES6)

this binds in an arrow function is lexical. It means that the arrow function doesn’t have a stand-alone this value binding. The arrow function will capture ‘this’ according to the scope train.

this value in the following function will be getFullName