I find myself needing:
var self = this;
a lot within my javascript 'classes'. Although this is commonly done, it feels a bit wrong.
What I'm hoping to find in this question is a better way to deal with this, or a something to convince me this is quite alright.
Is this the standard way to keep the correct bindings around? Should I standardize on using 'self' everywhere, unless i explicitly need 'this'.
edit: I know exactly why I need this, I'm just wondering if it's considered a bit evil and why. I'm aware there's also the 'apply' built-in javascript function to explicitly define scope when calling a method. Is it better?
As others have said: This "extra variable" is (at some level) the only way to get about the fact that this is a special expression and thus, being not a variable, is not bound in an execution context/closure.
However, what I think you are asking (or what I really want to answer) is:
Should one put var self = this at the top of every method/constructor?
Summary
While I tried this once, and had the same question, I no longer use this approach. Now I reserve the construct for when I need access in a closure. To me it adds a little "hey, this is what I really want!" semantic to my code:
this -> this and self -> this (but really that) in a closure
Questions ala carte:
...Although this is commonly done, it feels a bit wrong. What I'm hoping to find in this question is a better way to deal with this, or a something to convince me this is quite alright.
Do what feels right to you. Don't be afraid to try one method and switch back later (but please try to remain consistent within each project :-)
Is this the standard way to keep the correct bindings around? Should I standardize on using 'self' everywhere, unless i explicitly need 'this'.
"self" is the most common name used. As per above, I prefer the opposite approach -- to use this except when a closure binding is required.
..if it's considered a bit evil and why.
Evil is a silly subjective term (albeit fun sometimes). I've never said it was evil, just why I do not follow the approach. Some people tell me I am "evil" for not using semi-colons. I tell them they should actually come up with good arguments and/or learn JavaScript better :-)
I'm aware there's also the 'apply' built-in javascript function to explicitly define scope when calling a method. Is it better?
The problem with apply/call is that you must use them at point of the function invocation. It won't help if someone else calls one of your methods as the this may already be off. It's most useful for doing things like the jQuery-style callbacks where the this is the element/item of the callback, etc.
As an aside...
I like to avoid "needing self" on members and thus generally promote all member functions to properties where the receiver (this) just "flows through", which is normally "as expected".
The "private" methods in my code begin with a "_" and if the user calls them, that's on them. This also works better (is required, really) when using the prototype approach to object creation. However, Douglas Crockford disagrees with this "private" approach of mine and there are some cases where the look-up chain may thwart you by injecting an unexpected receiver:
Using the "self" bound in the constructor also locks the upper limit of the look-up chain for a method (it is no longer polymorphic upward!) which may or may not be correct. I think it's normally incorrect.
Happy coding.
Yes, this is the standard way.
Function.apply() and Function.call() can help, but not always.
Consider the following
function foo()
{
var self = this;
this.name = 'foo';
setTimeout( function()
{
alert( "Hi from " + self.name );
}, 1000 );
}
new foo();
If you wanted to do this but avoid the usage of a variable like self and use call() or apply() instead... well... you look at it and start to try, but soon realize you just can't. setTimeout() is responsible for the invocation of the lambda, making it impossible for you to leverage these alternate invocation styles. You'd still end up creating some intermediary variable to hold a reference to the object.
Is this the standard way to keep the correct bindings around?
There is no standard, where JavaScript and class/instance systems are concerned. You will have to choose what kind of object model you prefer. Here's another link to a backgrounder; conclusion: there is no conlusion.
Typically keeping a copy var self= this;(*) in a closure goes hand-in-hand with an object model built around closures with per-instance copies of each method. That's a valid way of doing things; a bit less efficient, but also typically a bit less work than the alternative, an object model built around prototyping, using this, apply() and ECMAScript Fifth Edition's bind() to get bound methods.
What could be counted more as ‘evil’ is when you have a mish-mash of both styles in the same code. Unfortunately a lot of common JS code does this (because let's face it, no-one really understands JavaScript's bizarre native object model).
(*: I typically use that instead of self; you can use any variable name you like, but self already has an somewhat obscure and completely pointless meaning as a window member that points to the window itself.)
Just came across this question because my coworkers addicted to self/that variables and I wanted to understand why...
I think there is a better way to deal with this in nowdays:
function () {}.bind(this); // native
_.bind(function () {}, this); // lodash
$.proxy(function () {}, this); // jquery
In javascript and other languages with closures, this can be a very important thing to do. The object that this refers to in a method can actually change. Once you set your self variable equal to this, then self will reliably remain a reference to the object in question, even if this later points to something different.
This is an important difference in javascript compared to many other languages we work in. I'm coming from .Net, so this type of thing seemed strange to me at first too.
Edit:
Ah, okay, you know all that. (maybe still helpful for someone else.) I'll add that Apply (and Call) are more for using from "the outside", giving to a function you're calling a specific scope that you already know about. Once you're inside a function and you're about to cascade further down into closures, the technique:
var self = this;
is the more appropriate way (easy and clear) way to anchor your current scope.
It's 6 years later, and I have some things to add myself:
bind() is now common enough to be used everywhere. I use it often as an alternative. Sometimes it feels clearer. I still on occasion use var self = this;. though.
Arrow functions slowly are becoming viable for usage. The syntax is a bit shorter which is nice, but I think the killer feature really is that by default they always bind to the parent scope.
This:
var self = this;
var foo = function(a) {
return self.b + a;
};
Can now be written as :
var foo = a => this.b + a;
This is the 'most optimistic' usage of arrow functions, but it's pretty sweet.
And just to concluse, there's nothing wrong with:
var self = this;
Most likely this is done as a way to maintain a reference to this when the scope is about to change (in the case of a closure). I don't know that I'd consider it a bad practice or pattern in and of itself, no. You see similar things a lot with libraries like jQuery and a great deal with working with AJAX.
I think there's an argument to be made for always including var self = this in every method: human factors.
It's needed often enough that you wind up having a mishmash of methods accessing this and others using self for the same purpose. If you move code from one to the other, suddenly you get a bunch of errors.
At the same time, I catch myself absent-mindedly writing self.foo out of habit when I haven't needed or added a var self = this. So I think it could make sense to just make a habit of always including it, needed or not.
The only trouble is... this, self, or that are all an ugly pox on your code and I kind of hate them all. So I think it is better to avoid using delegated methods where possible so that you can avoid using this, that or self the vast majority of the time, and use .bind(this) when you might otherwise resort to self/that. It's very rare that using delegates on the prototype is actually going to save you any substantial amount of memory anyway.
A nice side effect of that approach is that you don't have to prefix all your private variables with _, as they will be truly private and the public properties will be called out by the leading this., making your code more readable.
As bobince said, var that = this is better because it doesn't shadow window.self. self = this sounds less awkward to me, but sometimes you get confusing error messages like property myMethod not found on global, because you forgot the self = this line.
I just want to point out that 'self' is equivalent to 'window', try outputting window === self to the console. You should use this pattern with 'that' or something similar as a variable name, avoid using 'self' since it is already in use by the browser (one mistake and you will create yourself a global variable).
Even though it sounds weird, it is better to use 'that' for its name because other developers will immediately know what you were trying to accomplish in your code, avoid using nonstandard variable names.
I believe that this is an important note, but it was only mentioned in one comment, so I wanted to make it more visible.
This was useful at some point in time, using closure to pass scope, but if you're looking for the standard way of developing and handle the scope properly, use :
myFunction.bind(this)
or like some people suggest the arrow function.
On thing to keep in mind : having a variable replace this is not straight forward and can lead to confusion. If it's needed, it's the sign that the code is not structured optimally.
I like it. It is "self"-explanatory. Douglas Crockford has some things to say about this. He states that using "that" is convention. You can see Crockford for free if you scoot over to yui-theater and watch hes videos about Javascript.
Related
I'm in the middle of trying to figure out at least parts of enyo's fantastic dropzone.js. I'm fairly green with JavaScript train of thought and the prototype paradigm. There's a line of code right on the fourth row that I'm wondering what it does and why would one use a line like that. The line looks as follows:
var __slice = [].slice
Have I understood correctly, that this takes the slice function from the array prototype object and just gives it a bit easier way to refer to it? What is the benefit of this approach? And why the double-underscore at the beginning? I read somewhere, that this would be to avoid conflicts in the global scope, but isn't this already avoided by wrapping the whole code in the
(function() { //code here
}).call(this);
construct?
Have I understood correctly, that this takes the slice function from the array prototype object and just gives it a bit easier way to refer to it?
Yes.
What is the benefit of this approach?
__slice is shorter than Array.prototype.slice (which also requires a couple of extra layers of property lookup), and [].slice in theory creates and throws away an object. So having an identifier for it is just saving some typing and the tiniest, tiniest, tiniest bit of runtime performance.
And why the double-underscore at the beginning? I read somewhere, that this would be to avoid conflicts in the global scope, but isn't this already avoided by wrapping the whole code in the ...
Yes, it is already avoided by doing that. In this case, it would just be a convention the author wanted to use, perhaps to indicate that this is his/her shortcut to Array.prototype.slice. The __ has no intrinsic meaning.
Context
In a typical JavaScript OO class when you have for e.g.
function parent(){
this.a = "parent";
this.child = function(){
console.log(this.a); //undefined
}
}
Now I know that you can reference the parent this by using:
var that = this;
Question
Is this considered good, bad or neutral practice? And I guess maybe guide me on things to look out for in terms of performance or possibly alternative methods.
Note: I have read some other stackoverflow question/answers but they are more requesting how to use it rather than what the issues are with using it, if any.
Is this considered good, bad or neutral practice?
It's completely normal practice. It's fundamental to how JavaScript works. As long as it's appropriate to the situation, there's nothing wrong with it.
Subjective:
Using that for this is a pet peeve of mine. It makes no sense whatsoever to call it that. It is, however, common practice. :-) I frequently use self and it's quite common (not as common as that). As pointed out in the comments, it slightly opens you to debugging hassles because self is a global on browsers (it's similar to window). Another one I common do is to pick a noun related to what the thing actually is, which adds semantic value. For instance, if this refers to a Whatsit instance, I might use whatsit or theWhatsit. Another suggestion is below is _this (with the underscore). A decent IDE will color that differently from this, reducing your odds of misreading it, but there's that concern.
But this is purely a style choice, and that is a choice a lot of people make.
I'm working on an application framework written as an object literal and for the sake of simplicity I'd like to do two things:
Have the object available globally
Use the object name (as globally defined) for all references (vs. using this)
So, I've run some tests, done research, and am not finding any good reason NOT to take this approach. My question is - am I missing something? Perf tests actually seem to favor my method and from a logistical level I don't see any issues. Looking at other frameworks I've seen a mix, but I know that the this reference is revered by many programmers.
For reference...
A very minimal example of my approach:
var myobj = {
someVal: 'foo',
init: function(){
// Make myobj available globally
window.myobj = myobj;
// Fire off a method
myobj.doStuff();
},
doStuff: function(){
// Just print out the contents...
console.log(myobj.someVal);
}
}
myobj.init();
Note the references are all to the global, not this.
Like I said, I've seen a mix of this, I guess I just would like to know if this could cause issues in the long-run or if this a much ado about nothing.
As far as limitations go, the first thing that comes to mind is that you could only have one instance of this object. Trying to initialize a new one would wipe out the object.
Another reason for using this rather than a global variable name is that this will point to the correct object even if the name of the variable changes.
If you really want this to be a "create once" global object whose name never changes then this technique isn't technically wrong. But it won't be able to be used in any other situation. It is probably wiser to consider writing code that will be more adaptable if the requirements change (for instance if you use a library that causes a naming conflict with the chosen variable name)
Using this lets you be flexible in renaming the variable and passing it in different contexts without worrying about tracking variable names. It also will make it easy to change if naming conflicts arise.
We have been debating how best to handle objects in our JS app, studying Stoyan Stefanov's book, reading endless SO posts on 'new', 'this', 'prototype', closures etc. (The fact that there are so many, and they have so many competing theories, suggests there is no completely obvious answer).
So let's assume the we don't care about private data. We are content to trust users and developers not to mess around in objects outside the ways we define.
Given this, what (other than it seeming to defy decades of OO style and history) would be wrong with this technique?
// namespace to isolate all PERSON's logic
var PERSON = {};
// return an object which should only ever contain data.
// The Catch: it's 100% public
PERSON.constructor = function (name) {
return {
name: name
}
}
// methods that operate on a Person
// the thing we're operating on gets passed in
PERSON.sayHello = function (person) {
alert (person.name);
}
var p = PERSON.constructor ("Fred");
var q = PERSON.constructor ("Me");
// normally this coded like 'p.sayHello()'
PERSON.sayHello(p);
PERSON.sayHello(q);
Obviously:
There would be nothing to stop someone from mutating 'p' in unholy
ways, or simply the logic of PERSON ending up spread all over the place. (That is true with the canonical 'new' technique as well).
It would be a minor hassle to pass 'p' in to every function that you
wanted to use it.
This is a weird approach.
But are those good enough reasons to dismiss it? On the positive side:
It is efficient, as (arguably) opposed to closures with repetitive function declaration.
It seems very simple and understandable, as opposed to fiddling with
'this' everywhere.
The key point is the foregoing of privacy. I know I will get slammed for this, but, looking for any feedback. Cheers.
There's nothing inherently wrong with it. But it does forgo many advantages inherent in using Javascript's prototype system.
Your object does not know anything about itself other than that it is an object literal. So instanceof will not help you to identify its origin. You'll be stuck using only duck typing.
Your methods are essentially namespaced static functions, where you have to repeat yourself by passing in the object as the first argument. By having a prototyped object, you can take advantage of dynamic dispatch, so that p.sayHello() can do different things for PERSON or ANIMAL depending on the type Javascript knows about. This is a form of polymorphism. Your approach requires you to name (and possibly make a mistake about) the type each time you call a method.
You don't actually need a constructor function, since functions are already objects. Your PERSON variable may as well be the constructor function.
What you've done here is create a module pattern (like a namespace).
Here is another pattern that keeps what you have but supplies the above advantages:
function Person(name)
{
var p = Object.create(Person.prototype);
p.name = name; // or other means of initialization, use of overloaded arguments, etc.
return p;
}
Person.prototype.sayHello = function () { alert (this.name); }
var p = Person("Fred"); // you can omit "new"
var q = Person("Me");
p.sayHello();
q.sayHello();
console.log(p instanceof Person); // true
var people = ["Bob", "Will", "Mary", "Alandra"].map(Person);
// people contains array of Person objects
Yeah, I'm not really understanding why you're trying to dodge the constructor approach or why they even felt a need to layer syntactical sugar over function constructors (Object.create and soon classes) when constructors by themselves are an elegant, flexible, and perfectly reasonable approach to OOP no matter how many lame reasons are given by people like Crockford for not liking them (because people forget to use the new keyword - seriously?). JS is heavily function-driven and its OOP mechanics are no different. It's better to embrace this than hide from it, IMO.
First of all, your points listed under "Obviously"
Hardly even worth mentioning in JavaScript. High degrees of mutability is by-design. We're not afraid of ourselves or other developers in JavaScript. The private vs. public paradigm isn't useful because it protects us from stupidity but rather because it makes it easier to understand the intention behind the other dev's code.
The effort in invoking isn't the problem. The hassle comes later when it's unclear why you've done what you've done there. I don't really see what you're trying to achieve that the core language approaches don't do better for you.
This is JavaScript. It's been weird to all but JS devs for years now. Don't sweat that if you find a better way to do something that works better at solving a problem in a given domain than a more typical solution might. Just make sure you understand the point of the more typical approach before trying to replace it as so many have when coming to JS from other language paradigms. It's easy to do trivial stuff with JS but once you're at the point where you want to get more OOP-driven learn everything you can about how the core language stuff works so you can apply a bit more skepticism to popular opinions out there spread by people who make a side-living making JavaScript out to be scarier and more riddled with deadly booby traps than it really is.
Now your points under "positive side,"
First of all, repetitive function definition was really only something to worry about in heavy looping scenario. If you were regularly producing objects in large enough quantity fast enough for the non-prototyped public method definitions to be a perf problem, you'd probably be running into memory usage issues with non-trivial objects in short order regardless. I speak in the past tense, however, because it's no longer really a relevant issue either way. In modern browsers, functions defined inside other functions are actually typically performance enhancing due to the way modern JIT compilers work. Regardless of what browsers you support, a few funcs defined per object is a non-issue unless you're expecting tens of thousands of objects.
On the question of simple and understandable, it's not to me because I don't see what win you've garnered here. Now instead of having one object to use, I have to use both the object and it's pseudo-constructor together which if I weren't looking at the definition would imply to me the function that you use with a 'new' keyword to build objects. If I were new to your codebase I'd be wasting a lot of time trying to figure out why you did it this way to avoid breaking some other concern I didn't understand.
My questions would be:
Why not just add all the methods in the object literal in the constructor in the first place? There's no performance issue there and there never really has been so the only other possible win is that you want to be able to add new methods to person after you've created new objects with it, but that's what we use prototype for on proper constructors (prototype methods btw are great for memory in older browsers because they are only defined once).
And if you have to keep passing the object in for the methods to know what the properties are, why do you even want objects? Why not just functions that expect simple data structure-type objects with certain properties? It's not really OOP anymore.
But my main point of criticism
You're missing the main point of OOP which is something JavaScript does a better job of not hiding from people than most languages. Consider the following:
function Person(name){
//var name = name; //<--this might be more clear but it would be redundant
this.identifySelf = function(){ alert(name); }
}
var bob = new Person();
bob.identifySelf();
Now, change the name bob identifies with, without overwriting the object or the method, which are both things you'd only do if it were clear you didn't want to work with the object as originally designed and constructed. You of course can't. That makes it crystal clear to anybody who sees this definition that the name is effectively a constant in this case. In a more complex constructor it would establish that the only thing allowed to alter or modify name is the instance itself unless the user added a non-validating setter method which would be silly because that would basically (looking at you Java Enterprise Beans) MURDER THE CENTRAL PURPOSE OF OOP.
Clear Division of Responsibility is the Key
Forget the key words they put in every book for a second and think about what the whole point is. Before OOP, everything was just a pile of functions and data structures all those functions acted on. With OOP you mostly have a set of methods bundled with a set of data that only the object itself actually ever changes.
So let's say something's gone wrong with output:
In our strictly procedural pile of functions there's no real limit to the number of hands that could have messed up that data. We might have good error-handling but one function could branch in such a way that the original culprit is hard to track down.
In a proper OOP design where data is typically behind an object gatekeeper I know that only one object can actually make the changes responsible.
Objects exposing all of their data most of the time is really only marginally better than the old procedural approach. All that really does is give you a name to categorize loosely related methods with.
Much Ado About 'this'
I've never understood the undue attention assigned to the 'this' keyword being messy and confusing. It's really not that big of a deal. 'this' identifies the instance you're working with. That's it. If the method isn't called as a property it's not going to know what instance to look for so it defaults to the global object. That was dumb (undefined would have been better), but it not working properly in that scenario should be expected in a language where functions are also portable like data and can be attached to other objects very easily. Use 'this' in a function when:
It's defined and called as a property of an instance.
It's passed as an event handler (which will call it as a member of the thing being listened to).
You're using call or apply methods to call it as a property of some other object temporarily without assigning it as such.
But remember, it's the calling that really matters. Assigning a public method to some var and calling from that var will do the global thing or throw an error in strict mode. Without being referenced as object properties, functions only really care about the scope they were defined in (their closures) and what args you pass them.
After doing some research on the subject, I've been experimenting a lot with patterns to organize my jQuery code (Rebecca Murphy did a presentation on this at the jQuery Conference for example).
Yesterday I checked the (revealing) module pattern. The outcome looks a bit reminiscent of the YUI syntax I think:
//global namespace MyNameSpace
if(typeof MNS=="undefined"||!MNS){var MNS={};}
//obfuscate module, just serving as a very simple example
MNS.obfuscate = function(){
//function to create an email address from obfuscated '#'
var email = function(){
$('span.email').each(function(){
var emailAddress = $(this).html().replace(' [ # ] ','#');
$(this).html('' + emailAddress + '');
});
};
return {
email: email
};
}();
//using the module when the dom's ready
jQuery(document).ready(function($){
MNS.obfuscate.email();
});
In the end I had several modules. Some naturally included "private members", which in this case means variables and/or functions which were only of importance for other functions within this module, and thus didn't end up in the return statement.
I thought having connected parts of my code (everything which has to do with the search for example) combined in a module makes sense, gives the whole thing structure.
But after writing this, I read an article by John (Resig), where he also writes about the performance of the module pattern:
"Instantiating a function with a bunch of prototype properties is very, very, fast. It completely blows the Module pattern, and similar, out of the water. Thus, if you have a frequently-accessed function (returning an object) that you want people to interact with, then it's to your advantage to have the object properties be in the prototype chain and instantiate it. Here it is, in code:
// Very fast
function User(){}
User.prototype = { /* Lots of properties ... */ };
// Very slow
function User(){
return { /* Lots of properties */ };
}
(John mentions he is not against the module pattern "per se" though - just to let you know :)
Then I wasn't sure anymore if I was going into the right direction with my code. The thing is: I don't really need any private members, and I also don't think I need inheritance for the time being.
All I want for now is a readable/maintainable pattern. I guess this boils down to personal preference to a certain extend, but I don't wanna end up with readable code which has (rather serious) performance issues.
I'm no JavaScript expert and thus even less of an expert when it comes to performance testing. So first, I don't really know in how far the things John mentioned ("frequently-accessed function (returning an object) that you want people to interact with", lots of properties, etc.) apply to my code. The documents my code interacts with are not huge, with 100s or 1000s of elements. So maybe it's not an issue at all.
But one thing which came to my mind is that instead of just having
$('span.email').each(function(){
var emailAddress = $(this).html().replace(' [ # ] ','#');
$(this).html('' + emailAddress + '');
});
(inside the domready function), I create two "extra" functions, obfuscate and email, due to the use of the module pattern. The creation of additional functions costs some time. The question is: will it be measurable in my case?
I'm not sure if a closure is created in my example above (in an interesting post on the jQuery forum I read the following: "There is a philosophical debate on whether an inner function creates a closure if it doesn't reference anything on an outer function's variable object..."), but I did have closures in my real code. And even though I don't think I had any circular references in there, I don't know in how far this could lead to high(er) memory consumption/problems with garbage collection.
I'd really like to hear your input on this, and maybe see some examples of your code. Also, which tools do you prefer to get information on execution time, memory and CPU usage?
I also don't think I need inheritance for the time being
Indeed. This doesn't really apply to using modules as a namespace. It's about class instance analogues.
Objects you create by making every instance from a completely new {name: member} object are less efficient than objects you create using new Class with Class.prototype.name= member. In the prototype case the member value is shared, resulting in lighter-weight instances.
In your example MNS is a singleton, so there is no benefit to be had by sharing members through a prototype.
I'm not sure if a closure is created in my example above
Yes, it is. Even when no variables are defined in the outer function, there is still a LexicalEnvironment and scope object created for the outer function, with this and arguments bound in it. A clever JS engine might be able to optimise it away, since every inner function must hide this and arguments with their own copies, but I'm not sure that any of the current JS implementations actually do that.
The performance difference, in any case, should be undetectable, since you aren't putting anything significant in the arguments. For a simple module pattern I don't think there's any harm.
Also, which tools do you prefer to get information on execution time, memory and CPU usage?
The place to start is simply to execute the code 10000 times in a for-loop and see how much bigger new Date().getTime() has got, executed several times on as many different browsers as you can get hold of.
$(this).html().replace(' [ # ] ','#');
(What is this supposed to do? At the moment it will read the HTML of the span into a new String, replace only the first instance of [ # ] with #, and return a new String value. It won't change the existing content in the DOM.)
How much Javascript do you have? In my experience, on sites with lots of Javascript code on the pages, performance problems generally come from code that actually does things. Generally, problems stem from trying to do too many things, or trying to do some particular thing really badly. An example would be trying to do stuff like bind handlers to elements in table rows (big tables) instead of using something like "live".
My point is that things like how your modules or functions or whatever get organized is almost certainly not going to pose any sort of real performance issue on your pages. What is motivating you to go to all this trouble?