[Go to site: main page, start]

100% found this document useful (1 vote)
167 views112 pages

JavaScript Best Practices & Tips

This document provides several tips for writing efficient and optimized JavaScript code. Some key points include: - Use native language parts like arrays and objects instead of constructor functions to avoid overhead. - Cache frequently used values and functions to improve performance. Native functions can be cached to protect their references. - Be cautious with variable scoping and the this keyword. Functions can be bound, called or applied to set context. - Prefer modern language features like addEventListener, classList, and querySelector over older alternatives. - Leverage DOM APIs for tasks like getting computed styles rather than relying only on inline styles. - Optimize rendering by using requestAnimationFrame for intensive DOM operations.
Copyright
© All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
100% found this document useful (1 vote)
167 views112 pages

JavaScript Best Practices & Tips

This document provides several tips for writing efficient and optimized JavaScript code. Some key points include: - Use native language parts like arrays and objects instead of constructor functions to avoid overhead. - Cache frequently used values and functions to improve performance. Native functions can be cached to protect their references. - Be cautious with variable scoping and the this keyword. Functions can be bound, called or applied to set context. - Prefer modern language features like addEventListener, classList, and querySelector over older alternatives. - Leverage DOM APIs for tasks like getting computed styles rather than relying only on inline styles. - Optimize rendering by using requestAnimationFrame for intensive DOM operations.
Copyright
© All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
  • Introduction to JavaScript Practices
  • Author Information
  • Online Resources
  • Performance Tips Reminder
  • ECMAScript Familiarity
  • ECMAScript Specification
  • Handling Complexity
  • Code Readability
  • ECMA-262 Specification
  • Code Linting
  • Linting Resources
  • More Linting Resources
  • Sample Linting Configuration
  • Integrating Linting Tools
  • Linting Command Result
  • Test-Driven Development (TDD)
  • Buster.js for TDD
  • Test Case Example
  • Unit Testing Results
  • Choosing Unit Testing Tools
  • Unit Testing Presentations
  • Creating Objects and Arrays
  • Scope Pollution Prevention
  • Scope Management Example
  • Variable Declaration Best Practices
  • Equality Best Practices
  • Looping Practices
  • Array Manipulation Tips
  • Managing Global Context
  • Compatibility Techniques

JavaScript

good practices
and tips and tricks
Damian Wielgosik
[Link]
[Link]
[Link]/varjs
remember that performance tips
change over the time as JVM
evolves
make yourself familiar with
ECMAScript
ECMAScript
sometimes it’s difficult...
... to speak in a human language
... znaleźć ludzki
Dmitry język
Soshnikov

your personal ECMAScript teacher


lint your code, hurt your feelings
[Link]
[Link]
/*jslint sloppy: true, vars: true, white: true, plusplus: true,
newcap: true */
(function() {
// ...
})();
mount your linting tool to the
text editor/IDE you use
it’s a result of cmd+L in TextMate
go TDD when it’s possible
try [Link]
([Link]/)
(function() {
if (typeof require == "function" && typeof module ==
"object") {
buster = require("buster");
require("../models/[Link]");
}

var assert = [Link];


var factory;

[Link]("ArticleFactory", {
setUp: function () {
factory = new [Link]();
},

"createArticle should not return null": function () {


var article = [Link](1, "Foobar",
"bla bla", "12/12/2012","12:12",
[Link], { addArticle: function()
{}}, {}, {});
[Link](article);
},
});
})();
there is a lot of unit testing
libraries, choose the best
there are great presentations too

[Link]/szafranek/practical-guide-to-unit-
testing
use native language parts for
creating objects and arrays

var arr = []; // not new Array


var obj = {}; // not new Object
use self-invoking functions not
to pollute outer scope

(function() {
// do stuff here
})();
use self-invoking functions not
to pollute outer scope

(function() {
var privateVar = 1;
})();
[Link](privateVar); // undefined
define variables at the top of the
scope

var fn = function() {
var news = [],
timer,
foobar;
};
use === everywhere

0 === ""; // false


0 == ""; // true
do not iterate over an array with
for in loop

[Link] = function() {
// ...
};

var arr = [1, 2, 3];


for (var i in arr) {
[Link](i); // contains
}
add to an array using push

var arr = [1];


[Link](2);
arr; // [1,2]
you can store a global object to
avoid mistakes with this

(function() {
var global = this;
[Link](global === window); // true
})();
global compatible with
ECMAScript 5 and „use strict”

"use strict";
var global = Function('return this')();
cache native functions to protect
them

