Good Practices JavaScript
Good Practices JavaScript
good practices
and tips and tricks
Damian Wielgosik
ferrante.pl
javascript.pl
twitter.com/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
buster.testCase("ArticleFactory", {
setUp: function () {
factory = new app.models.ArticleFactory();
},
slideshare.net/szafranek/practical-guide-to-unit-
testing
use native language parts for
creating objects and arrays
(function() {
// do stuff here
})();
use self-invoking functions not
to pollute outer scope
(function() {
var privateVar = 1;
})();
console.log(privateVar); // undefined
define variables at the top of the
scope
var fn = function() {
var news = [],
timer,
foobar;
};
use === everywhere
Array.prototype.contains = function() {
// ...
};
(function() {
var global = this;
console.log(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 = Array.isArray;
})();
be careful with this
var obj = {
foo : function() {
return this.myVariable;
},
myVariable : 1
};
var fn = obj.foo;
fn(); // undefined
be careful with this - don’t forget
about call/apply
var obj = {
foo : function() {
return this.myVariable;
},
myVariable : 1
};
var fn = obj.foo;
fn.call(obj); // 1
be careful with this - don’t forget
about bind
var obj = {
foo : function() {
return this.myVariable;
},
myVariable : 1
};
var fn = obj.foo.bind(obj);
fn(obj); // 1
not every browser supports
Function.bind
not every browser supports
Function.bind - but you can
polyfill it!
Function.bind polyfill
if (!Function.prototype.bind) {
Function.prototype.bind = function (oThis) {
if (typeof this !== "function") {
// closest thing possible to the ECMAScript 5 internal IsCallable function
throw new TypeError("Function.prototype.bind - what is trying to be bound is
not callable");
}
fNOP.prototype = this.prototype;
fBound.prototype = new fNOP();
return fBound;
};
}
for loop is not slower than while
jsperf.com/for-loop-research
using indexes with localStorage
is faster than getItem in some
browsers
jsperf.com/localstorage-science
using indexes with localStorage
is faster than getItem in some
browsers
var key = 1;
localStorage[key]; // faster
localStorage.getItem(key); // slower
native forEach is not faster than
classic loops
jsperf.com/for-vs-array-foreach
use requestAnimationFrame if you deal with
heavy proccesses like DOM manipulation
(function() {
var requestAnimationFrame = window.requestAnimationFrame ||
window.mozRequestAnimationFrame || window.webkitRequestAnimationFrame ||
window.msRequestAnimationFrame || function(fn) { window.setTimeout(fn,
16); };
window.requestAnimationFrame = requestAnimationFrame;
window.setTimeout(function() {
makeThings();
}, 16);
no!
yes!
functions are objects
(function() {
var toString = Object.prototype.toString;
var isArray = Array.isArray || function(arr) { return toString.call
(arr) === "[object Array]"; };
})();
clear arrays using length for
memory performance
var obj = {
foobar : ""
};
var num = 2;
if (typeof num === "number") {
// we have a number
}
use typeof to check if you can
fire a function
container.innerHTML = html;
var newsList = container.querySelector(".news");
make use of datasets
node.dataset.id; // "123"
node.dataset.type; // "news"
did you know about
node.matchesSelector?
<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 = document.getElementById("elem-container");
var theCSSprop = window.getComputedStyle(elem,null).getPropertyValue("height");
document.getElementById("output").innerHTML = theCSSprop;
}
getTheStyle();
</script>
innerHTML is not the fastest
way to check if node is empty
node.addEventListener("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
form.addEventListener("submit", function(e) {
e.preventDefault();
}, false);
Performance?
var start = +new Date();
for (var i = 0; i < 100000; i++);
console.log("Result is: ", +new Date() - start);
Better?
console.time("My test");
for (var i = 0; i < 100000; i++);
console.timeEnd("My test");
Still better?
console.profile("My test");
runApp();
console.profileEnd("My test");
The best?
jsperf.com
jsperf.com
jsperf measures operations per
second!
See also window.performance
do not optimize prematurely!
JavaScript !== Java
flickr.com/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! ;-)
http://www.fotofaza.pl/podglad_zdjecia,15,ludzie,chuligani.html
function calls cost time!
use JS asynchronously when needed
var arr = [ function() { console.log("A"); },
function() { throw new Error("boom!"); },
function() { console.log("B"); },
function() { console.log("C"); }
];
$('input.username').keypress(throttle(function (event) {
// do the Ajax request
}, 250));
http://remysharp.com/2010/07/21/throttling-function-calls/
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
document.querySelectorAll("div")
returns a NodeList
not an array
var nodes = document.querySelectorAll("div");
nodes = [].slice.apply(nodes);
However:
„Whether the slice function can be applied successfully to a host object is
implementation-dependent.” - ECMAScript
mobile?
Use window.scrollTo(0, 1) to get rid of the browser address bar
on iOS!
/mobile/i.test(navigator.userAgent) && !location.hash && setTimeout
(function () {
if (!pageYOffset) window.scrollTo(0, 1);
}, 1000);
Memory?
Memory leaks?
Memory leak checker
sIEeve
Performance?
home.orange.nl/jsrosman/
Memory leaks?
people.mozilla.com/~dbaron/leak-screencasts/
general thoughts
Get rid of jQuery if it’s not neccessary -
there is http://microjs.com
Hunt on new stuff!
http://js.gd might be a good start!
Visit JSNews on Facebook for more awesomeness
http://tinyurl.com/jsnewspl
or attend meet.js meetups
Poznan, Warsaw, Wroclaw, Cracow
http://meetjs.pl
but first of all, be smart and listen to smart people -
there is a lot on the web