Skip to content

Instantly share code, notes, and snippets.

@lkaihua
Last active February 6, 2019 15:36
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save lkaihua/64844fd1a13b83f2a1fcf980eac1fb57 to your computer and use it in GitHub Desktop.
Save lkaihua/64844fd1a13b83f2a1fcf980eac1fb57 to your computer and use it in GitHub Desktop.
Javascript examples on `this`

A collection of code snippets explaining:

  • this
  • bind
  • arrow functions
var name = 'globalName';
const obj = {
name: 'myName',
sayName: function () { console.log(this.name);}
}
obj.sayName();
// output: myName
const say = obj.sayName;
// we are merely storing the function
// the value of `this` isn't magically transferred
say();
// output: globalName
// now because this function is executed in global scope
// `this` will refer to the global var
const boundSay = obj.sayName.bind(obj);
// now the value of this is bound to the obj object
boundSay();
// output: myName
// Now this will refer to the name in the obj object: 'myName'
const obj2 = {
name: "hisName"
};
const boundSay2 = obj.sayName.bind(obj2);
// obj2 has no function to say its name
// and we want to share the same function from obj
boundSay2();
// output: hisName
// what happened?
// `.bind` is creating a new function, with the given context
console.log(boundSay == obj.sayName)
// output: false
// reading
// 1. https://stackoverflow.com/questions/2236747/use-of-the-javascript-bind-method
// 2. https://gist.github.com/zcaceres/2a4ac91f9f42ec0ef9cd0d18e4e71262
this.age = 3;
const sayAge = () => {
console.log(this.age)
}
sayAge()
// output: 3
// An arrow function `() => {}` does not have its own `this`
// (and `arguments`, `super` or `new.target`).
// so calling add() is looking up `this.age` in upper scope
function Person() {
this.age = 30;
sayAge();
}
const p = new Person();
// output: 3
// instead of 30
// It proves that the arrow function is looking up `this.age` in a consistent manner,
// by always pointing to the context when it first *created*.
// how to fix
function Person2() {
this.age = 30;
const sayAge2 = () => {
console.log(this.age);
}
// define the arrow function in the context that we need it
sayAge2();
}
const p2 = new Person2();
// output: 30
// Following is a popular usage to create arrow function in class
// A1
class A1 {
constructor() {
this.counter = 0;
}
handleClick1 = () => {
this.counter++;
}
handleClick2() {
this.counter++;
}
}
// class A1 will be transpiled into
// class A2 by Babel
class A2 {
constructor() {
this.handleClick1 = () => {
this.counter++;
};
this.counter = 0;
}
handleClick2() {
this.counter++;
}
}
// The original intention is to declare an instance method by an arrow function
// `handleClick1`, however, the arrow function is moved into constructor after tranpiling
// as an instance member.
//
// The arrow function `handleClick1` is not in the prototype, with two shortcomings:
// 1. performance could be problematic since all instances create their own members.
// 2. can not be called by `super` since they are inside constructors.
// > You should only bind with .bind() or arrow function a method if you’re going to pass it around.
// reading
// 1. https://medium.com/@charpeni/arrow-functions-in-class-properties-might-not-be-as-great-as-we-think-3b3551c440b1
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment