JavaScript Proven Practises

Post on 22-Apr-2015

1046 Views

Category:

Technology

0 Downloads

Preview:

Click to see full reader

DESCRIPTION

 

Transcript

JavaScriptProven Practices

20 June 2012

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)

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

Douglas Crockford - Jslint.com

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

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

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

code

50

output

Always use varVariables have scope

GlobalFunction

Using var helps keep the scope straight

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?

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?

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

Situation 2 cont.

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

code

'awesome'

output

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!

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

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

Timers – SetTimeout & SetIntervalFunction contstructors

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. }

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?

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

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

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

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

Unary Operator vs. parseInt

1. parseInt("567Gb");

code

567

output

1. +"567Gb";

code

NaN

output

Situation 5

1. function validate (idNumber) {2. var year = getYear(idNumber);3. // omitted4. }5. 6. function getYear(idNumber) {7. // omitted8. }

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.

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 || {}));

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

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

Namespaces Fixed

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

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

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

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

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

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

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

Avoid with - Fixed

1. var o = document.forms["mainForm"].elements;2. o.input1.value = "junk";3. o.input2.value = "junk";

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

Prefer object literalsPREFER

Allows for more flexibility, cleaner code (no constructors) & you don’t need to worry about constructor parameter ordering.

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 = {};

Situation 8

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

code

Prefer object literalsApplies to arrays just as well

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

Situation 9

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

3. x == y;

code

1. true

output

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

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

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

Situation 10

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

5. x();

code

output

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

ALWAYS end with semicolon - fixed

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

4. x();

code

6

output

Situation 11

1. var a = 1,2;2. var b = 1,2,3;3. var c = 99+1,99

code

2399

output

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

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]

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

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

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/

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

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. }

Questions?

Next week: Tools

included will be tools that solve all these issues

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/

top related