so you think you know javascript
TRANSCRIPT
So you think you know JavaScript?
1
Matt AppersonFounder / Owner
3
© 2013 Apperson Labs
JavaScript is a great language!
© 2013 Apperson Labs
But do a quick Google search and you see that many have no clue how to use it correctly to build apps
WHY?
© 2013 Apperson Labs
Ask any developer who has ever touched a website, and he will say he knows JavaScript...
WRONG?
© 2013 Apperson Labs
Seen this page much?
© 2013 Apperson Labs
DEATH TO CoffeeScript!!And all frameworks...
9
© 2013 Apperson Labs
10
© 2013 Apperson Labs
• JS has been around for a while, but it has been the red headed step child
11
© 2013 Apperson Labs
• JS has been around for a while, but it has been the red headed step child• Most JS examples and tutorials are legacy, hacks, and based on use in web pages
12
© 2013 Apperson Labs
• JS has been around for a while, but it has been the red headed step child• Most JS examples and tutorials are legacy, hacks, and based on use in web pages• JS is NOT strongly typed, so it’s easy to turn it into spaghetti code
© 2013 Apperson Labs
“Where are we going thunder?” - Brian Regan
•How JavaScript works (from 10,000 feet)
•Common mistakes
•Titanium gotchas (aka “the dark corners”)
© 2013 Apperson Labs
Objects
© 2013 Apperson Labs
Object usage and properties
false.toString(); // 'false'[1, 2, 3].toString(); // '1,2,3'
function Foo(){}Foo.bar = 1;Foo.bar; // 1
© 2013 Apperson Labs
Object usage and properties
2.toString(); // raises SyntaxError
2..toString(); // the second point is correctly recognized2 .toString(); // note the space left to the dot(2).toString(); // 2 is evaluated first
© 2013 Apperson Labs
Object usage and properties
var obj = { bar: 1, foo: 2, baz: 3};obj.bar = undefined;obj.foo = null;delete obj.baz;
for(var i in obj) { if (obj.hasOwnProperty(i)) { console.log(i, '' + obj[i]); }}
© 2013 Apperson Labs
function Foo() { this.value = 42;}Foo.prototype = { fun: function() {}};
function Bar() {}
// Set Bar's prototype to a new instance of FooBar.prototype = new Foo();Bar.prototype.foo = 'Hello World';
// Make sure to list Bar as the actual constructorBar.prototype.constructor = Bar;
var test = new Bar(); // create a new bar instance
JS Prototype (correct):
© 2013 Apperson Labs
Bar.prototype = Foo.prototype;
JS Prototype (incorrect):
String.prototype.yell() = function() { return this + 'yay!!!!';}
Not inheriting correctly...
Prototyping native objects...
© 2013 Apperson Labs
Functions
© 2013 Apperson Labs
Function declaration:
// Example 1var test = function() { return "yay!";}
// Example 2function TestTwo() { return "yay also!";}
console.log(test); // "yay"console.log(TestTwo); // "yay also!""
© 2013 Apperson Labs
Function declaration:
// Example 1console.log(test); // Errorvar test = function() { return "yay!";};
// Example 2console.log(TestTwo); // “yay also!”function TestTwo() { return "yay also!";}
© 2013 Apperson Labs
Closures
function Counter(start) { var count = start; return { increment: function() { count++; },
get: function() { return count; } }}
var foo = Counter(4);foo.increment();foo.get(); // 5
© 2013 Apperson Labs
Closures (the reference issue)
for(var i = 0; i < 10; i++) { setTimeout(function() { console.log(i); }, 1000);}
© 2013 Apperson Labs
Closures (the reference issue)
for(var i = 0; i < 10; i++) { (function(e) { setTimeout(function() { console.log(e); }, 1000); })(i);}
© 2013 Apperson Labs
Constructorsfunction Foo() { this.bla = 1;}
Foo.prototype.test = function() { console.log(this.bla);};var test = new Foo();
function Blob() { return false;}new Blob(); // an empty object, not what’s expected
function Test() { this.value = 2;
return { fun: 1 };}new Test(); // the returned object
© 2013 Apperson Labs
Constructors (factories)function Bar() { var value = 1; return { method: function() { return value; } }}Bar.prototype = { foo: function() {}};
new Bar();Bar();
© 2013 Apperson Labs
Constructors (dropping “new”)function Foo() { var obj = {}; obj.value = 'blub';
var private = 2; obj.someMethod = function(value) { this.value = value; }
obj.getPrivate = function() { return private; } return obj;}
© 2013 Apperson Labs
Constructors (dropping “new”)
•It uses more memory since the created objects do not share the methods on a prototype.
•In order to inherit, the factory needs to copy all the methods from another object or put that object on the prototype of the new object.
•Dropping the prototype chain just because of a left out `new` keyword is contrary to the spirit of the language.
© 2013 Apperson Labs
CommonMistakes
© 2013 Apperson Labs
setTimeout();
var timer = setTimeout(function() {// more code here}, 100);
This might not do what you think...
•It is expensive as it creates a new context
•The timer is not accurate as JS engines only have a single thread, forcing asynchronous events to queue waiting for execution.
© 2013 Apperson Labs
USING_CAPS_FOR_CONSTANTS
var DELAY = 20; // This is a constant, don’€šÃ„ôt change
For a long time we had to do this...
That is messy and dangerous... we have better options now!
const DELAY = 20; // This is a real constant
© 2013 Apperson Labs
parseInt();
var testONE = parseInt('20'); // This returns 20
© 2013 Apperson Labs
parseInt();
var testONE = parseInt('20'); // This returns 20
var testTWO = parseInt('08'); // This returns 0
© 2013 Apperson Labs
parseInt();
var testONE = parseInt('20'); // This returns 20
var testTWO = parseInt('08'); // This returns 0
var testTHREE = parseInt('08', 10); // This returns 08
© 2013 Apperson Labs
Global Variables
var bar = 'JavaScript can be fun!';
function foo() { bar = 'with a few exceptions'; return bar;}
console.log(foo()); // 'with a few exceptions'console.log(bar); // 'with a few exceptions'
© 2013 Apperson Labs
Global Variables
var bar = 'JavaScript can be fun!';
function foo() { var bar = 'with a few exceptions'; return bar;}
console.log(foo()); // 'with a few exceptions'console.log(bar); // 'JavaScript can be fun!'
© 2013 Apperson Labs
Global Variables
var bar = 'JavaScript can be fun!';
function foo() { var cat = bar cat = cat + ' yay!'; return bar;}
console.log(foo()); // 'Javascript can be fun! yay!'console.log(bar); // 'Javascript can be fun!'
© 2013 Apperson Labs
Not using hasOwnProperty();
function Cat() { // some code}
Cat.prototype.stomach = [ ];Cat.prototype.eat = function(food) { for( var i in food ) { this.stomach.push(food[i]); }};
© 2013 Apperson Labs
Not using hasOwnProperty();
function Cat() { // some code}
Cat.prototype.stomach = [ ];Cat.prototype.eat = function(food) { for( var i in food ) { if(food.hasOwnProperty(i)) { this.stomach.push(food[i]); } }};
© 2013 Apperson Labs
Using fake getters and setters...
function Foo(){ var _value;
this.getValue = function(){ return _value; };
this.setValue = function(val){ _value = val; };}
Foo.prototype.test = function() {console.log('The value is:' + this.value); // nopeconsole.log('The value is:' + this.getValue()); // OK...
}
© 2013 Apperson Labs
True getter and setters!
function Foo(){ var _value;
Object.defineProperty(this, "value", { get : function(){ return _value; }, set : function(newValue){ _value = newValue; }, enumerable : true });}
Foo.prototype.test = function() {console.log('The value is:' + this.value); // Yep!
}
Reference - https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/defineProperty
© 2013 Apperson Labs
Not returning `this` on non-getters
function test() { }
test.prototype.run = function() { console.log('Doing something...');};
test.prototype.sayHi = function() { console.log('Doing something else...');};
var bar = new test();bar.run();bar.sayHi();
© 2013 Apperson Labs
Not returning `this` on non-getters
function test() { }
test.prototype.run = function() { console.log('Doing something...'); return this;};
test.prototype.sayHi = function() { console.log('Doing something else...'); return this;};
var bar = new test().run().sayHi();
© 2013 Apperson Labs
Try / Catch - A good idea?
function test() { try { // do stuff here } catch(e) { //this will blow up sometimes and I don’t know why... }}
© 2013 Apperson Labs
Try / Catch...
function test() { try { // do stuff here } catch() { // this might work, and it might blow up.// I have no idea why it blows up sometimes }}
© 2013 Apperson Labs
Try / Catch...
function test() { try { // do stuff here } catch(e) { // this worksconsole.log(e); }}
// There is a performance hit, yet it is responsible. So weigh the choice to use it carefully
© 2013 Apperson Labs
Titanium gotchas...
Reference - http://developer.appcelerator.com/blog/2012/02/what-is-a-titanium-proxy-object.html
•Objects returned by the Titanium API are not true JS objects[TIMOB-5818]
•Common JS does not work the same on both platforms[TIMOB-8082]
•Multiple JS engines to consider
© 2013 Apperson Labs
BETA
© 2013 Apperson Labs
Q & A