(function() {
var isArray = [Link];
})();
be careful with this

var obj = {
foo : function() {
return [Link];
},
myVariable : 1
};

var fn = [Link];
fn(); // undefined
be careful with this - don’t forget
about call/apply

var obj = {
foo : function() {
return [Link];
},
myVariable : 1
};

var fn = [Link];
[Link](obj); // 1
be careful with this - don’t forget
about bind

var obj = {
foo : function() {
return [Link];
},
myVariable : 1
};

var fn = [Link](obj);
fn(obj); // 1
not every browser supports
[Link]
not every browser supports
[Link] - but you can
polyfill it!
[Link] polyfill

if (![Link]) {
[Link] = function (oThis) {
if (typeof this !== "function") {
// closest thing possible to the ECMAScript 5 internal IsCallable function
throw new TypeError("[Link] - what is trying to be bound is
not callable");
}

var aArgs = [Link](arguments, 1),


fToBind = this,
fNOP = function () {},
fBound = function () {
return [Link](this instanceof fNOP
? this
: oThis,
[Link]([Link](arguments)));
};

[Link] = [Link];
[Link] = new fNOP();

return fBound;
};
}
for loop is not slower than while

[Link]/for-loop-research
using indexes with localStorage
is faster than getItem in some
browsers

[Link]/localstorage-science
using indexes with localStorage
is faster than getItem in some
browsers

var key = 1;
localStorage[key]; // faster
[Link](key); // slower
native forEach is not faster than
classic loops

var arr = [1, 2, 3, 4, 5];


[Link](function() {}); // slower
for (var i = 0, ilen = [Link]; i < ilen; i++) {}; // faster

[Link]/for-vs-array-foreach
use requestAnimationFrame if you deal with
heavy proccesses like DOM manipulation

(function() {
var requestAnimationFrame = [Link] ||
[Link] || [Link] ||
[Link] || function(fn) { [Link](fn,
16); };
[Link] = requestAnimationFrame;

var start = [Link]().


var elements = 0;

var step = function() {


var house = [Link]("div");
[Link]("house");
[Link](building);
elements++;
if (elements < 10000) {
requestAnimationFrame(step);
}
}
requestAnimationFrame(step);
})();
do not create too many functions
- that costs memory

[Link](function() {
makeThings();
}, 16);

no!

var frame = function() {


makeThings();
};
[Link](frame, 16);

yes!
functions are objects

var fn = function() {};


[Link] = 1;
[Link]; // 1
functions are objects, so they
help cache

var getSin = function(num) {


if (getSin[num]) {
return getSin[num];
} else {
return getSin[num] = [Link](num);
}
};
more crossbrowser isArray?

(function() {
var toString = [Link];
var isArray = [Link] || function(arr) { return [Link]
(arr) === "[object Array]"; };
})();
clear arrays using length for
memory performance

var arr = [1, 2, 3, 4, 5];


[Link] = 0; // instead of arr = [];
max number in an array?

var arr = [1, 2, 3, 4, 5];


[Link](Math, arr);
use ”in” to check if the property
is defined in the object

var obj = {
foobar : ""
};

'foobar' in obj; // true


'barbar' in obj; // false
!![Link]; // false
use typeof to check variable
types

var num = 2;
if (typeof num === "number") {
// we have a number
}
use typeof to check if you can
fire a function

var fn = function() {};


if (typeof fn === "function") {
fn();
}
typeof RegExp

typeof RegExp === "function"; // true


typeof /\d+/g; // "object"
you don’t need jQuery just to get
some nodes

var news = [Link]("[Link]"); // finds all the elements


var news = [Link]("[Link]"); // finds the first element
you don’t need regular
expressions to work with class
names

[Link]("foo"); // <body class="foo">


[Link]("foo"); // true
[Link]("foo"); // <body>
[Link]("foo"); // <body class="foo">
[Link]("foo"); // <body>
build your view templates with
innerHTML

var html = '<ul class="news">' +


'<li>' +
'<h1>Something</h1>' +
'<p>Text</p>' +
'</li>' +
'</ul>';

[Link] = html;
var newsList = [Link](".news");
make use of datasets

<div data-id="123" data-type="news"></div>

[Link]; // "123"
[Link]; // "news"
did you know about
[Link]?

<div id="foo" class="bar">This is the element!</div>


<script type="text/javascript">
var el = [Link]("foo");
if ([Link]("[Link]")) {
alert("Match!");
}
</script> // thanks to MDN
[Link] if
[Link] is not enough

<style>
#elem-container{
position: absolute;
left: 100px;
top: 200px;
height: 100px;
}
</style>

