Proper javascript context capture
Quite often, in many articles, I see people grab this context for use in an anonymous function and am surprised that what has already become the standard is just a terrible practice that contradicts all the canons of programming. Do you know such a record?
Maybe you should also rethink this aspect?
So an example:
Another example (jQuery):
What do you say about them?
I believe that the names of the variables self and $ this (as well as that, _this, t) are evil. Evil lies for two reasons.
First, the names do not carry a semantic load at all. In the same miracle, we could use, say, the
Second - sometimes contexts can multiply and intersect, and then confusion arises. For example, when functions are nested inside one another:
You should always give sane names to variables. This rule does not apply to context in JS, but to programming as a whole, but during context capture everyone forgets about it. For instance:
This will solve the problem with nested functions.
But more often than not, such a variety of contexts is required. So let's look at another way:
I got this idea from the MooTools framework and I think it's great. Extend Function prototype a bit
Now we can not lose context throughout the work. If we need only an external context, we directly indicate this and the code becomes much more transparent:
It often happens that in order to work with the method of the object you have to fence a very ugly design. For example (example on MooTools):
we cannot pass to the get method just a reference to the parse method:
because then the context of the method is lost. The bind method will help us with this and we see how much clearer this code has become:
A small piece of code from the Bridge card game on LibCanvas demonstrating the use of bind.
The essence of asynchrony is that the AI should not take any action while the map is flying.
For example, he takes a card from the deck, but can put it there only after the card reaches, otherwise the effect will be unpleasant for the player.
vl.vg/28.01.2010/tooltip-jquery
blog.kron0s.com/javascript-programming-patterns_2
habrahabr.ru/blogs/jquery/52185
var self = this;
Maybe you should also rethink this aspect?
So an example:
var self = this;
asyncFunc(function () {
self.callMethod();
});
Another example (jQuery):
$('input').bind('keydown', function () {
var $this = $(this);
$this.css({
background : $this.val()
});
});
What do you say about them?
Hatred
I believe that the names of the variables self and $ this (as well as that, _this, t) are evil. Evil lies for two reasons.
First, the names do not carry a semantic load at all. In the same miracle, we could use, say, the
var killmeplz = this;
Second - sometimes contexts can multiply and intersect, and then confusion arises. For example, when functions are nested inside one another:
var self = this;
asyncFunc(function () {
var self2 = this; // wtf ?!!
setTimeout(function () {
self.callMethod(self2);
}, 200);
});
Solution one - name variables correctly
You should always give sane names to variables. This rule does not apply to context in JS, but to programming as a whole, but during context capture everyone forgets about it. For instance:
$('input').bind('keydown', function () {
var $colorInput = $(this);
$colorInput.css({
background : $colorInput.val()
});
});
This will solve the problem with nested functions.
$block = $(this);
$('button').each(function () {
var $button = $(this);
$.each(users, function () {
var user = this;
$block.append(user.init($button));
});
});
But more often than not, such a variety of contexts is required. So let's look at another way:
Force function context
I got this idea from the MooTools framework and I think it's great. Extend Function prototype a bit
Function.prototype.bind = function (scope) {
var fn = this;
return function () {
return fn.apply(scope, arguments);
};
};
Now we can not lose context throughout the work. If we need only an external context, we directly indicate this and the code becomes much more transparent:
asyncFunc(function () {
this.callMethod();
}.bind(this));
Other options for working with .bind
It often happens that in order to work with the method of the object you have to fence a very ugly design. For example (example on MooTools):
var Analizer = new Class({
initialize : function (name) {
this.dataRouter = new DataRouter[name]();
},
start : function () {
var analizer = this;
this.dataRouter.get(function (data) {
analizer.parse(data);
});
},
parse : function (data) {
// parsing data, using this.privateMethods
}
});
we cannot pass to the get method just a reference to the parse method:
dataGetter.get(analizer.parse);
because then the context of the method is lost. The bind method will help us with this and we see how much clearer this code has become:
var Analizer = new Class({
initialize : function (name) {
this.dataRouter = new DataRouter[name]();
},
start : function () {
this.dataRouter.get(
this.parse.bind(this)
);
},
parse : function (data) {
// parsing data, using this.privateMethods
}
});
A small piece of code from the Bridge card game on LibCanvas demonstrating the use of bind.
The essence of asynchrony is that the AI should not take any action while the map is flying.
For example, he takes a card from the deck, but can put it there only after the card reaches, otherwise the effect will be unpleasant for the player.
Bridge.AI = new Class({
// ..
putCardSmart : function (card) {
this.putCard( card,
// Этот метод вызовется только когда карта долетит, но он сохранит контекст.
this.finishSmart.bind(this)
);
},
getCardSmart : function () {
this.getCard(function (card) {
this.canPutCard(card) ?
this.putCardSmart(card) :
this.finishSmart();
}.bind(this)); // Мы захватываем контекст.
},
finishSmart : function () {
this.canFinishMove() ?
this.finishMove() :
this.movement();
}
// ..
});
Bad Tips Examples
vl.vg/28.01.2010/tooltip-jquery
blog.kron0s.com/javascript-programming-patterns_2
habrahabr.ru/blogs/jquery/52185