Let’s say we have an example of code like this:
(function(){
function close_window() {
if (typeof self.close === 'function') {
self.close();
}
}
// and somewhere in the code above method is called many times
function some_action() {
// here some code
close_window();
}
}());
Note: method close_window
could be written in a better way, but in that case I wanted to show just a simple example.
Some time later someone did more changes and then after all the code may looks like:
if (!window.myNamespace) {
window.myNamespace = {};
}
(function(){
var self = window.myNamespace;
// tons of code here
function close_window () {
if (typeof self.close === 'function') {
self.close();
}
}
// and somewhere in the code above method is called many times
function some_action() {
// here some code
close_window();
}
}());
Note: self
is just used here as a reference to object window.myNamespace
. It’s just like in PHP
where the self
refer to the current class. In this case our class
represent just object window.myNamespace
.
Ok, you may ask: “So what about those changes?“.
Well, previously you expected that calling close_window
will close current window. However, after changes you will notify that something went wrong. Closing window stopped working, but previously everything was fine. When you open the browser console then you may notify error TypeError: self.close is not a function
.
So, what’s happened?
In case of self.close();
browser script “engine” will search through the scope chain (up to the global object; window
in browsers), until an self-named function is found. If somebody (for any reason, e.g. accidentally) defines an self
elsewhere in the scope chain, it will be called instead. That’s why using full reference to object (in our case we calling function
to close current window) will guarantee that we’ll call what we expect.
So, the right version should be:
(function(global){
// "global" represent "window" object in browsers
function close_window() {
if (typeof global.self.close === 'function') {
global.self.close();
}
}
// and somewhere in the code above method is called many times
function some_action() {
// here some code
close_window();
}
}(this));
And now you can use var self = 'whatever you want';
at the top of current scope. So, the benefits to use full reference to specified object is not only that this may prevent for some errors like described above, but it is even faster execution since browser do not have to go through all scopes to find specified object.
Leave a Reply