Javascript static / singelton is vs _this vs object name
This is a matter of performance and best practice.
Assuming I have a js object that encapsulates a large number of helper methods. An object is treated as a static class, meaning it is never created and all of its methods are basically helper methods. With events and jQuery, the scope of the objects this
keeps changing, and since it has quite a lot of methods, I'm wondering which is the best thing to keep this
in _this
the beginning of each method, or just use the name of the object MyObject
.
Over the years I've done both when it comes to singleton static objects, but I figured there should only be one best practice, and it takes time to take the best approach.
My current research shows that the benefits of using it _this
instead of a direct call MyObject
are mainly as follows:
- If the object name changes
_this
will always work - Might be faster (though haven't seen any performance test results) since the browser stays in the same scope and doesn't have to scoped every time
MyObject
.
Pros of using MyObject
:
- Less code to write.
- Garbage collection management? (fewer variables to assign)
- Might be more readable for some developers (where several apply
this
) - Easier to refactor your code as
MyObject
it will always work
I would like to know if there is a way to globally save _this
(only inside the object's scope) and not assign it at the beginning of each method. If not - are there other pros / cons that I am missing or is it considered bad practice to directly access the object name.
This is a simplified object for reference (real object has many other methods).
var MyObject = {
init: function() {
this.registerEvents();
//other stuff
},
registerEvents: function() {
this.registerOnSomeEvent();
//registering more events..
//...
},
registerOnSomeEvent: function() {
var _this = this;
jQuery('#someid').click(function() {
_this.doSomething();//option 1
MyObject.doSomething();//option 2
});
},
doSomething: function() {
//doing something...
}
}
MyObject.init();
Thanks for your help!
source to share
You can encapsulate the entire object in a closure to achieve this without specifying _this
for each function:
window.MyObject = (function () {
var self = {
init: function() {
self.registerEvents();
//other stuff
},
registerEvents: function() {
self.registerOnSomeEvent();
//registering more events..
//...
},
registerOnSomeEvent: function() {
jQuery('#someid').click(function() {
self.doSomething();//option 1
self.doSomething();//option 2
});
},
doSomething: function() {
//doing something...
}
};
self.init();
return self;
})();
source to share
I think your problem is that you have been trying for a very long time to imitate something that you should be doing.
const mySingleton = (function () {
// Instance stores a reference to the Singleton
var instance;
function init() {
// Singleton
// Private methods and variables
var privateVariable = "Im also private";
var privateRandomNumber = Math.random();
return {
// Public methods and variables
publicMethod: function () {
console.log( "The public can see me!" );
},
publicProperty: "I am also public",
get randomNumber() {
return privateRandomNumber;
}
};
function privateMethod(){
console.log( "I am private" );
}
};
return {
// Get the Singleton instance if one exists
// or create one if it doesn't
get instance() {
if ( !instance ) instance = init();
return instance;
}
};
})();
If you don't want to ever use context this
, never use inheritance, and never have more than one instance, just don't write these things as methods on an object, but rather declare private methods in a singleton pattern (which is a revealing module pattern, but only with one copy)
Because since you basically do exactly that, but you disclose everything and you spam this
hundreds and hundreds of times completely without any purpose. this
not constant by design. Don't use it as such.
source to share