JavaScript sets a value of the execution context, "this", during execution.
Use cases/mistakes
For an example, we use a Menu constructor, that should accept an element and create a menu on it’s base as in the following:
function Menu(elem) {
// ...
}
// Usage
var elem = document.getElementById('Abhijeet') // a DOM element
var menu = new Menu(elem)
Set TimeoutWhen you setup
setTimeout, you may want it to reference the object:
function Mymenu(elem) {
setTimeout(function () {
alert(this) // window, not menu!
}, 1000)
}
new Mymenu(document.createElement('div'))
But this references the window, because setTimeout always executes the function in the window context.
Private method / local function
A local function is often used as a private method.
A simple call to privateMethod() uses "this" as the window.
function Mymenu(elem) {
function privateMethod() {
alert(this) // window, not menu!
}
// ... call private method
privateMethod()
}
new Mymenu(document.createElement('div'))
Binding with "var abhi = this".
First, we can store a reference to "this" in the closure.
In the following example, "this" is copied to a new variable "abhi". This variable is then used instead of "this".
function Mymenu(elem) {
var abhi = this
setTimeout(function () {
alert(abhi) // object! (menu)
}, 1000)
}
new Mymenu(document.createElement('div'))
Early bindingWe could use a helper function, "bind", that forces this.
The following is an example of such a function. It accepts a function "func" and returns a wrapper that calls "func" withthis = "fixThis".
For example:
function bind(func, fixThis) {
return function () {
return func.apply(fixThis, arguments)
}
}
Late bindingLate binding is a variation of bind with a slightly different behavior.
In short, it means “binding on call time”, instead of “immediate binding”.
Late Binding in Action
To use late binding, we use "bindLate" instead of "bind".
For example:
<!DOCTYLE HTML>
<html>
<body>
<script>
function bindLate(funcName, fixThis) { // instead of bind
return function () {
return fixThis[funcName].apply(fixThis, arguments)
}
}
function Mymenu(elem) {
this.Hello = function () { alert('Mymenu') }
elem.onclick = bindLate('Hello', this)
}
function BigMenu(elem) {
Mymenu.apply(this, arguments)
this.Hello = function () { alert('BigMenu') }
}
new BigMenu(document.body)
</script>
Click here. I'm a BigMenu!
</body>
</html>