October 19 2018
- https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Property_accessors
- https://developer.mozilla.org/en-US/docs/Learn/JavaScript/Objects/Object-oriented_JS
- https://developer.mozilla.org/en-US/docs/Learn/JavaScript/Objects/Object_prototypes
- http://crockford.com/javascript/prototypal.html
- http://javascript.info/class-patterns
- https://dmitripavlutin.com/gentle-explanation-of-this-in-javascript/
- http://crockford.com/javascript/private.html
- https://www.gamedev.net/blogs/entry/2265481-oop-is-dead-long-live-oop/
function Runner(name) {
console.log(this instanceof Rabbit); // => true
this.name = name;
}
function Rabbit(name, countLegs) {
console.log(this instanceof Rabbit); // => true
// Indirect invocation. Call parent constructor.
Runner.call(this, name);
this.countLegs = countLegs;
}
var myRabbit = new Rabbit('White Rabbit', 4);
myRabbit; // { name: 'White Rabbit', countLegs: 4 }
function Vehicle(type, wheelsCount) {
if (!(this instanceof Vehicle)) {
throw Error('Error: Incorrect invocation');
}
this.type = type;
this.wheelsCount = wheelsCount;
return this;
}
// Constructor invocation
var car = new Vehicle('Car', 4);
car.type // => 'Car'
car.wheelsCount // => 4
car instanceof Vehicle // => true
// Function invocation. Generates an error.
var brokenCar = Vehicle('Broken Car', 3);
function Foo () {
console.log(this instanceof Foo); // => true
this.property = 'Default Value';
}
// Constructor invocation
var fooInstance = new Foo();
fooInstance.property; // => 'Default Value'
function Foo () {
console.log(this instanceof Foo); // => true
this.property = 'Default Value';
}
// Constructor invocation
var fooInstance = new Foo();
fooInstance.property; // => 'Default Value'
vs.
class Bar {
constructor() {
console.log(this instanceof Bar); // => true
this.property = 'Default Value';
}
}
// Constructor invocation
var barInstance = new Bar();
barInstance.property; // => 'Default Value'
function multiply(number) {
'use strict';
return this * number;
}
// create a bound function with context
var double = multiply.bind(2);
// invoke the bound function
double(3); // => 6
double(10); // => 20
Contrary to .apply() and .call() methods (see 5.), which invokes the function right away, the .bind() method only returns a new function that it supposed to be invoked later with a pre-configured this. .bind() makes a permanent context link and will always keep it. A bound function cannot change its linked context when using .call() or .apply() with a different context, or even a rebound doesn’t have any effect.
var numbers = {
array: [3, 5, 10],
getNumbers: function() {
return this.array;
}
};
// Create a bound function
var boundGetNumbers = numbers.getNumbers.bind(numbers);
boundGetNumbers(); // => [3, 5, 10]
// Extract method from object
var simpleGetNumbers = numbers.getNumbers;
simpleGetNumbers(); // => undefined or throws an error in strict mode
Because the function invocation has the biggest impart on this, from now on do not ask yourself:
Where is this taken from?
but do ask yourself:
How is the function invoked?
For an arrow function ask yourself:
What is this where the arrow function is defined?
JavaScript is kind of funny.
See you next time!
Unless otherwise mentioned in the post, those projects are side projects which I work on on weekends and evenings, and are not affiliated with my work or employer.
Tags: software engineering, personal development | Report a bug via Twitter