These are the code sample used in the presentation. // References: // Eloquent JavaScript by Marijn Haverbeke, 2011 // JavaScript Enlightenment by Cody Lindley, 2011 // http://javascript.crockford.com/code.html //// EXPECTATIONS // javasript for java programmers // Mantra: javascript has no classes //// to var or not to var // run this with jasmine var x=1; y=2; console.log(window.x, window.y, 'x' in window, 'y' in window); ///////// falsy values 0, NaN, '', "", false, null, undefined //// == or === console.log(0 == false, 0===false); console.log(0 == "", 0===""); console.log(7 == "7", 7==="7"); console.log("8" == "8", "8"==="8"); ////////// null and undefined are types var a= null; var b= undefined; console.log(typeof a, typeof b); console.log(c); ///////// creating an object var obj1= {}; var obj2= new Object(); console.log(typeof obj1); console.log(typeof obj2); ///// defining properties on objects var obj= {k1:1, k2:2}; obj.prop1= 'hello'; obj['my prop2']= new Date(); console.log(obj); delete obj.k2; console.log(obj); console.log('k2' in obj); ////// strings var s1= new String('hello'); var s2= 'hello'; console.log(s1, s2); console.log(typeof s1, typeof s2); // object string ////// adding property to an instance var s1= new String("hello"); s1.prop1=42; console.log(s1, s1.prop1); // notice how we can add property to any object var s2= 'hello'; s2.prop2=43; console.log(s2, s2.prop2); //////// adding method to an existing prototype (class) String.prototype.substringAfter = function(start) { var i= this.indexOf(start); if (i<0) return ''; return this.substr(i+start.length); } console.log('abcde'.substringAfter('c')); console.log('substringAfter' in String.prototype); delete String.prototype.substringAfter; console.log('substringAfter' in String.prototype); //////// using for in var ar= [10, 20, 30]; for (var k in ar) { console.log(k, ar[k]); // notice how k is the key/index } var person= {fname:'abdul', lname:'habra', pay:100}; for (var k in person) { console.log(k, person[k]); } // so far for in is ok, but consider this Array.prototype.prop1 = 'some libraries do this'; var ar2= [10, 20, 30]; for (var k in ar2) { console.log(k, ar2[k]); // notice how we have 4 elements now } // solve it like this for (var k in ar2) { if (ar2.hasOwnProperty(k)) { console.log(k, ar2[k]); } } // better yet _.each(ar2, function(value) { console.log(value); }); ////////// declaring functions: 4 ways function statment(x,y) {return x+y;}; var expression= function(x,y) {return x+y;}; var namedExpression= function f(x,y) { return x+y;} var functionConstructor= new Function('x', 'y', 'return x+y;'); console.log(statment(1,3)); console.log(expression(1,3)); console.log(namedExpression(1,3)); console.log(functionConstructor(1,3)); ///////// reflecting on function parameters function f1() { for (var k in arguments) { console.log(k, arguments[k]); } } f1('a', 'b', 11) ////////////// Anonymous functions // suppose I have an object with method setCallback, // which takes a function // regular function: function f1(x) { return x*3;} obj.setCallback(f1); // or Anonymous functions obj.setCallback( function(x) { x*3}; ) // self invoking function var f = function(a,b) {console.log(a+b)} (1,2); // self invoking Anonymous functions (function(msg) { console.log(msg);} ) ('hello'); (function(msg) { console.log(msg);} ('hello')); //////// order of functions // run this with jasmine f1(); f2(); function f1() { console.log('in f1'); } var f2= function() { console.log('in f2'); } //// exceptions function playWithExceptions() { try { console.log('in try'); throw 'wow'; } catch(error) { console.log('in catch:', error.message); } console.log('after catch'); } ///// simulating a class declaration: Constructor function // Good for singletons function PolitePersonSingleton(name, age, sex) { this.getAge = function() { return sex==='f'? age/2 : age; } }; var john = new PolitePersonSingleton('john', 40, 'm'); var jane = new PolitePersonSingleton('jane', 40, 'f'); // if you forget "new", then, "this" is bound to global object console.log('john age ', john.getAge()); console.log('jane age ', jane.getAge()); ///// private/public methods function PolitePersonSingleton(name, age, sex) { this.getAge = function() { return sex==='f'? age/2 : age; }; function calculateIQ() { return Math.random() * 200; }; var privateVar=1; this.publicVar=2; }; var john= new PolitePersonSingleton('john', 40, 'm'); john.calculateIQ(); console.log(john.privateVar); console.log(john.publicVar); //// Simulating class with many instances function HonestPerson(name, age, sex) { function getAge() { return sex==='f'? age*0.8 : age; }; function calculateIQ() { return Math.random() * 200; }; var privateVar=1; var publicVar=2; return { getAge: getAge, publicVar: publicVar }; }; var jane= HonestPerson('jane', 40, 'f'); // No new var john= HonestPerson('john', 40, 'm'); console.log('john age ', john.getAge()); console.log('jane age ', jane.getAge()); //john.calculateIQ(); console.log(john.privateVar); console.log(john.publicVar); //// simulating class with many instances: add properties function HonestPerson(name, age, sex) { var that= {}; // properties container. do not use this or self var privateVar=1; var publicVar=2; function getAge() { return sex==='f'? age*0.8 : age; }; function calculateIQ() { return Math.random() * 200; }; function setJob(job) { that.job= job; } function getJob() { return that.job; } function toString() { return 'name=' + name + ', age=' + age + ', sex=' + sex + ', job=' + that.job; }; return { getAge: getAge, publicVar: publicVar, setJob: setJob, getJob: getJob, toString: toString }; }; var jane= HonestPerson('jane', 40, 'f'); var john= HonestPerson('john', 40, 'm'); jane.setJob('doctor'); john.setJob('nurse'); console.log('john job ', john.getJob()); console.log('jane job ', jane.getJob()); console.log(john.toString()); console.log(jane.toString()); ///// regular expressions var regex1= /a.*/; console.log(regex1.test('ab')); console.log(regex1.test('bb')); //////// UNEXPECTED BEHAVIOR (from java programmers perspective) ///// semicolon insertion function f1() { return true; } console.log(f1()); // be extra careful specially when you return objects like { ... } ///// parseInt console.log(parseInt("06")); console.log(parseInt("07")); console.log(parseInt("08")); console.log(parseInt("08", 10)); ///// arrays boundries var ar= ['a', 'b', 'c']; console.log(ar); ar[0]= 'A'; ar[1]= 'B'; ar[2]= 'C'; ar[30]= 'D'; // oops typo. "array out of bound exception"? console.log(ar); ///// parsing text, be careful with keys var text= 'praise thine Lord and Constructor'; var words= text.toLowerCase().split(' '); var count= {}; for (var i=0, n=words.length; i<n; i++) { var word= words[i]; if (count[word]) { count[word] = count[word] + 1; } else { count[word]= 1; } } //console.log(count); // what do you expect? //////////// What's next // Consider underscore.js // consider backbone.js |
Documents > JavaScript & Client >