Advanced JavaScript Techniques
sixrevisions.com
sixrevisions.com
It's not a terrible article, and he doesn't have bad advice, but as someone else points out in another comment he makes some pretty rookie mistakes (new Objects() instead of {})...
Advanced techniques should only be used when there is a clear justification to sacrifice simplicity. It is disastrous when developers use so-called "advanced" technique only to entertain themselves and show-off.
You are judged not by the niftyness of your code, but by the availability, maintainability, stability and functionality of your system as a whole.
In his namespace example, also, he uses the new Object() notation, which is not nearly as concise as var foo = {}, which does the same exact thing (similarly, var arr = [] is better than var arr = new Array()).
We could rewrite the entire namespace initialization block as:
var MY = (MY) ? MY : { CUSTOM : {} };
This sets the variable MY to itself if it exists, otherwise assign an object literal that has a member property CUSTOM that happens to be an empty object. You could now create a new function, say, MY.CUSTOM.foo = function() { alert('foo'); };
var namespace = function(ns) {
var scope = window;
var tokens = ns.split(".");
for (var idx = 0, len = tokens.length; idx < len; idx++) {
var token = tokens[idx];
scope = scope[token] = scope[token] || {};
}
};
For example: namespace("Zen.Ui");(function(a,b,c){}).length == 3
Using that knowledge, you can do this at the top of a function:
if(arguments.callee.length > arguments.length){ throw "Required Parameter Missing"; }
- Defaults: Must be defined within the object literal
- User Options : part of the function arguments
(user can use an object literal,
anon function etc.)
- Settings : The actual mixin used by the methods
function aProblem(arg1, arg2, options){
// define the necessary defaults
var defaults={} //define defaults
// use a mixin algo to combine options and
// defaults
var settings = mixin(options, defaults);
// main function routines
var myObj={};
return myObj={
property1 : settings.property1,
property2 : settings.property2
}
} for (var i=0, l=myLinkCollection.length; i<l; i++) { }
http://robertnyman.com/2008/04/11/javascript-loop-performanc... function _namespace(){};
function _namespaceLib(){};
// Define your library methods
(function(){
var _private;
this.getPrivate = function(){return _private};
}).apply(_namespaceLib);
// Wrap your code with the new scope
(function(){ with (_namespaceLib) {
// Do anything you want here
var local = "only visible in local scope";
// The library is now in scope
alert( this.getPrivate() );
// Define your external methods
_namespace.myAPIMethod = function(){return local};
}}).apply({});
// _private and local are not accessible
_namespace.myAPIMethod(); // returns "only visible in local scope"And why is this a better namespacing method?
- adds an extra look-up when resolving scope
- creates code that sometimes isn't immediately obvious
But with this technique you basically get to forget you're writing code in a namespace. You can var myFunc; all you want without polluting the global. And you can put the library in a separate file and reference its exposed methods as if they were written in the body of your application.
Also, using DOM methods allows you to easier attach listeners, save references to DOM elements for later updates/use etc. That means less getElementById()'s later.
Writing HTML inside js code is just horrible (IMHO). Horrible ugly code. And obviously easier to have security issues if you're including non-sanitized user data.
#6 is a horrible idea.
As far as your JS code is concerned, HTML is a (horrible, ugly) serialization of the DOM. Manipulate the DOM programatically. Don't use HTML.
innerHTML is just the worst thing ever invented. Ugly ugly thing.
<script type="text/html" id="user_tmpl">
<% for ( var i = 0; i < users.length; i++ ) { %>
<li><a href="<%=users[i].url%>"><%=users[i].name%></a></li>
<% } %>
</script>
Quick tip: Embedding scripts in your page that have a unknown content-type (such is the case here - the browser doesn't know how to execute a text/html script) are simply ignored by the browser - and by search engines and screenreaders.This is quick and dirty, but much more elegant than writing HTML in JS.
Especially when working with something like json data generated elsewhere.
I have been creating some pretty crazy interfaces in 3D Javascript. I try everything I read to see if its faster. I find that its resizing elements during an animation that really affect speed. Stopping event bubbling is pretty nice too. But things I didn't know like using reverse loops because comparing to "0" is faster than an int. or setting [i] into variable after the "++" so the whole length isnt processed over and over. What about using "Math." instead of (var calc = a1 * a2 / a3), var calc = Math.round((a1*a2)/a3); because using the preMthods in the dom is faster. These things really work and I saw my performance shoot through the roof!! My number one performance enhancer though? Dont use <img> tags. The way the browsers render <img> is different than (backgroun-image:url();) and takes much more out of the speed than using a CSS background.
['<h1>',text,'</h2>'].join('')
instead of
'<h1>'+text+'<h2>'
Something like the latter is generally frowned upon in Python because it increases the number of temporary objects that have to be allocated, I'm sure the same logic holds good for most if not all Javascript implementations as well.
render_as_dom(table(tr(td("one"), td("two"))));
I'd prefer to write code like this rather than have a mix of JS and html, with html rendering on the server.which led me to this -
http://www.cactusjs.com/browser/trunk/DOM/tag.js
which is basically a js version of what Ive been doing in PHP with xilla tags.
Given they've implemented both 280Atlas [Obj-J on js] and Suns Lively Kernel in Javascript, there must be a way to avoid HTML generation and even code server and browser side in a similar looking pseudo-lisp dialect...
In Cappuccino each "view" object (CPView, CPButton, etc) has a DIV element as it's base, and other elements contained in that (usually just IMG, canvas/VML, or subviews' DIVs). We don't output HTML at all, but rather manipulate the DOM elements at runtime.
This sort of approach definitely makes sense for the kind of highly interactive applications Cappuccino is designed for, but maybe not for more "pagey" websites where you want search engines to be able to index it, etc.
But then so many 'web pages' now are really js apps, that google must effectively do screen scraping anyway... Perhaps we should just admit that we always need an alternate feed to provide semantic meaning [aka tags] to web crawlers/readers, and be done with it.
Maybe a system where each widget can be queried for its textual content, via a standard simple API would mean all apps made with say Cappucino would be able to emit text to a crawler, without [too much] special code being written - the framework could do it?
Running a JS program on the browser to generate the page should be a legit technique, even for pages that remain static thereafter.
Have you had a look at RaphaelJS? [normalized SVG support via JS : allows JS to do flash-style animations with an open standard behind it].
See also: Parenscript, Scheme2js (part of HOP), biwascheme.
I wrote something like this for YUI.