javascript proven practises
DESCRIPTION
TRANSCRIPT
![Page 1: JavaScript Proven Practises](https://reader035.vdocuments.mx/reader035/viewer/2022062512/5539ab914a79594f6c8b49ee/html5/thumbnails/1.jpg)
JavaScriptProven Practices
20 June 2012
![Page 2: JavaScript Proven Practises](https://reader035.vdocuments.mx/reader035/viewer/2022062512/5539ab914a79594f6c8b49ee/html5/thumbnails/2.jpg)
Agenda
Cover proven practices about how to write better JavaScript
Lots of slides (50+) but a lot are code we will talk about and see what is right & what is wrong
Assumption: You can read JavaScript (or fake it)
![Page 3: JavaScript Proven Practises](https://reader035.vdocuments.mx/reader035/viewer/2022062512/5539ab914a79594f6c8b49ee/html5/thumbnails/3.jpg)
JavaScript is a sloppy language, but inside it there is an elegant, better language.
Douglas Crockford - Jslint.com
![Page 4: JavaScript Proven Practises](https://reader035.vdocuments.mx/reader035/viewer/2022062512/5539ab914a79594f6c8b49ee/html5/thumbnails/4.jpg)
Situation 11. var i=0;2. function demo(){3. for (i=0; i<10; i++){ 4. // do stuff5. } 6. }
7. demo();8. // what is i?
code
10
output
![Page 5: JavaScript Proven Practises](https://reader035.vdocuments.mx/reader035/viewer/2022062512/5539ab914a79594f6c8b49ee/html5/thumbnails/5.jpg)
Situation 1 cont.1. function demo(){2. i = 50;3. }
4. demo();5. // what is i?
code
50
output
![Page 6: JavaScript Proven Practises](https://reader035.vdocuments.mx/reader035/viewer/2022062512/5539ab914a79594f6c8b49ee/html5/thumbnails/6.jpg)
Always use varVariables have scope
GlobalFunction
Using var helps keep the scope straight
![Page 7: JavaScript Proven Practises](https://reader035.vdocuments.mx/reader035/viewer/2022062512/5539ab914a79594f6c8b49ee/html5/thumbnails/7.jpg)
Always use var - fixes1. var i=0;
2. function demo(){3. var i = 0;4. for (i=0; i<10; i++){ 5. print("demo");6. } 7. }
8. demo();9. // what is i?
![Page 8: JavaScript Proven Practises](https://reader035.vdocuments.mx/reader035/viewer/2022062512/5539ab914a79594f6c8b49ee/html5/thumbnails/8.jpg)
Always use var - fixes1. var i =0;
2. function demo(){3. for (var i=0; i<10; i++){ 4. print("demo");5. } 6. }
7. demo();8. // what is i?
![Page 9: JavaScript Proven Practises](https://reader035.vdocuments.mx/reader035/viewer/2022062512/5539ab914a79594f6c8b49ee/html5/thumbnails/9.jpg)
Situation 2
1. function setspan(num, text)2. {3. eval("myspan" + num + ".innerText = '" + text + "'");4. }
code
//syntax error
output
1. myspan1.innerText = 'it ain't what you do, it's the way thacha do it';
data
![Page 10: JavaScript Proven Practises](https://reader035.vdocuments.mx/reader035/viewer/2022062512/5539ab914a79594f6c8b49ee/html5/thumbnails/10.jpg)
Situation 2 cont.
1. eval("var a = 'awesome';");2. print(a);
code
'awesome'
output
![Page 11: JavaScript Proven Practises](https://reader035.vdocuments.mx/reader035/viewer/2022062512/5539ab914a79594f6c8b49ee/html5/thumbnails/11.jpg)
Avoid evaleval is hard to get right and there are many many situations out of your control you need solve
eval runs code – so you are saying you trust the user to write code
Modern browsers pre-compile JavaScript, eval doesn’t benefit from this!
![Page 12: JavaScript Proven Practises](https://reader035.vdocuments.mx/reader035/viewer/2022062512/5539ab914a79594f6c8b49ee/html5/thumbnails/12.jpg)
Situation 3
1. function doSomething(someValue){ 2. //... 3. } 4. 5. setTimeout("doSomething('3 seconds elapsed. Time is up.');", 3000);
code
1. var sum = new Function('op1', 'op2', 'return op1 + op2;'); 2. var result = sum(10, 20); // ==> 30
code
![Page 13: JavaScript Proven Practises](https://reader035.vdocuments.mx/reader035/viewer/2022062512/5539ab914a79594f6c8b49ee/html5/thumbnails/13.jpg)
Avoid eval part 2eval can appear in sneaky locations in JavaScript
Timers – SetTimeout & SetIntervalFunction contstructors
![Page 14: JavaScript Proven Practises](https://reader035.vdocuments.mx/reader035/viewer/2022062512/5539ab914a79594f6c8b49ee/html5/thumbnails/14.jpg)
Avoid Eval Part 2 Fixed
1. setTimeout(function(){ 2. doSomething('3 seconds elapsed. Time is up.'); 3. }, 3000);
1. function sum(op1, op2){2. return op1 + op2;3. }
![Page 15: JavaScript Proven Practises](https://reader035.vdocuments.mx/reader035/viewer/2022062512/5539ab914a79594f6c8b49ee/html5/thumbnails/15.jpg)
Situation 41. var total = variable1 + variable2;2. print(total);
code
1. 12
output
1. var variable1 = "1";2. var variable2 = "2";
data
1. var variable1 = document.elements["inputA"].value;
I’d never be so stupid to add strings?
![Page 16: JavaScript Proven Practises](https://reader035.vdocuments.mx/reader035/viewer/2022062512/5539ab914a79594f6c8b49ee/html5/thumbnails/16.jpg)
Situation 41. var total = parseInt(variable1) + parseInt(variable2);2. print(total);
code
3
output
1. var variable1 = "1";2. var variable2 = "2";
data
1. var variable1 = "064";2. var variable2 = "032";
data
78
output
64 base 8 = 52 base 1032 base 8 = 26 base 1052 + 26 = 78
![Page 17: JavaScript Proven Practises](https://reader035.vdocuments.mx/reader035/viewer/2022062512/5539ab914a79594f6c8b49ee/html5/thumbnails/17.jpg)
Unary OperatorJavaScript has one type for numbers
Other primitives: Object, string & boolean, RegExp, Math, Array, Date, Error, NativeError (mostly)
parseInt & parseFloat require you to set the numeric base the number is in – else it will try and guess
![Page 18: JavaScript Proven Practises](https://reader035.vdocuments.mx/reader035/viewer/2022062512/5539ab914a79594f6c8b49ee/html5/thumbnails/18.jpg)
Unary Operator(+<variable>) is the right way to get an number
Even though braces are optional - you should always have them, else it is hard to work out what is addition and what is unary
![Page 19: JavaScript Proven Practises](https://reader035.vdocuments.mx/reader035/viewer/2022062512/5539ab914a79594f6c8b49ee/html5/thumbnails/19.jpg)
Unary Operator Fixed1. var total = (+variable1) + (+variable2);2. print(total);
code
3
output
96
output
1. var variable1 = "1";2. var variable2 = "2";
data
1. var variable1 = "064";2. var variable2 = "032";
data
![Page 20: JavaScript Proven Practises](https://reader035.vdocuments.mx/reader035/viewer/2022062512/5539ab914a79594f6c8b49ee/html5/thumbnails/20.jpg)
Unary Operator vs. parseInt
1. parseInt("567Gb");
code
567
output
1. +"567Gb";
code
NaN
output
![Page 21: JavaScript Proven Practises](https://reader035.vdocuments.mx/reader035/viewer/2022062512/5539ab914a79594f6c8b49ee/html5/thumbnails/21.jpg)
Situation 5
1. function validate (idNumber) {2. var year = getYear(idNumber);3. // omitted4. }5. 6. function getYear(idNumber) {7. // omitted8. }
![Page 22: JavaScript Proven Practises](https://reader035.vdocuments.mx/reader035/viewer/2022062512/5539ab914a79594f6c8b49ee/html5/thumbnails/22.jpg)
NamespacesGroup things into namespaces, so that they are properly scoped.
Expose only what you need to expose.
There are at least 5 different ways to do namespaces – pick one as a team. I’m going to show you my favourite next – the Self-Executing Anonymous Function Public & Private.
![Page 23: JavaScript Proven Practises](https://reader035.vdocuments.mx/reader035/viewer/2022062512/5539ab914a79594f6c8b49ee/html5/thumbnails/23.jpg)
Namespaces Fixed1. (function (idNumbers, undefined) {2. 3. idNumbers.validate = function (idNumber) {4. var year = getYear(idNumber);5. // omitted6. }7. 8. function getYear(idNumber) {9. // omitted10. }
11. }(window.idNumbers = window.idNumbers || {}));
![Page 24: JavaScript Proven Practises](https://reader035.vdocuments.mx/reader035/viewer/2022062512/5539ab914a79594f6c8b49ee/html5/thumbnails/24.jpg)
Namespaces Fixed1. idNumbers.validate(""); // works
2. idNumbers.getYear(""); // undefined
![Page 25: JavaScript Proven Practises](https://reader035.vdocuments.mx/reader035/viewer/2022062512/5539ab914a79594f6c8b49ee/html5/thumbnails/25.jpg)
Namespaces Fixed
1. (function (idNumbers, $, undefined) {2. 3. // omitted
4. }(window.idNumbers = window.idNumbers || {}, jQuery));
![Page 26: JavaScript Proven Practises](https://reader035.vdocuments.mx/reader035/viewer/2022062512/5539ab914a79594f6c8b49ee/html5/thumbnails/26.jpg)
Separation of concernsTaking namespaces further – practise separation of concerns
Put JavaScript into separate files – do not inline in the HTML file.Build as much of your JavaScript do it is not tied to HTML or CSS Let HTML do what it is good at (organisation of content), CSS do what it is good at (presentation style) & JavaScript do what it is good at
1. itemX.color = "#fff";2. itemX.font-family = "Consolas";
bad
1. itemX.style = "codeBlock";
good
![Page 27: JavaScript Proven Practises](https://reader035.vdocuments.mx/reader035/viewer/2022062512/5539ab914a79594f6c8b49ee/html5/thumbnails/27.jpg)
Situation 61. with (document.forms["mainForm"].elements) {2. input1.value = "junk";3. input2.value = "junk";4. }
code
1. <html>2. <body>3. <form id="mainForm">4. <input id="input1" type="text">5. <input id="input2" type="text">6. </form>7. </body>8. </html>
data
![Page 28: JavaScript Proven Practises](https://reader035.vdocuments.mx/reader035/viewer/2022062512/5539ab914a79594f6c8b49ee/html5/thumbnails/28.jpg)
Situation 6 cont.1. with (document.forms["mainForm"].elements) {2. input1.value = "junk";3. input2.value = "junk";4. }
code
1. <html>2. <body>3. <form id="mainForm">4. <input id="input1" type="text">
5. </form>6. </body>7. </html>
data
![Page 29: JavaScript Proven Practises](https://reader035.vdocuments.mx/reader035/viewer/2022062512/5539ab914a79594f6c8b49ee/html5/thumbnails/29.jpg)
Situation 6 cont.1. var input2;2. with (document.forms["mainForm"].elements) {3. input1.value = "junk";4. input2.value = "junk";5. }
code
1. <html>2. <body>3. <form id="mainForm">4. <input id="input1" type="text">5. </form>6. </body>7. </html>
data
![Page 30: JavaScript Proven Practises](https://reader035.vdocuments.mx/reader035/viewer/2022062512/5539ab914a79594f6c8b49ee/html5/thumbnails/30.jpg)
Avoid WithNo way to really know who/what will be changed
![Page 31: JavaScript Proven Practises](https://reader035.vdocuments.mx/reader035/viewer/2022062512/5539ab914a79594f6c8b49ee/html5/thumbnails/31.jpg)
Avoid with - Fixed
1. var o = document.forms["mainForm"].elements;2. o.input1.value = "junk";3. o.input2.value = "junk";
![Page 32: JavaScript Proven Practises](https://reader035.vdocuments.mx/reader035/viewer/2022062512/5539ab914a79594f6c8b49ee/html5/thumbnails/32.jpg)
Situation 7
1. var o = new Object(); 2. o.name = 'Jeffrey'; 3. o.lastName = 'Way'; 4. o.someFunction = function() { 5. console.log(this.name); 6. }
code
![Page 33: JavaScript Proven Practises](https://reader035.vdocuments.mx/reader035/viewer/2022062512/5539ab914a79594f6c8b49ee/html5/thumbnails/33.jpg)
Prefer object literalsPREFER
Allows for more flexibility, cleaner code (no constructors) & you don’t need to worry about constructor parameter ordering.
![Page 34: JavaScript Proven Practises](https://reader035.vdocuments.mx/reader035/viewer/2022062512/5539ab914a79594f6c8b49ee/html5/thumbnails/34.jpg)
Prefer object literals - fixed1. var o = { 2. name : 'Jeffrey',3. lastName : 'Way',4. someFunction : function() { 5. console.log(this.name); 6. }7. };
1. var o = {};
![Page 35: JavaScript Proven Practises](https://reader035.vdocuments.mx/reader035/viewer/2022062512/5539ab914a79594f6c8b49ee/html5/thumbnails/35.jpg)
Situation 8
1. var a = new Array(); 2. a[0] = "Robert";3. a[1] = "MacLean";
code
![Page 36: JavaScript Proven Practises](https://reader035.vdocuments.mx/reader035/viewer/2022062512/5539ab914a79594f6c8b49ee/html5/thumbnails/36.jpg)
Prefer object literalsApplies to arrays just as well
![Page 37: JavaScript Proven Practises](https://reader035.vdocuments.mx/reader035/viewer/2022062512/5539ab914a79594f6c8b49ee/html5/thumbnails/37.jpg)
Prefer object literals - fixed
1. var o = ["Robert", "MacLean"];
A common error in JavaScript programs is to use an object when an array is required or an array when an object is required. The rule is simple: when the property names are small sequential integers, you should use an array. Otherwise, use an object.
Douglas Crockford
![Page 38: JavaScript Proven Practises](https://reader035.vdocuments.mx/reader035/viewer/2022062512/5539ab914a79594f6c8b49ee/html5/thumbnails/38.jpg)
Situation 9
1. var x = "123";2. var y = 123;
3. x == y;
code
1. true
output
![Page 39: JavaScript Proven Practises](https://reader035.vdocuments.mx/reader035/viewer/2022062512/5539ab914a79594f6c8b49ee/html5/thumbnails/39.jpg)
Situation 9 cont.1. '' == '0'2. 0 == ''
3. false == 'false'4. false == '0'
5. false == undefined6. false == null7. null == undefined
8. ' \t\r\n' == 0
falsetrue
falsetrue
falsefalsetrue
true
![Page 40: JavaScript Proven Practises](https://reader035.vdocuments.mx/reader035/viewer/2022062512/5539ab914a79594f6c8b49ee/html5/thumbnails/40.jpg)
Use === rather than ==== is equality=== is identityEquality checks type, if type differs will convert and then check valuesIdentity checks type, if type differs will return false
![Page 41: JavaScript Proven Practises](https://reader035.vdocuments.mx/reader035/viewer/2022062512/5539ab914a79594f6c8b49ee/html5/thumbnails/41.jpg)
Use === rather than == - fixed1. "123" === 123; // false
2. '' === '0' // false3. 0 === '' // false
4. false === 'false' // false5. false === '0' // false
6. false === undefined // false7. false === null // false8. null === undefined // false
9. ' \t\r\n' === 0 // false
![Page 42: JavaScript Proven Practises](https://reader035.vdocuments.mx/reader035/viewer/2022062512/5539ab914a79594f6c8b49ee/html5/thumbnails/42.jpg)
Situation 10
1. function x(){2. return 3. 64. }
5. x();
code
output
![Page 43: JavaScript Proven Practises](https://reader035.vdocuments.mx/reader035/viewer/2022062512/5539ab914a79594f6c8b49ee/html5/thumbnails/43.jpg)
ALWAYS end with semicolonSemicolon is a statement separator in JavaScript
Putting semicolon’s in is optional – but then JavaScript will guess where the statements will be separated
Be consistent
![Page 44: JavaScript Proven Practises](https://reader035.vdocuments.mx/reader035/viewer/2022062512/5539ab914a79594f6c8b49ee/html5/thumbnails/44.jpg)
ALWAYS end with semicolon - fixed
1. function x(){2. return 6;3. }
4. x();
code
6
output
![Page 45: JavaScript Proven Practises](https://reader035.vdocuments.mx/reader035/viewer/2022062512/5539ab914a79594f6c8b49ee/html5/thumbnails/45.jpg)
Situation 11
1. var a = 1,2;2. var b = 1,2,3;3. var c = 99+1,99
code
2399
output
![Page 46: JavaScript Proven Practises](https://reader035.vdocuments.mx/reader035/viewer/2022062512/5539ab914a79594f6c8b49ee/html5/thumbnails/46.jpg)
Avoid the comma operatorComma operator – not the comma separator in arrays – can lead to very tricky to understand code.
Unless you are 100% sure about it – don’t use it
Even when you are 100% sure – add comments for the rest of us
![Page 47: JavaScript Proven Practises](https://reader035.vdocuments.mx/reader035/viewer/2022062512/5539ab914a79594f6c8b49ee/html5/thumbnails/47.jpg)
Comma Operator - Fixed1. var r = [], n = 0, a = 0, b = 1, next;
2. function nextFibonacci() { 3. next = a + b; 4. return b = (a = b, next);5. }
6. while(n++ < 10) {7. r.push(nextFibonacci());8. }
9. r; //[1, 2, 3, 5, 8, 13, 21, 34, 55, 89]
![Page 48: JavaScript Proven Practises](https://reader035.vdocuments.mx/reader035/viewer/2022062512/5539ab914a79594f6c8b49ee/html5/thumbnails/48.jpg)
Situation 121. foo = "awesome";
1. var foo = "awesome";2. delete foo;
1. var o = { foo: 123, foo: 456 };
1. function eval() { }
1. eval("var a = false;");2. print(a);
1. with
![Page 49: JavaScript Proven Practises](https://reader035.vdocuments.mx/reader035/viewer/2022062512/5539ab914a79594f6c8b49ee/html5/thumbnails/49.jpg)
Turn Strict mode ONAll code runs in the strict context which makes your code more stable, finds more coding problems and raises more exceptions.Can define strict in a function
![Page 50: JavaScript Proven Practises](https://reader035.vdocuments.mx/reader035/viewer/2022062512/5539ab914a79594f6c8b49ee/html5/thumbnails/50.jpg)
Turn Strict mode ONWhat does it do?
ECMAScript 3 deprecated methods raise exceptionsUnassigned variables throw exceptionsDelete throws exceptionsDuplicate properties throw exceptionsHijacking eval throws exceptionsEval code is sandboxedWith is goneMORE!!!
Full info: http://dmitrysoshnikov.com/ecmascript/es5-chapter-2-strict-mode/
![Page 51: JavaScript Proven Practises](https://reader035.vdocuments.mx/reader035/viewer/2022062512/5539ab914a79594f6c8b49ee/html5/thumbnails/51.jpg)
Turn Strict mode ONFor this talk it helps with:
Situation 1 – always use var. Undeclared variables will syntax errorSituation 4 – parseInt defaults to decimal in strict mode
Your mileage may vary here: Chrome 19 does it wrong IE 10 does it right
Situation 6 – with. Always gives syntax error
![Page 52: JavaScript Proven Practises](https://reader035.vdocuments.mx/reader035/viewer/2022062512/5539ab914a79594f6c8b49ee/html5/thumbnails/52.jpg)
Turn Strict mode ON - Fixed1. "use strict";
1. foo = "awesome"; // exception2. var bar = "awesome";3. delete bar; // exception4. var o = { foo: 123, foo: 456 }; // exception5. function eval() { } // exception6. eval("var a = false;");7. print(a); // undefined8. with //syntax error
1. function demo(){2. "use strict";3. // more4. }
![Page 53: JavaScript Proven Practises](https://reader035.vdocuments.mx/reader035/viewer/2022062512/5539ab914a79594f6c8b49ee/html5/thumbnails/53.jpg)
Questions?
![Page 54: JavaScript Proven Practises](https://reader035.vdocuments.mx/reader035/viewer/2022062512/5539ab914a79594f6c8b49ee/html5/thumbnails/54.jpg)
Next week: Tools
included will be tools that solve all these issues
![Page 55: JavaScript Proven Practises](https://reader035.vdocuments.mx/reader035/viewer/2022062512/5539ab914a79594f6c8b49ee/html5/thumbnails/55.jpg)
Sourceshttp://www.javascripttoolbox.com/bestpractices
http://net.tutsplus.com/tutorials/javascript-ajax/24-javascript-best-practices-for-beginners/
http://stackoverflow.com/
http://www.crockford.com/
http://www.jslint.com/lint.html#options
http://enterprisejquery.com/2010/10/how-good-c-habits-can-encourage-bad-javascript-habits-part-1/