I have a general question about the design of JavaScript Libraries.
I am trying to consolidate common methods into one js file so they can be reused by different scripts.
I have taken a look at how the JSON library is structured and believe it was a good approach.
JSON for Javascript.
So they start off creating an instance of the class:
if (!this.JSON) {
this.JSON = {};
}
Then they do this:
(function () {
if (typeof JSON.stringify !== 'function') {
JSON.stringify = function (value, replacer, space) {
This is works perfect if you just want to do JSON.[function_name], but what if I want to have a more structured library such that I want: JSON.[subgroup].[function]. How would I structure my JS library in such a way?
Any links to resources are greatly appreciated, thanks.
I would recommend you to follow the Module Pattern in JavaScript instead of following JSON's pattern strictly. Your subgroup is actually referring to sub-modules. Take a look at the following excellent article:
Ben Cherry's JavaScript Module Pattern In-Depth
Other resources you should probably go through:
John Resig's Learning Advanced JavaScript
Seven JavaScript Things I Wish I Knew Much Earlier In My Career
The Seven Deadly Sins Of JavaScript Implementation
There are problems with the module pattern. See http://snook.ca/archives/javascript/no-love-for-module-pattern. I used to use it before but stopped. Now I just tend to keep it simple. If you really want sub-namespacing you can make a simple namespace function for the job.
See
http://blogger.ziesemer.com/2008/05/javascript-namespace-function.html
Related
Not sure if this is a new question so pls ref to any good source if you have any.
My team is working on a big JS chart project we inherited from the previous developers who made intensive use of built-in objects prototypes for adding reusable code. We have a lot of new utility functions added to Date, Object and other intrinsic objects so I guess they went this way 'cause altering prototypes provides a bit more intuitive API.
On the other hand our component suffers from performance/memory gotchas and we apply all the possible optimizations and best practices. I can't find one regarding API design. I'm trying to figure out whether it's better to seed built-in objects' prototypes with library code instead of combining them in dedicated objects via somewhat namespace pattern.
The question is which design is better? And will one of them gain performance and/or memory over another?
Date.prototype.my_custom_function = new function (...) {...};
var period = new Date();
period.my_custom_function();
vs
DateLib.my_custom_function // defined in a DateLib function
var period = new Date();
DateLib.my_custom_function(period);
Thanks, guys, any help is appreciated!
EDIt:
The main problem is that our component ended up being an awkward JS beast that slows down some mobile devices, especially old ones, such as iPad1 and early Androids... We've done a lot of optimization but I still see several questionable parts. I want to make sure if the built-in prototype pollution is another candidate to look into.
Particularly, the Date and Object guys are heavily loaded with typical library code. For example, in fact the my_custom_function is a big big function and it's not the only additional member that sits on the Date prototype at code startup.
The Object is loaded even more. Most of the client code doesn't make use of those additional features, it's used on purpose - so we're about to decide whichever way we're better stick with:
Keep using prototype pollution design
Refactoring reusable APIs into separate library static objects
to be honest I haven't run perf benchmarks yet, will do once I have time. If someone has outcome/ideas will be very helpful.
Modifying objects you don't own is definitely bad idea. The choice here is rather architectural: if you have to store a date persistently, then use a private property of the constructor:
function DateLib() {
this._dateObject = new Date();
}
DateLib.prototype.getDateString = function () {
return this._dateObject.toDateString()
};
var dateLib = new DateLib();
dateLib.getDateString();
If you just want to do some manipulation with a date, create a method:
var DateLib = {
toDateString: function (date) {
return date.toDateString()
}
}
DateLib.toDateString(new Date());
As it comes to the performance, all approaches are equally fast (thanks to Bergi, alternative test by Esailija).
Note: this is not browser comparison test. Tests were performed on a different machines, so only method-vs-method performance should be analysed here.
Is there any super set or language similar to javascript that provides a more classical c++/java/c#-like OO System. But can be used with HTML-5 and DOM and has a cross-platform implementation?
You could give CoffeeScript a try.
It compiles to JavaScript so it's indeed cross-platform.
As far as scripting is concerned, it is also compatible with using HTML5 tags but it's not really an issue: HTML is the markup language, JavaScript (or CoffeeScript) is the scripting language. So you can still select or edit (HTML5) elements using CoffeeScript; the script will be compiled to JavaScript and it'll still work.
Yes, it's called JavaScript. There are some good articles about OOP around
var Parent = {
method: function () {
...
}
}
var Child = Object.create(Parent, {
childMethod: { value: function () {
...
} }
})
Any attempt to emulate a class system in JavaScript is a waste of time and ends up writing bloated / unreadable / unmaintainable code.
If the above is too ugly, consider using an extend function
In addition to the suggestion to learn CoffeeScript above, you could try out a couple of javascript patterns.
I was recently watching a pluralsight screencast (structuring javascript code) and I was made aware of a couple of javascript patterns but i really like the "Revealing Prototype Pattern".
Very concise and simple, you get some of the benefits of OOP including encapsulation et al.
Pluralsight offers a free 10 days trial period so i guess you can easily get up to speed with it.
There are a few options. The ones that spring to my mind are:
Simple JavaScript Inheritance
YUI extend
I have a background in OOP. I started to work a lot with JavaScript. As the project grows it's becoming more difficult to maintain it. In Java I apply OOP principles to keep things under control. What should I do with JavaScript, what should I study that is aimed at keeping a JavaScript application under control?
You can apply OOP principles to Javascript development too. Javascript uses prototypal inheritance, but that is an implementation detail. The concepts are still the same. Most of the concepts with which you are familiar have direct analogues in javascript.
Other tried and true methods apply as well:
1) Stay DRY -- Do not Repeat Yourself. Duplicate code is always evil.
2) Separate concerns -- Use the MVC or MVVM patterns to keep code clean and doing only 1 thing.
3) Test -- When I hear "Difficult to maintain" my brain translates that into lack of tests. You can certainly write unit tests for javascript projects.
4) Code Review -- Code reviews can be a good way of rejecting duplicated code, code that is not crafted properly, not formatted, etc....
This is how you define objects and methods in javascript.
function SomeObj() {
this.someMethod = function() {
alert('boo');
}
}
var o_obj = new SomeObj();
o_obj.someMethod(); //alerts "boo"
Hope it helps.
You can also use prototype to create static functions.
this.prototype.someMethod = function() {
alert('boo');
}
When I was in the same situation I started to look at "how other did". Its ended up with http://dojotoolkit.org/ and http://jquery.com and I was looking how they implement widgets/plugins so other could extend the framework.
Another way of defining simple objects and methods in javascript (without the need for new).
function creaeSomeObj() {
var that = {};
that.someMethod = function() {
alert('boo');
}
return that;
}
var o_obj = createSomeObj();
o_obj.someMethod(); //alerts "boo"
This pattern doesn't support inheritance, but many times it is sufficient.
Why "vs"? JavaScript supports object-oriented programming, but not in the traditional class-based way that you see in e.g. Java.
The way JavaScript's OOP works is usually known as "prototypal inheritance", or more specifically "delegative prototypal inheritance". This can be boiled down to "if you're looking for the property 'foo' in an object, and you can't find it there, then try looking for 'foo' inside the object's prototype instead". That is, the lookup of the property is delegated to the object's prototype (we say that the object inherits the properties from the prototype).
The way prototypal inheritance works has a couple of implications. For instance:
Objects in JavaScript are "dynamic" in the sense that they're just a bunch of name-value pairs. New properties can be added and removed during runtime, so they're much less "static" than objects in the typical class sense.
The way delegative prototypal inheritance works ("if you can't find the prototype here, then look here instead") means it's much simpler than classical OOP. From a purely prototypal point of view, you don't need constructors, for example. "Methods" are just regular functions that happen to be attached to the prototype (which means they are available as properties on all inheriting objects).
There are pro's and con's with both prototypal and classical inheritance, but it's important to remember that they're different.
Now, JavaScript is in some senses inspired by Java and other classical languages, so therefore they decided to make the syntax "class-like" to make it easier for people used to classes to get started. I won't elaborate a lot on this; it's documented to a great extent in other places already.
Some interesting posts:
hughfdjackson's introduction to JavaScript OOP -- short and more to-the-point,
Sorella's longer "Understanding Javascript OOP" -- rather in-depth and very complete resource.
Pluralsight has a course on just this topic: Structuring JavaScript Code that may provide some insight. Two caveats: 1. I haven't sat through the course yet - but content looks great and I've been impressed with other Pluralsight courses I've taken, and 2. it is not free (but may be worth the small $ if it saves you time down the road b/c you have better code structure). No, I don't work for Pluralsight.
In addition to the js frameworks mentioned in this thread, can also look at Knockoutjs - great tutorials here learnknockoutjs.com. Knockout is MVVM focused. Note, there is a good discussion in stackoverflow comparing Backbone to Knockout, and Pluralsight also has a course on using Knockout which I have watched and do recommend.
In JavaScript, Functions are Objects; Mozilla Developer Network, McKoss, SitePoint, and JavaScript Kit explain further.
Example JavaScript Object
function myObj() {
this.myMethod = function() {
alert('hello');
}
}
var demo_obj = new myObj();
demo_obj.myMethod();
Patterns to keep things under control
The patterns listed here are particular to JavaScript.
Use a Script Loader.
Use a JS Framework.
Lint your JavaScript. - Tools are availble to run this on your desktop in Rhino or node.
Minify your JS.
The patterns listed here are typical of OOP Languages, and are not
particular to JavaScript.
DRY - Don't Repeat Yourself.
Observer (Pub/Sub) pattern.
Anti-Patterns to let things out of control
Polluting the namespace
use of eval()
Prototyping against the Object object
Inline Script Tags.
use of document.write
I have found a JavaScript gallery.
When I view the JavaScript code, I really don't understand how to write code in this style. What is the style called? Where can I find documents related to it?
Note: what i want to know is the way that define Class in this code
(function (){ ... })(window)
what is style ?
jQuery Mobile. http://jquerymobile.com/
The reason you can't read it is because they are compressing the code which changes around variable names and makes the code as small as possible. This helps the code load faster.
jQuery.com
Based on your question, it seems you're not familiar with jQuery. jQuery is a JavaScript framework written in JavaScript. It is most useful for it's selector/filter capabilities, being able to pull objects of objects using something like $('div'); (or jQuery('div');), which would pull all the divs from the page. Using dot notation, you can perform methods on those returned objects.
(function (){ ... })(window)...
is both an unnamed function definition and call, passing in the window object. It's sort of like function foo (){...} foo(window), only you don't store the definition in variable foo and you need to wrap the definition in parentheses for syntax recognition in order to call it with the trailing parentheses.
For more advanced JavaScript topics, google closures.
Developers typically minify their javascript before deployment. This makes it hard to understand. but typically you can go to their website if they are willing to share the code
Try to get a look at the github website of the app.
I'm working on a site and using JQuery for essentially the first time. I've mostly used MooTools for previous projects, and I have a few widget classes I've written using the MooTools Class structure. I'd like to port them over to JQuery, but it looks to me like there is nothing similar to the MooTools functionality when it comes to object classes.
I've searched around a bit, and haven't found much on it. Digg appears to have rolled their own, but I'm not sure if this is something I should be using. Is there a better way? How object-oriented do people normally get with JQuery? What's the usual method of encapsulating a UI widget (or any functional class structure)?
I'll post a fake example of a possible MooTools widget class:
var ZombatWidget = new Class({
Extends: BaseWidget,
widgetPropertyX = 'prop1',
widgetPropertyY = 'prop2',
attach = function(el) {
var f = function() {
//do something widgety
};
el.addEvent('dblclick',f);
el.addClass('widgetized');
}
});
var z = new ZombatWidget();
z.attach($('widgetDiv'));
What I've got is a lot bigger than that, but you get the idea. Do I need to convert this to the prototype method of class/inheritance structuring? How would you write this kind of object class using JQuery?
You might find this approach useful to the task at stake: building an object-oriented jquery plugin.
And this article on Ajaxian "a real OO class system with jquery".
Hm... interesting. We have jQuery which imho is a great tool to interact with the DOM. It's a selection tool where you can write your own code (plugins) to modify selected items. You can interact here with your own (object oriented) code in a plugin to do something really cool.
So why would you need extra OO capabilities in jQuery unless you want to be able to inherit from other jQuery plugins?
Because you might have a plugin that allows you to do the following:
$(".spiffyness").yourSpiffyficationPlugin1();
And, while doing some really cool awesomeness already, you need more spiffyness on top of this.
Therefore you want to inherit from your first plugin which results in:
$(".spiffyness").yourSpiffyficationPlugin2(); //plugin inherited from 1
But... wouldn't you get there too by doing this:
$(".spiffyness").yourSpiffyficationPlugin1().yourSpiffyficationPlugin2();
Where the second plugin just does this tiny (but awesome ;)) thing extra on top of the first one?
In other words: is what you want, worth the effort for the sake of OO purism? Or is the jQuery pipe mechanism good enough and maybe everything you need?
I would say that separation of responsibilities and/or your mootools mindset might be the real issue here. Let jQuery do what it is good at, use it's powerfull pipe mechanism, pipe your own plugins (which may contain tons of fancy OO stuff)... and you can have great results while your code is still clean.
If you do think I am thinking too simple here, a good example of the essence of your point would be welcome! :-)
And to be ahead of that, if you are doing something really advanced and you do not get away with simply doing something on top of something else, you're plugin could also delegate to one of your OO classes. E.g. like:
$.fn.totalAwesomeness = function(options) {
var defaults = {
mode: 1,
title: 'Awesome'
};
var opts = $.extend(defaults, options);
return this.each(function() {
var $this = $(this);
var handler = null;
if(defaults.mode == 1)
handler = new com.myStuff.class1($this);
else if(defaults.mode == 2)
handler = new com.myStuff.class2($this); //class2 inherits from class1
handler.doMagic();
});
};
You can always also use moo4q - http://moo4q.com/ . It adds MooTools class support to jQuery.
I wrote an article some time ago about jQuery object oriented plugins, hope it will be helpful
http://ajax911.com/jquery-object-oriented-plugins/
There are third party javascript class implementations that provide very powerful introspection capabilites. I would like to particularly highlight JS.Class and Joose.
While JS.Class is modeled after Ruby, Joose is modeled after Moose.
I am not a mootools user so I can not comment on their advantages/disadvantages with respect to mootools. But I would summarize their key features.
JS.Class has a strong focus on simulating the Object oriented features of Ruby and does a pretty good job at that. It provides a powerful library modeled after the standard library of Ruby and also comes with a well integrated package management and testing framework.
Joose, while provides no testing framework/package management facilites, excels in terms of
advanced attribute management facilities, filters and better introspection facilities.
Both of them have really good documentation and can be used in browser as well as server.
I've just finished a very first release of my mini project: https://github.com/op1ekun/plOOgins. It's all about writing OOP code to be used as Jquery plugins. It's not rocket science just a little something that we wanted to use at my workplace. Maybe it will help You a bit. Good luck!
Plugins sometimes do the trick.
Of course, you could use just enough of mootools to get it's class/inheritance model. With the implementation of document.id "compatibility mode" in 1.2.3 you can have your cake and eat it too (I think--haven't done it myself.)
The question is... Why are you moving away from MooTools is it fits your needs? Seems to me like MooTools was working fine, and there is nothing jQuery does that MooTools can't do. (The opposite isn't true).
Unfortunately, jQuery is not built to support classical OOP as MooTools is so you will need to write your Classes as jQuery plugins.