<div id="elem-container">dummy</div>
<div id="output"></div>

<script>
function getTheStyle(){
var elem = [Link]("elem-container");
var theCSSprop = [Link](elem,null).getPropertyValue("height");
[Link]("output").innerHTML = theCSSprop;
}
getTheStyle();
</script>
innerHTML is not the fastest
way to check if node is empty

if ([Link] === "") {} // slower


if ([Link] === 0) {} // faster
don’t extend DOM nodes with
custom properties to avoid
memory leaks

var div = [Link]("div");


[Link] = function() {};
add events using
addEventListener

[Link]("click", function() {
alert("Boom!");
}, false);
do not forget to prevent form
submitting when dealing with
web app forms that are sent e.g.
by AJAX

[Link]("submit", function(e) {
[Link]();
}, false);
Performance?
var start = +new Date();
for (var i = 0; i < 100000; i++);
[Link]("Result is: ", +new Date() - start);
Better?
[Link]("My test");
for (var i = 0; i < 100000; i++);
[Link]("My test");
Still better?
[Link]("My test");
runApp();
[Link]("My test");
The best?
[Link]

[Link]
jsperf measures operations per
second!
See also [Link]
do not optimize prematurely!
JavaScript !== Java

do not optimize prematurely!

[Link]/photos/paulmartincampbell/3583176306/sizes/o/in/photostream/
forget about your old habits!
do not port bad solutions to JavaScript!
otherwise they’re gonna find
you! ;-)

[Link]
function calls cost time!
use JS asynchronously when needed
var arr = [ function() { [Link]("A"); },
function() { throw new Error("boom!"); },
function() { [Link]("B"); },
function() { [Link]("C"); }
];

for (var i = 0, ilen = [Link]; i < ilen; i++) {


arr[i]();
}
oops?
var arr = [ function() { [Link]("A"); },
function() { throw new Error("boom!"); },
function() { [Link]("B"); },
function() { [Link]("C"); }
];

for (var i = 0, ilen = [Link]; i < ilen; i++) {


[Link](arr[i], 0);
}
timers can be useful with AJAX requests
var throttle = function(fn, delay) {
var timer = null;
return function () {
var context = this;
var args = arguments;
clearTimeout(timer);
timer = setTimeout(function () {
[Link](context, args);
}, delay);
};
};

$('[Link]').keypress(throttle(function (event) {
// do the Ajax request
}, 250));

[Link]
parseInt(„09”) === 0
JS thinks „09” is an octal number
because it starts with 0
parseInt(„09”, 10) === 9
However,
parseFloat(„09”) === 9
However,
parseFloat(„09”) === 9
[Link]("div")
returns a NodeList
not an array
var nodes = [Link]("div");
nodes = [].[Link](nodes);
However:
„Whether the slice function can be applied successfully to a host object is
implementation-dependent.” - ECMAScript
mobile?
Use [Link](0, 1) to get rid of the browser address bar
on iOS!
/mobile/[Link]([Link]) && ![Link] && setTimeout
(function () {
if (!pageYOffset) [Link](0, 1);
}, 1000);

thanks to amazing work by Remy Sharp


[Link]
iphone-url-bar/
Mobile debugging?
Aardwolf - mobile
debugging made easy

Yes, we all know Firebug and Web Inspector


Memory stats?
WebKit Inspector

Memory?
Memory leaks?
Memory leak checker
sIEeve

Performance?

[Link]/jsrosman/
Memory leaks?

[Link]/~dbaron/leak-screencasts/
general thoughts
Get rid of jQuery if it’s not neccessary -
there is [Link]
Hunt on new stuff!
[Link] might be a good start!
Visit JSNews on Facebook for more awesomeness
[Link]
or attend [Link] meetups
Poznan, Warsaw, Wroclaw, Cracow
[Link]
but first of all, be smart and listen to smart people -
there is a lot on the web

JavaScript
good practices 
and tips and tricks
Damian Wielgosik
ferrante.pl (http://ferrante.pl) (http://ferrante.pl)
javascript.pl (http://javascript.pl)
twitter.com/varjs (http://twitter.
remember that performance tips 
change over the time as JVM 
evolves
make yourself familiar with 
ECMAScript
ECMAScript
sometimes it’s difficult...
... to speak in a human language
... znaleźć ludzki język
Dmitry Soshnikov
your personal ECMAScript teacher
lint your code, hurt your feelings

You might also like