Your JavaScript Library
Edge of the Web ’09
Dmitry Baranovskiy
http://www.atlassian.com/
http://raphaeljs.com/ http://g.raphaeljs.com/
Why should I write
a library of my own?
function trim(str) {
return str.replace(/^s+|s+$/g, "");
}
function $(id) {
return document.getElementById(id);
}
Low Level
High Level
Toolbox
Widgets
Prototype
Scriptaculous jQuery UI
gRaphaël
D
o
j
o
R
a
p
h
a
ë
l
jQuery
Ext
API & Functionality
Library is the answer.
So, what is the question?
Library is the answer.
So, what is the question?
Who is the target?
Java, Ruby, PHP, JavaScript…
Who is the target?
Java, Ruby, PHP, JavaScript…
“Everything should be made
as simple as possible,
but not simpler.”
Albert Einstein
JavaScript is your friend
Performance
var a = [1, 2, 3, 4, 5, 6, 7, 8, 9];
for (var i = 0; i < a.length; i++) {
a[i] *= 2;
}
var j = a.length;
while (j--) {
a[j] *= 2;
}
function parseColour(colour) {
// #XXXXXX
var value = parseInt(colour.substring(1), 16);
return {
r: (value & 0xff0000) >> 16,
g: (value & 0xff00) >> 8,
b: value & 0xff,
};
}
var parseColour = (function () {
var cache = {};
return function (colour) {
if (colour in cache) {
return cache[colour];
}
// calculation
cache[colour] = value;
return value;
};
})();
var parseColour = (function () {
var cache = {},
count = [];
return function (colour) {
if (colour in cache) {
return cache[colour];
}
// calculation
cache[colour] = value;
count.push(colour);
if (count.length > 1000) {
delete cache[count.shift()];
}
return value;
};
})();
Performance
Rocks
by Thomas Fuchs & Amy Hoy
JavaScript Rocks! presents...
find more awesome JavaScript stuff at http://www.jsrocks.com
JavaScript
Animation
Bulletproof
Global Scope
Global Scope
Treat it as a public toilet
var myLib = {
method1: function () {},
method2: function () {},
// ...
};
var myLib = {};
(function () {
var libVariable = 2;
myLib.method1 = function () {};
myLib.method2 = function () {};
})();
Native Prototypes
String.prototype.trim = function () {
return this.replace(/^s+|s+$/g, "");
};
Number.prototype.times = function (func) {
for (var i = 0; i < this; i++) {
func(i);
}
};
Object.prototype
for (var value in cache) {
this.setAttribute(value, cache[value]);
}
var horizontal = {left: 1, right: 1};
if (direction in horizontal) {
this.horizontal(direction);
}
Object.prototype.top = 3;
// ...
for (var value in cache) {
this.setAttribute(value, cache[value]);
}
var horizontal = {left: 1, right: 1};
if (direction in horizontal) {
this.horizontal(direction);
}
Object.prototype.top = 3;
// ...
for (var value in cache) {
if (cache.hasOwnProperty(value)) {
this.setAttribute(value, cache[value]);
}
}
var horizontal = {left: 1, right: 1};
if (horizontal.hasOwnProperty(direction)) {
this.horizontal(direction);
}
function isArray(object) {
return object && (object instanceof Array);
}
Beware of <iframe>
function isArray(object) {
return Object.prototype.toString.call(object)
=== "[object Array]";
}
undefined
function setSomething(a) {
if (a == undefined) {
a = 5;
}
this.set(a);
}
var undefined;
function setSomething(a) {
if (a == undefined) {
a = 5;
}
this.set(a);
}
function setSomething(a) {
this.set(a || 5);
}
Packaging
Minify / Pack / Obfuscate
JSMin
Dojo ShrinkSafe
Packer
YUI Compressor
jQuery
Prototype
Raphaël
18 Kb
24 Kb
19 Kb
52 Kb
80 Kb
56 Kb
121 Kb
138 Kb
120 Kb
Original Minified GZIP
function calculate(value) {
if (typeof value == "number") {
return parseFloat(value);
}
if (isArray(value)) {
var i = value.length;
while (i--) value[i] = parseFloat(value[i]);
return value.join(",");
}
var values = value.split(","),
i = values.length;
while (i--) values[i] = parseFloat(values[i]);
return values.join(",");
}
394 b
function calculate(c){if(typeof c=="number"){return
parseFloat(c);}if(isArray(c)){var
b=c.length;while(b--){c[b]=parseFloat(c[b]);}return
c.join(",");}var a=c.split(","),b=a.length;while(b--)
{a[b]=parseFloat(a[b]);}return a.join(",");}
235 b
394 b
function calculate(value) {
var parseFloat = parseFloat;
if (typeof value == "number") {
return parseFloat(value);
}
if (isArray(value)) {
var i = value.length;
while (i--) value[i] = parseFloat(value[i]);
return value.join(",");
}
var values = value.split(","),
i = values.length;
while (i--) values[i] = parseFloat(values[i]);
return values.join(",");
} 427 b
235 b
394 b
function calculate(value) {
var parseFloat = parseFloat;
if (typeof value == "number") {
return parseFloat(value);
}
if (isArray(value)) {
var i = value.length;
while (i--) value[i] = parseFloat(value[i]);
return value.join(",");
}
var values = value.split(","),
i = values.length;
while (i--) values[i] = parseFloat(values[i]);
return values.join(",");
} 427 b
235 b
394 b
function calculate(d){var b=b;if(typeof d=="number")
{return b(d);}if(isArray(d)){var
c=d.length;while(c--){d[c]=b(d[c]);}return
d.join(",");}var a=d.split(","),c=a.length;while(c--)
{a[c]=b(a[c]);}return a.join(",");}
216 b
427 b
235 b
394 b
element.setAttribute("width", 320);
element.setAttribute("width", 320);
var setAttribute = function (element, key, value) {
element.setAttribute(key, value);
}
// ...
setAttribute(element, "width", 320);
element.setAttribute("width", 320);
var setAttribute = function (element, key, value) {
element.setAttribute(key, value);
}
// ...
setAttribute(element, "width", 320);
var setAttribute = "setAttribute";
// ...
element[setAttribute]("width", 320);
Error Handling
function setWidth(width) {
width = parseFloat(width);
if (isNaN(width)) {
handleErrors("‘width’ is not a number");
}
}
function handleErrors(message) {
throw new Error(message);
}
function update(x, y, width, height) {
try {
this.setX(x);
this.setY(y);
this.setWidth(width);
this.setHeight(height);
} catch (err) {
throw new Error("Some error happened…
Somewhere.");
}
}
JSLint
http://jslint.com/
Share the magic
Thank You
Icons used with permission of Iconfactory
http://dmitry.baranovskiy.com
dmitry@baranovskiy.com

Your JavaScript Library