Let's JavaScript

6,497 views

Published on

1. What is JavaScript
2. Who use JavaScript
3. Variables
4. Functions and scope
6. Objects
7. Constructors and prototypes

Published in: Technology
2 Comments
53 Likes
Statistics
Notes
No Downloads
Views
Total views
6,497
On SlideShare
0
From Embeds
0
Number of Embeds
305
Actions
Shares
0
Downloads
0
Comments
2
Likes
53
Embeds 0
No embeds

No notes for slide

Let's JavaScript

  1. 1. Let's JavaScript (Not any other programming language) by Pawel Dorofiejczyk
  2. 2. Java... what !? "Java is to JavaScript like car is to carpet"
  3. 3. ● Object Oriented ● Dynamic and lose typed ● No classes, no interfaces, no abstraction ● Prototypical inheritance ● No privacy control at object level ● Object as collection of properties ● Function scope
  4. 4. LOL! Who use that crap !?
  5. 5. ● Websites frontend ● Server Side JavaScript (node.js, Rhino) ● Document oriented databases: MongoDB, CouchDB ● Windows 8 (WinJS) ● GNOME Shell ● OpenOffice and Adobe Creative Suite (Photoshop, Illustrator, Dreamwaver) ● Adobe AIR and more...
  6. 6. Let's start brainwashing!
  7. 7. Let's create a variable var name = "Let's JavaScript"; //string var i = 1; //number ("integer") var fl = 1.11; //number ("float") var boo = true; //boolean glob = "I'm global string";
  8. 8. JavaScript's variable Local variable declaration by var keyword ● Global variable declaration - without var (don't use it!) ● Dynamic type ●
  9. 9. Variable types primitives objects special Number Object Null Function String Array Date Boolean RegExp Undefined
  10. 10. typeof - the crap? typeof "string var"; //returns "string"; typeof 1; //returns "number"; typeof {}; //returns "object"; typeof undefined; //returns "undefined"; typeof function(){}; //returns "function" But... typeof []; //returns "object" (!) typeof null; //returns "object" (!!!) typeof NaN; // returns "number" ;)
  11. 11. Let's create a function var f = function(arg) { //function body };
  12. 12. Function in JavaScript ● ● ● ● ● ● ● ● Is an object Can have properties and methods Is Closure Reference can be stored in variable Can create other functions Have own scope Have special property - prototype Native methods bind, apply, call
  13. 13. So... function hello() { console.log('Hello world'); Looks like "normal" function declaration, but in fact... } === var hello = function() { console.log('Hello world'); } ...it is translated to this form so anonymous function is created and it's reference is passed to var === var hello = new Function( "console.log('Hello world')" ); and what's more every function declaration is creation of new object
  14. 14. Function arguments ● Are stored in pseudo-array arguments ● Primitives (number, string, boolean) are always passed by value ● Objects are passed by reference
  15. 15. Function arguments var test = function(a, b, obj) { obj.modified = true; console.log(arguments); } var obj = {}; console.log(obj.modified); //'undefined' test(1, 'a', obj); //{ '0': 1, '1': 'a', '2': { modified: true } } console.log(obj.modified); //true It is object so was passed by reference
  16. 16. Accumulator problem Problem : "I want to create accumulator function which accumulates values passed to it" Solution: "In JavaScript, function is an object so I can create function with internal variable handling passed values sum"
  17. 17. How to do NOT use function var accumulator = function(x) { this.sum = (this.sum || 0) + x; return this.sum; } console.log(accumulator(1)); //1 console.log(accumulator(1)); //2 console.log(accumulator.sum); //undefined console.log(sum); //2 //whoups!
  18. 18. this IS NOT this ?!
  19. 19. this IS NOT this this by default refers to the object that a function is a member of { var accumulator = function(x) { this.sum = (this.sum || 0) + x; return this.sum; } } In this case, function is member of default global object so this refers to global object. If we run this code in browser, global object is window so this === window
  20. 20. Let’s try without this var accumulator = function(x) { accumulator.sum = (accumulator.sum || 0) + x; return accumulator.sum; } Public, so someone can spoil our internal state Ok… but... accumulator.sum = undefined; accumulator(1); //returns NaN :(
  21. 21. Scope, the ultimate!* *Function is the ultimate but without scope, function is nothing
  22. 22. Let's create a scope var f = function() { //new scope :) }; looks familiar?
  23. 23. or in other way... (function() { //new scope }());
  24. 24. JavaScript's scope ● Is static (lexical) ● Is created only by function ● Function arguments becomes part of scope ● Child scope have reference to parent scope (scope chain) ● this is not scope (!!!)
  25. 25. Function scope var test = 'global scope var'; var f = function() { var test = 'function f scope'; console.log(test); } Local test variable declaration, covers global test variable console.log(test); //returns 'global scope var' f(); //returns 'function f scope'
  26. 26. Hidden scope reference var test = 'global scope var'; var a = function() { console.log(test); } var b = function(callback) { var test = 'function b scope var'; callback(); } b(a); //returns 'global scope var' Function object contains hidden reference to scope in which was created
  27. 27. Hidden scope reference var test = 5; var inc = function() { return ++test; } var dec = function() { return --test; } inc(); //returns 6 dec(); //returns 5 NOT 4 Both functions inc and dec have reference to common scope so both can modify the same variable
  28. 28. Returning to accumulator problem "Creator" function var accumulator = (function() { Initialize sum variable in var sum = 0; creator function's scope return function(x) { Adds x to parent scope's sum += x; variable sum return sum; }; })(); Immediate executing Scope based privacy!
  29. 29. Common scoping mistake var callbacks = []; for(var i = 0; i < 10; i++) { callbacks[i] = function() { console.log(i); } } for(var index in callbacks) { callbacks[index](); }
  30. 30. Common scoping mistake var callbacks = []; for(var i = 0; i < 10; i++) { callbacks[i] = function() { console.log(i); } At the end of for loop, i === 10 } for(var index in callbacks) { callbacks[index](); } For loop doesn't create new scope, so variable i is global Log global variable i
  31. 31. .bind for the rescue! bind is Function object method which creates new function with bounded parameters
  32. 32. .bind for the rescue! var log = function(x) { console.log(x); } Object reference which will be bound to this variable in function scope (It doesn't matter in this case) var logHello = log.bind(null, ”Hello”); log(1); //prints 1 log(”test”); //prints test logHello(); //prints Hello Values which will be bound to function’s parameters
  33. 33. Common scoping mistake FIXED var callbacks = []; var logger = function(i) { console.log(i); } Create local scope variable i Log logger function's scope variable i for(var i = 0; i < 10; i++) { callbacks[i] = logger.bind(null, i); } Returns new function with bounded global variable i value as function argument
  34. 34. Let's create an object var obj = {};
  35. 35. B-B-B-B-But... Where is the class?!
  36. 36. Object-oriented, NOT Class-oriented Java JavaScript class HelloWorld { public void greet() { System.out.println('Hello!'); } } var obj = { greet: function() { console.log('Hello'); } } HelloWorld obj = new HelloWorld(); obj.greet() obj.greet();
  37. 37. JavaScript Object ● ● ● ● ● ● ● ● ● Dynamic, not ordered, key-value Collection of properties Array access or object access Iterable Created in runtime Object literal {} No privacy control at object level Prototypical inheritance Constructor functions
  38. 38. MOAR objects!
  39. 39. Simple objects var obj = { prop1: 'test' //add property at creation time } obj.prop2 = function() { //add property later console.log(this.prop1); } console.log(obj.prop1 == obj['prop1']); //returns true obj['prop2'](); //returns 'test'
  40. 40. Iterate objects var obj = { prop1: 'test1', prop2: 'test2', prop3: function(){} } for(var prop in obj) { console.log(obj[prop]); } Returns: 'test1' 'test2' [Function] OR 'test2' 'test1' [Function] OR ...
  41. 41. Iterate objects var obj = { prop1: 'test1', prop2: 'test2', prop3: function(){} } for(var prop in obj) { console.log(obj[prop]); } IT DOESN'T GUARANTEE ORDER!!!
  42. 42. Constructors in JavaScript Constructor is not magic object method. It's a function which returns new objects.
  43. 43. Constructors in JavaScript Java JavaScript class HelloWorld { private String greetMsg; function HelloWorld(greetMsg) { return { greet: function() { console.log(greetMsg); } } } public HelloWorld(String greetMsg) { this.greetMsg = greetMsg; } public void greet() { System.out.println(this.greetMsg); } } HelloWorld hi = new HelloWorld('Hi!'); obj.greet(); var hi = HelloWorld('Hi!'); hi.greet();
  44. 44. new and prototype
  45. 45. How new works Have to be used with constructor function ● Uses prototype function property reference as __proto__ of new object ● Binds new object to constructor's this ● Executes constructor function ●
  46. 46. How new works var HelloWorld = function(greetMsg) { this.greetMsg = greetMsg; Don't use return. New object will be returned automatically } HelloWorld.prototype.greet = function() { console.log(this.greetMsg); } var hi = new HelloWorld('Hi!'); hi.greet(); We create our constructor as new function object this is binded to new object so we declare object variable greetMsg We declare common object's properties in constructor function's prototype
  47. 47. How new works HelloWorld.prototype ● greet HelloWorld ● prototype hi ● __proto__ hello ● __proto__ *Imagine __proto__ is hidden reference (it is available in some browsers but It is not standard)
  48. 48. How new works var HelloWorld = function(greetMsg) { this.greetMsg = greetMsg; Don't use return. New object will be returned automatically } HelloWorld.prototype.greet = function() { console.log(this.greetMsg); } var hi = new HelloWorld('Hi!'); hi.greet(); console.log(hi.greetMsg); //returns 'Hi!' We create our constructor as new function object this is binded to new object so we declare object variable greetMsg We declare common object's properties in constructor function's prototype
  49. 49. Privacy problem - how to do NOT fix var HelloWorld = function(greetMsg) { } HelloWorld.prototype.greet = function() { console.log(greetMsg); } We would like to keep greetMsg private. As we know, the only way is to do it private in constructor's scope We are trying to get private variable but it is different scope which don't have access to constructor's scope var hi = new HelloWorld('Hi!'); hi.greet(); //ReferenceError: greetMsg is not defined
  50. 50. Privacy problem fix var HelloWorld = function(greetMsg) { this.greet = function() { We creating greet function inside constructor so it has access to constructor's scope. console.log(greetMsg); } } Consider that it is not part of prototype so we create new function per object creation. In JavaScript, memory is price for privacy. var hi = new HelloWorld('Hi!'); hi.greet(); console.log(hi.greetMsg); //returns 'undefined'
  51. 51. Forgotten new disaster var HelloWorld = function(greetMsg) { this.greetMsg = greetMsg; } this is binded to global object so we declare global variable greetMsg HelloWorld.prototype.greet = function() { console.log(this.greetMsg); Prototype won't be used, so we won't have greet method } Disaster begins here var hi = HelloWorld('Hi!'); hi.greet(); //TypeError: Cannot call method 'greet' of undefined console.log(greetMsg); //returns 'Hi!'
  52. 52. Your application has just been blown up Do you still like new?
  53. 53. Classical inheritance var Animal = function(name) { this.name = name; } Animal.prototype.getName = function() { return this.name; } var dolphin = new Animal('Dolphin'); dolphin.getName(); //returns 'Dolphin'
  54. 54. Classical inheritance We want WalkingAnimal, which extends Animal and adds method walk var WalkingAnimal = function() { } We need constructor function WalkingAnimal.prototype = new Animal(); We have to set object we would like to extend as constructor prototype. Unfortunately we have to call constructor to create object. We don't pass any arguments so name will be undefined
  55. 55. Classical inheritance var WalkingAnimal = function(name) { We should not forget Animal.call(this, name); about calling Animal constructor to do it's job } WalkingAnimal.prototype = new Animal(); WalkingAnimal.prototype.walk = function() { console.log(this.getName() + 'is walking'); Next we add method walk } to WalkingAnimal prototype var cow = new WalkingAnimal('Cow'); cow.getName(); //returns 'Cow' cow.walk(); //'Cow is walking'
  56. 56. Looks ugly?
  57. 57. Object.create* var WalkingAnimal = function(name) { Animal.call(this, name); } WalkingAnimal.prototype = Object.create(Animal.prototype); WalkingAnimal.prototype.walk = function() { console.log(this.getName() + ' is walking'); } Object.create sets hidden __proto__ reference to Animal.prototype but without calling constructor *Introduced in JavaScript 1.6
  58. 58. inherits function to hide ugly stuff Function.prototype.inherits = function(parent, methods) { this.prototype = Object.create(parent.prototype); We store parent in this.prototype.$parent = parent; $parent variable. Can be useful later for(name in methods) { this.prototype[name] = methods[name]; } } We copy every method from methods object to function prototype
  59. 59. inherits method usage var WalkingAnimal = function(name) { this.$parent.call(this, name); } WalkingAnimal.inherits(Animal, { walk: function() { console.log(this.getName() + 'is walking'); } }
  60. 60. Or maybe don't do it classical ● ● ● ● ● Don't use new Don't use prototype Forgot about inheritance tree Use composition and mixins Use power of functions (including functional programming) ● Treat objects like function namespace or data container not state container ● Occasionally use Object.create and Object. defineProperty if you need
  61. 61. References ● Douglas Crockford "JavaScript: The good parts" ● Douglas Crockford's site (http://www.crockford.com/) ● Dymitry Soshnikov's blog (http://dmitrysoshnikov.com) ● Mozilla's "A re-introduction to JavaScript" (https://developer.mozilla.org/enUS/docs/JavaScript/A_re-introduction_to_JavaScript?redirect=no) ● Angus Croll's blog (http://javascriptweblog.wordpress.com)
  62. 62. Questions?
  63. 63. Want more? Here you are director's cut ;)
  64. 64. JavaScript primitives with methods? var a = 1; console.log(typeof a); //returns 'number' console.log(a instanceof Number); //returns false console.log(a.toExponential()); //returns 1e+0 var b = "abc"; console.log(typeof b); //returns 'string' console.log(b instanceof String); //returns false console.log(b.slice(1)); //returns 'bc' var c = true; console.log(typeof c); //returns 'boolean' console.log(c instanceof Boolean); //returns false console.log(c.toString()); //returns 'true'
  65. 65. The secret life of primitives var a = 1; a.toExponential(); It is not really method of primitive. = var a = 1; (new Number(a)).toExponential(); Every time you trying access primitive method, new object, containing primitive value is created secretly.

×