I have to make sense of a codebase I was given on my new job. I can see many anti-patterns here, one of them is a "god object", which contains a lot of things and different object access it all the time. That's a different problem, my question here is about the fact, that some objects access its members using '.', others do it via [], for example
GOD.meow.woof()
in one source file and
GOD['meow']["woof"]()
in another.
I know javascript deeply enough to realize that there is no difference whatsoever. Or is there? git blame shows me that both sources were written by the same person, so it has nothing to do with style. On the one hand, what can you expect from a person, who don't hesitate to create god objects, on the other hand maybe he was in a hustle and eventually didn't have time to repay this technical debt, we'll never know.
Is it possible that using the latter method of access is safer in any way? Your opinions are welcome, fellows, before I launch my inner refactoring ninja.
A frequent reason: there's a minifier which needs the second form to know it must preserve the "meow" and "woof" names. That's especially convenient with Google Closure.
Other than that, there's no reason, as you already saw in the documentations (using special characters and dynamic strings don't apply in your case).
Related
In the socket.io documentation, they use a nomenclature that doesn't look like javascript (though it's a javascript library) that seems a bit out of place.
Examples here: http://socket.io/docs/client-api/ (the page has changed since, here's a web archive snapshot as of 2014)
This one is clear enough (just specifying types of arguments and return value):
IO(url:String, opts:Object):Socket
But this style I don't recognize at all:
IO#protocol
Manager#timeout(v:Boolean):Manager
I can pretty much figure it out through deduction (though I find it hard to read because it looks so foreign), but where does this style come from and why? Is this from another language (it certainly isn't javascript syntax that I've ever seen)? Is there a name for it? Is there a description of this style of documenting objects, methods, properties?
FYI, the idea to ask this question came because I referred a user here on SO to the socket.io documentation and they came back and said that wasn't javascript, did I have a link to the javascript documentation. I had to explain that it was the javascript documentation, it was just a funky (non-javascript-like) documentation style.
The page in question has been rewritten since to use object.property instead, but I remember that Object#property style, though I don't think it's ever had a name.
The problem it's trying to solve is that properties/methods can be available on constructors like Array.isArray(), as well as on instances, like ['foo','bar'].join(' '). The question is how to denote the latter. There were some competing denotations, such as
array.join(), which is what the socket.io docs are using now
Array.prototype.join (technically correct, but arguably even more confusing than Array#join to anyone who doesn't know how prototypes work in JS)
Array#join(), invented to be clearly different from Array.join syntax, and to avoid confusion with any existing JavaScript syntax.
The Object#prototype syntax was somewhat popular ten years ago, but didn't win in the end, so now it's just confusing when you encounter it.
I'm currently working with a personal library that's accumulated quite a number of "helper" functions, which are used throughout my architecture for various purposes. Back when there were only a few of them, I kept them in a single file and object so I could access them like so:
tools.parseSomething(obj);
This has been terribly handy, and keeps the code still somewhat organised and readable. The problem is that the file (and object) containing these methods is growing to an enormous size, and needs a cleanup. I was considering creating separate files for "categories" of functions and placing them in those, so they'd be accessed like:
tools.env.getEnvironmentInfo();
My concern with this approach is not the readability so much, but the performance of the look-up. From what I've read recently, object look-ups are no longer the major bottle-neck they used to be, but I still want my library to be as efficient as possible (readability second).
I also considered having the separate files, but add all of the functions to the parent object so they're still accessible in the original way, but stored separately. The object containing the functions is "static" and exists as a single instance.
My question is, with regards to what I've explained, what would be the most efficient method of storing and using a large amount of helper functions? By efficiency I mean performance, which is the sole area of concern for me at the moment.
I'd agree that premature optimization is going on here, however that wasn't your question.
I'd assert that instead of thinking in terms of loosely related scriptlets that 'do kind of related things', I'd suggest an richer object model that can be stateful and perhaps expose the behaviors you need while hiding some optimizations you feel are necessary like caching lookups, etc.
So instead of getEnvironmentInfo, why not have an Environment instance that has, for example, already fetched some parameters and stored internally so subsequent calls are made faster. From there you can create new environments or whatever other behaviors suit you.
This is just good programming practice in whatever language.
I have been programming JavaScript for a fair while. I haven't ever taken a course or read guides/books as to best practices, but I've seemed to figure things out pretty well as I've gone. I know that my code isn't always the shortest and cleanest, but it's made sense for me.
I recently got into object-oriented programming and think that it's a great time to jump head-first into the language. While I know that it would be in my best interest to spend a few days pouring over OOP, I have a specific question that would help me in my attempts.
Making Variables Objects
I have a PhoneGap application, for example, that includes many functions each serially listed in split-up .js files. Everything worked okay, but I would have to keep passing the same few functions between every function, and the potential for error was fine. After reading into methods and objects a little, each page evolved to this usage:
var myPage = {
myVar1 : 'value',
myVar2 : 32,
initialize : function() {
//code that initialized the variables within this object
},
doSomething : function() {
//function that would do something with myPage vars
}
//...
};
Using this methodology, each page ended up as a grand variable with many encompassed methods and variables. This cleaned up quite a bit and greatly reduced global vars, but I still don't feel as though it's perfect. My shared .js files are broken into types and many objects, each with their own functions. My first question is: is this a bad thing, and if so, why? If I could get an explanation for my specific use, it would benefit me much more than seeing optimal examples in textbooks and guides.
Making Prototypes and Classes with a Single Instance
Looking at examples provided here and across the web and dead-tree publications, I see that objects and prototypical behavior is defined as a class, then instances of the class are created. Nothing that I need to do, however, seems to fit this budget, and I'm nearly positive that it's because I'm simply not thinking in the correct paradigm. However, if I have a function that validates input, how does that fit into a better OOP methodology?
I simply have a variable/object named validate that contains the functions necessary, then put that variable in the shared file. If I were to create it as a class and create an instance of it each time that I needed to validate something, doesn't that create a lot more overhead? I don't see how it works for applications such as this.
I think that OOP is the way to go, and I want to be part of it. Thanks in advance for all answers and comments.
My first question is: is this a bad thing, and if so, why?
Competent developers avoid having functions defined in the global scope (what you do when you write function() {} inside a script) because it pollutes the global scope, where many other scripts try to do the same. Think of it as many of us trying to make a better "share()" function on the same page - only one of us will win.
I see that objects and prototypical behavior is defined as a class, then instances of the class are created. Nothing that I need to do, however, seems to fit this budget, and I'm nearly positive that it's because I'm simply not thinking in the correct paradigm
There's not much you can do there. If you have a function that validates input, then it would be better as part of the element:
someElement.validate(); // as a prototype
instead of the conventional
validate(someElement); // as a global function
I recently watched Douglas Crockford's JavaScript presentations, where he raves about JavaScript prototype inheritance as if it is the best thing since sliced white bread. Considering Crockford's reputation, it may very well be.
Can someone please tell me what is the downside of JavaScript prototype inheritance? (compared to class inheritance in C# or Java, for example)
In my experience, a significant disadvantage is that you can't mimic Java's "private" member variables by encapsulating a variable within a closure, but still have it accessible to methods subsequently added to the prototype.
i.e.:
function MyObject() {
var foo = 1;
this.bar = 2;
}
MyObject.prototype.getFoo = function() {
// can't access "foo" here!
}
MyObject.prototype.getBar = function() {
return this.bar; // OK!
}
This confuses OO programmers who are taught to make member variables private.
Things I miss when sub-classing an existing object in Javascript vs. inheriting from a class in C++:
No standard (built-into-the-language) way of writing it that looks the same no matter which developer wrote it.
Writing your code doesn't naturally produce an interface definition the way the class header file does in C++.
There's no standard way to do protected and private member variables or methods. There are some conventions for some things, but again different developers do it differently.
There's no compiler step to tell you when you've made foolish typing mistakes in your definition.
There's no type-safety when you want it.
Don't get me wrong, there are a zillion advantages to the way javascript prototype inheritance works vs C++, but these are some of the places where I find javascript works less smoothly.
4 and 5 are not strictly related to prototype inheritance, but they come into play when you have a significant sized project with many modules, many classes and lots of files and you wish to refactor some classes. In C++, you can change the classes, change as many callers as you can find and then let the compiler find all the remaining references for you that need fixing. If you've added parameters, changed types, changed method names, moved methods,etc... the compiler will show you were you need to fix things.
In Javascript, there is no easy way to discover all possible pieces of code that need to be changed without literally executing every possible code path to see if you've missed something or made some typo. While this is a general disadvantage of javascript, I've found it particularly comes into play when refactoring existing classes in a significant-sized project. I've come near the end of a release cycle in a significant-sized JS project and decided that I should NOT do any refactoring to fix a problem (even though that was the better solution) because the risk of not finding all possible ramifications of that change was much higher in JS than C++.
So, consequently, I find it's riskier to make some types of OO-related changes in a JS project.
I think the main danger is that multiple parties can override one another's prototype methods, leading to unexpected behavior.
This is particularly dangerous because so many programmers get excited about prototype "inheritance" (I'd call it extension) and therefore start using it all over the place, adding methods left and right that may have ambiguous or subjective behavior. Ultimately, if left unchecked, this kind of "prototype method proliferation" can lead to very difficult-to-maintain code.
A popular example would be the trim method. It might be implemented something like this by one party:
String.prototype.trim = function() {
// remove all ' ' characters from left & right
}
Then another party might create a new definition, with a completely different signature, taking an argument which specifies the character to trim. Suddenly all the code that passes nothing to trim has no effect.
Or another party reimplements the method to strip ' ' characters and other forms of white space (e.g., tabs, line breaks). This might go unnoticed for some time but lead to odd behavior down the road.
Depending on the project, these may be considered remote dangers. But they can happen, and from my understanding this is why libraries such as Underscore.js opt to keep all their methods within namespaces rather than add prototype methods.
(Update: Obviously, this is a judgment call. Other libraries--namely, the aptly-named Prototype--do go the prototype route. I'm not trying to say one way is right or wrong, only that this is the argument I've heard against using prototype methods too liberally.)
I miss being able to separate interface from implementation. In languages with an inheritance system that includes concepts like abstract or interface, you could e.g. declare your interface in your domain layer but put the implementation in your infrastructure layer. (Cf. onion architecture.) JavaScript's inheritance system has no way to do something like this.
I'd like to know if my intuitive answer matches up with what the experts think.
What concerns me is that if I have a function in C# (for the sake of discussion) that takes a parameter, any developer who writes code that calls my function immediately knows from the function signature what sort of parameters it takes and what type of value it returns.
With JavaScript "duck-typing", someone could inherit one of my objects and change its member functions and values (Yes, I know that functions are values in JavaScript) in almost any way imaginable so that the object they pass in to my function bears no resemblance to the object I expect my function to be passed.
I feel like there is no good way to make it obvious how a function is supposed to be called.
As it currently stands, this question is not a good fit for our Q&A format. We expect answers to be supported by facts, references, or expertise, but this question will likely solicit debate, arguments, polling, or extended discussion. If you feel that this question can be improved and possibly reopened, visit the help center for guidance.
Closed 10 years ago.
This might come as a strange question to many of you, and I don't actually know if it is correct to say OOP in this context, because OOP (object-oriented programming) is usually associated with programming languages like C++ and Java, and not lightweight programming languages, or scripting languages. My question, however, is in the category of JavaScript, which is also object oriented. I do know about objects, properties, methods, prototypes and constructors, I just can't seem to get into my mind when to use objects.
When I am writing my web-applications, I, for some reason, never use objects. This annoys me, because when I read about objects in a variety of books and online articles, objects make everything so much simpler and, just to put it out there, I HATE repeating myself, and this is why I wish I knew when to use objects.
I really want to become better at using objects and when to use objects.
Can you please mention a few situations objects would be good? It would be really nice to have written down something you know you can go back and look at when you get confused about when to use these darn objects :)
I would love simple answers explaining why and when objects are to prefer.
I would also like if you could tell me if I am to use objects when I am in some special situations generally suitable for objects i.e. every time you want to _________ then you use an object...
I really hope you understand my question and you will consider that I'm somewhat new to this site and new to JavaScript
Thanks!
You probably use objects without even realizing it.
If you're writing Javascript that interacts with the DOM, you're using objects.
If you're using any of the Javascript frameworks out there (jQuery, MooTools, etc.), you're using objects.
Using objects will be useful when you need to encapsulate some commonly used code so that it can be easily re-used (within a single application or across multiple applications like jQuery plugins...which are objects in and of themselves).
And to answer the question in the title of your post...the only way to really get better at OOP is to practice! Reading and studying the subject can only get you so far.
First, you don't need to use objects to avoid repeating yourself. If you need to do the same thing at two points in your code, you can write a plain vanilla non-OOP function to do that and call it twice.
To summarize the advantages of OOP without writing a book here, OOP basically does three things for you:
Group related data together. Non-OOP programs often have a whole bunch of variables floating around in the main program that are only loosely related. With OOP, you put related variables into an object.
Associate functions with data. By putting functions in an object with the data they operate on (purists will say they are then "members" rather than "functions"), you make it clear to the reader that these go together.
Combining #1 and #2 lets you hide implementation details from other objects. You create the "public interface" for a class, the set of functions that other objects should call and that represent the logical things that this class does, and then any other functions you need can be hidden. (More explicitly in some languages than in others, but that's not the point here.)
Classes can inherit and mutate. If you have two similar classes A and B that should be mostly the same but with some minor differences, you can make a superclass C with all the common stuff and then A and B inherit from that and each adds in its own unique stuff. This is what is usually advertised as the power of OOP. Frankly, yes, it's way cool, and in some situations can be very handy, but I only use its true power occasionally, and I suspect the same is true of most programmers. (OOP enthusiasts feel free to jump in with how and why you use inheritance all the time.)
When to OOP it? Any time you have several pieces of data that logically go together, it makes sense to create a class to hold them. Like X and Y coordinates; or customer name, address, and zip code; or phaser range and phaser power consumption; or whatever.
Any time you have functions that logically operate on this related data, put them in the the class with the data. Like "capitalize customer name", "compute distance of this point from the origin", etc.
How and when to use inheritance is more complicated. I'll leave that for another time.
The first thing to remember, is that a lot of simple Javascript code really doesn't need to define objects (using them is inevitable, as all the stuff the DOM gives you are objects). Don't panic too much.
One of the good things about Javascript is that it supports a lot of different styles; OOP, imperative and functional.
One of the bad things about using Javascript is that because it supports a lot of different styles, it's hard to learn another style, at least until you are forced to an "a-ha" moment by something else.
Spending time in languages that are more inclined to force you into OOP (even when some would argue they shouldn't) is helpful here. C# and Java force one along OOP lines, though C++ does not (with the same strength and weakness here as with Javascript).
Try to think about the "things" in your program. Some of these things will already be modelled by objects (those the DOM gives you). Some really will just be numbers and strings and not worth composing beyond that (though learning how to add functionality to those types through prototype is a good idea too). Some will be "things" more complicated than a simple type and naturally suited to modelling as an object.
Do also look at functional programming in Javascript (e.g. passing a function as a parameter to another function is about the simplest example), as the interaction between this and OOP is one of the strongest elements in Javascript, and essential in defining methods on objects given the prototype-based OOP model it has.
My personal experience with OOP in JavaScript is a positive one, once I figured out to get it to do what I wanted of course, I usually use it in combination with jQuery so the resulting code can seem a bit.... odd.
function BlogPost(id,title,content)
{
this.id = id;
this.title = title;
this.content = content;
function display()
{
var post = $('<div class="blogpost"></div>');
$(post).append('<h2>' + this.title + '</h2>');
$(post).append('<p>' + this.content + '</p>');
var deleteButton = $('<span class="deletePost">delete</span>')
$(post).append(deleteButton);
$(deleteButton).click(this.delete)
$('#postcontainer').append(post);
}
function delete()
{
$.post('some/xhr/handeler',{id:this.id});
}
}
This is a quick (untested) class that can be used to dynamically add blogposts to a div with id postcontainer' and handles clicks on a delete button.
Think about how you can use objects to organize and simplify your application. I have found two metaphors useful:
A mechanical watch is made up of a number of gears, each of which serves a single purpose in the overall operation of the machine. If you think of your application as a watch, then objects are its gears.
A workgroup is made up of a number of people, each of whom performs a specific job. The people communicate with each other in performing their jobs, and the jobs fall along two lines--those that perform tasks (workers), and those that organize and direct the work of other people (managers).
You can use these metaphors to organize the work your application does. Start by dividing the app into functional layers; UI, business layer, and persistence, for example. Take each of your use cases, and distribute the work it does among these layers. That should give you a starting point for the classes you will need.
Make each class as self-contained a possible. you want to seal it off when it is done, like a .NET control. Classes should communicate with each other only through their interfaces, which are made up of properties and methods. These interfaces should have the smallest footprint (fewest public properties and methods) you can come up with. The idea is to isolate the side effects of a change to any class to that class alone.
If you do these things, you will be ahead of 80% of all programmers. You will find it much easier to develop and maintain even large applications, because you will be able to break complex problems down to simple components.
Javascript is just a terrible language to learn OOP in. I would recommend learning OOP in another language (like Java or C++) and then learn Object Oriented syntax in Javascript. At that moment you have all the ingredients.
That's when you can decide whether or not you want to be using an object for a task in Javascript or if it is enough to use just functions.
Personally, I mostly write non-object javascript and leave objects for when a task feels object oriented to me. For example, I used an object oriented design for a drag and drop script, in which you simply made a DragNDrop object with the correct parameters and the items in your page would be dragable from that moment on, or when I wanted to simplify some javascript xml handling functions, I wrote an object that wrapped the normal xml objects.
Justin Niessner said it and I can only add to his answer...
In addition to practice, I find reading other people's code very instructive. You need to be cautious because not all code is exemplary (to say the least) but developing critical skills is part of getting better.
In my opinion I think it's better to think about OOP in the context of a particular domain or business problem. For example, JavaScript uses objects to model browser behavior and attributes, e.g., Window, Frame, History...
A domain model of a business problem will contain objects that will be reflected in the programming code written OOP. For example, a university student application will have objects for students, professors, courses, curriculums, rooms and so on. Consequently, begin with your business problem and model the domain. Your OOP code should have objects modeled from your domain.
Source:http://csci.csusb.edu/dick/samples/uml0.html
You might be interested in design patterns (Book, Wikipedia), which tell you, how to solve common problems using OOP.
Many classical design patterns may not be so relevant for JavaScript, since in JavaScript there are other non OOP elements (e.g. functions), which can solve some problems even more elegant.
Some simple design patterns I can recommend to start with:
Abstract factory: Defer the instantiation of objects. In JavaScript in most cases a function will do the job.
Decorator: Transparently add functionality to an object at runtime. Can also be nested. Usage example: Logging
Composite: Treat a tree/graph of object like a single object.
I think that using classes in general and OOP principles, makes your code neater, more readable and makes you more productive .
Recently I worked on a web application that would require heavy client side Javascript.
Coming from C#/Java background I realized that Javascript would require a change of thinking, however I still wanted to apply good OO principles if possible, in particular to control the likely complexity of the application.
After a bit of searching I found a great book called Object Oriented Javascript by Stoyan Stefanov. It truly opened my eyes to power of this often called "toy language". Some sections on functional programming concepts, variable scoping and closures may even be a bit more advanced than you want.
However reading and applying many of these concepts from this book (closures, anonymous functions etc) in Javascript, has actually even helped me back in C# land where these concepts are only now becoming more mainstream.
Given your stated situation and goal I can highly recommend this book as one of the best ways to learn about doing OO in Javascript.
Javascript is much, much less object oriented than C# or Java; don't worry if your Javascript doesn't look object oriented.