Last active
December 17, 2015 11:39
-
-
Save thoov/5603594 to your computer and use it in GitHub Desktop.
Javascript Invocation Types
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
There are four patterns of invocation in JavaScript: | |
- the method invocation pattern | |
- the function invocation pattern | |
- the constructor invocation pattern | |
- the apply invocation pattern | |
The patterns differ in how the bonus parameter this is initialized. | |
From Douglas Crawford's Javascript the Good Parts | |
Method Invocation Pattern | |
When a function is stored as a property of an object, we call it a method. | |
When a method is invoked, this is bound to that object. | |
If an invocation expression contains a refinement (that is, a . dot expression or [subscript] expression), | |
it is invoked as a method: | |
*/ | |
var myObject = { | |
value: 0, | |
increment: function (inc) { | |
this.value += typeof inc === 'number' ? inc : 1; | |
} | |
}; | |
myObject.increment(); | |
document.writeln(myObject.value); // 1 | |
myObject.increment(2); | |
document.writeln(myObject.value); // 3 | |
/* | |
Function Invocation Method | |
When a function is not the property of an object ie: var sum = add(3, 4), then it is invoked as a function. | |
When a function is invoked with this pattern, this is bound to the global object. | |
This was a mistake in the design of the language. Had the language been designed correctly, when the inner function is invoked, | |
this would still be bound to the this variable of the outer function. | |
A consequence of this error is that a method cannot employ an inner function to help it do its work because the inner | |
function does not share the method’s access to the object as its this is bound to the wrong value. | |
Fortunately, there is an easy workaround. If the method defines a variable and assigns it the value of this, | |
the inner function will have access to this through that variable. By convention, the name of that variable is that. | |
*/ | |
myObject.double = function () { | |
var that = this; // Workaround. | |
var helper = function () { | |
that.value = add(that.value, that.value); | |
}; | |
helper(); // Invoke helper as a function. | |
}; | |
myObject.double(); // Invoke double as a method. | |
document.writeln(myObject.getValue()); // 6 | |
/* | |
Constructor Invocation Method | |
JavaScript is a prototypal inheritance language. That means that objects can inherit | |
properties directly from other objects. The language is class-free. This is a radical departure | |
from the current fashion. Most languages today are classi- cal. Prototypal inheritance | |
is powerfully expressive, but is not widely understood. JavaScript itself is not confident | |
in its prototypal nature, so it offers an object-making syntax that is reminiscent of the classical | |
languages. Few classical programmers found prototypal inheritance to be acceptable, and classically | |
inspired syntax obscures the language’s true prototypal nature. It is the worst of both worlds. | |
If a function is invoked with the new prefix, then a new object will be created with a hidden | |
link to the value of the function’s prototype member, and this will be bound to that new object. | |
The new prefix also changes the behavior of the return statement. We will see more about that next. | |
*/ | |
// Create a constructor function called Quo. | |
// It makes an object with a status property. | |
var Quo = function (string) { | |
this.status = string; | |
}; | |
// Give all instances of Quo a public method called get_status. | |
Quo.prototype.get_status = function () { | |
return this.status; | |
}; | |
// Make an instance of Quo. | |
var myQuo = new Quo("confused"); | |
document.writeln(myQuo.get_status()); // confused | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment