javascript proven practises

55
JavaScript Proven Practices 20 June 2012

Upload: robert-maclean

Post on 22-Apr-2015

1.050 views

Category:

Technology


0 download

DESCRIPTION

 

TRANSCRIPT

Page 1: JavaScript Proven Practises

JavaScriptProven Practices

20 June 2012

Page 2: JavaScript Proven Practises

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

JavaScript is a sloppy language, but inside it there is an elegant, better language. 

Douglas Crockford - Jslint.com

Page 4: JavaScript Proven Practises

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

Situation 1 cont.1. function demo(){2. i = 50;3. }

4. demo();5. // what is i?

code

50

output

Page 6: JavaScript Proven Practises

Always use varVariables have scope

GlobalFunction

Using var helps keep the scope straight

Page 7: JavaScript Proven Practises

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

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

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

Situation 2 cont.

1. eval("var a = 'awesome';");2. print(a);

code

'awesome'

output

Page 11: JavaScript Proven Practises

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

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

Avoid eval part 2eval can appear in sneaky locations in JavaScript

Timers – SetTimeout & SetIntervalFunction contstructors

Page 14: JavaScript Proven Practises

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

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

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

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

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

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

Unary Operator vs. parseInt

1. parseInt("567Gb");

code

567

output

1. +"567Gb";

code

NaN

output

Page 21: JavaScript Proven Practises

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

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

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

Namespaces Fixed1. idNumbers.validate(""); // works

2. idNumbers.getYear(""); // undefined

Page 25: JavaScript Proven Practises

Namespaces Fixed

1. (function (idNumbers, $, undefined) {2. 3. // omitted

4. }(window.idNumbers = window.idNumbers || {}, jQuery));

Page 26: JavaScript Proven Practises

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

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

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

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

Avoid WithNo way to really know who/what will be changed

Page 31: JavaScript Proven Practises

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

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

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

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

Situation 8

1. var a = new Array(); 2. a[0] = "Robert";3. a[1] = "MacLean";

code

Page 36: JavaScript Proven Practises

Prefer object literalsApplies to arrays just as well

Page 37: JavaScript Proven Practises

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

Situation 9

1. var x = "123";2. var y = 123;

3. x == y;

code

1. true

output

Page 39: JavaScript Proven Practises

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

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

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

Situation 10

1. function x(){2. return 3. 64. }

5. x();

code

output

Page 43: JavaScript Proven Practises

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

ALWAYS end with semicolon - fixed

1. function x(){2. return 6;3. }

4. x();

code

6

output

Page 45: JavaScript Proven Practises

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

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

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

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

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

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

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

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

Questions?

Page 54: JavaScript Proven Practises

Next week: Tools

included will be tools that solve all these issues

Page 55: JavaScript Proven Practises

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/