1 / 50

OO Constructs in Javascript

This article discusses the benefits of using Object-Oriented constructs in JavaScript, including better separation of concerns, reduced code coupling, encapsulation, inheritance and re-use. It also explores different approaches to dynamic web development, AJAX, HTML5 JavaScript capabilities, JavaScript libraries, writing apps with JavaScript, and the use of PhoneGap.

regalado
Download Presentation

OO Constructs in Javascript

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. OO Constructs in Javascript COMP319

  2. Why bother? • OO allows for better • Separation of concerns • Reduced code coupling • Encapsulation • Inheritance and re-use • Javascript • HTML5 provides powerful UI constructs • Inherent part of all modern applications COMP319

  3. Approaches to dynamic web development • Server side (PHP/Java/C#) to generate dynamic content • Request to server, server compiles and executes dynamic web page • Whole web page has to be generated when content changes • HTML, Javascript Ajax • Web page can be generated using Javascript, server communications using Ajax COMP319

  4. AJAX Asynchronous JavaScript + XML • Request sent to server using Javascript object • XMLHttpRequest() • Benefits • User can interact with page while request is being processed • Provides for faster page updates • Provides clear model/view/controller separation COMP319

  5. AJAX model Server side Application service Database HTML + Javascript code AJAX request Static or Dynamic server page Page fetch COMP319

  6. HTML5 Javascript capabilities • Standard scripting • Variables, control structures (if case for while etc) • Graphics 2D API • Canvas type drawing • Sound • DOM building (Document object model) • Build HTML page in Javascript • Local storage (persistance) • Geolocation COMP319

  7. Javascript libraries • Jquery • Cross platform JScript development • PIXI JS • Sprite library (also supports WebGL) • AngularJS • Web development Javascript library • MVC Framework • SoundJS • Sound library COMP319

  8. Javascript for writing Apps • Using Phonegap HTML5 Javascript application can be translated to • iPhone, Android, Windows, Blackberry • Phonegap can access functions such as • Camera, Compass, Accelerometer • Write one application  Many platforms • Slower than standard application but still fast COMP319

  9. Issues with Phonegap • Slower than native application but • Most applications are network bound • New phonegap technologies such as Steroids from Appgyver have improved Phonegap • http://www.appgyver.com/ • Hardware is faster all the time • Can be integrated with native code • App store approval • iPhone app must use native UI features • Many Phonegap applications have been approved by iPhone COMP319

  10. So.. • HTML5 Javascript very powerful • Complex application UI can be built • However • Javascript doesn’t have keywords such as • private • class • interface COMP319

  11. Javascript type checking • Uses dynamic typing • Sometimes called Duck typing • Based in the concept • If it walks like a Duck, looks like a Duck and sounds like a Duck • It’s a COMP319

  12. Type safety checking • Not implicit in the language • var A=1 • A =“Hello”; // allowed • Solutions • Add in Javascript code type checking (no good for above) • Use Google’s closure compiler COMP319

  13. Javascript has objects and types but no classes • Example • var myvar=“Hello World”; • This has created a string object • How do we know it’s a string object • It has the attribute • length • It has the methods • substring indexof etc. • Also can use typeof (see later slides) COMP319

  14. Javascript variable scope • Default public and global • var myAge=21 • Can be declared in function, this creates local, private but volatile variables function myFunct() { var myAge=21; Alert(“Age is “+myAge); } // myAge dissappears after closing // but not always… see closures later COMP319

  15. Creating objects in Javascript • Can be created implicitly • var a=“Seb” • Or new keyword is available • var a=new String(“Seb”); • var person=new Object(); • Objects can have attributes • person.forename=“Seb”; • person.surname=“Coope”; • Or even • a.surname=“Seb”; // totally mutable COMP319

  16. Prototypes • Javascript has no class keyword.. how to create classes • Javascript uses prototypes • What is a prototype? • Describes the attributes and methods of a Javascript object • Example • Prototype for String objects contains the attributes length and substring etc. COMP319

  17. Prototypes when creating objects • In Javascript there are no classes, new objects can be created using a current object • The new object has the same properties as the existing object • To make a new object from the current object, use the create method • var newObject=Object.create(oldObject); COMP319

  18. Class definition var Person=new Object(); Person.surname=""; // Persons surname Person.dob=null; // Date of birth Person.setSurname=function(surname) { this.surname=surname; } Person.getSurname=function() { return(this.surname); } COMP319

  19. Creating an object from another var person1=Object.create(Person); person1.setSurname("Coope"); var person2=Object.create(Person); person2.setSurname("Smith"); alert("person1.surname :"+person1.getSurname()+" person2.surname :"+person2.getSurname()); // Note all attributes are public .. person1.surname is available COMP319

  20. Adding DOB Person.setDOB=function(day,month,year) { this.dob=new Date(year,month,day,0,0,0,0); } But how about type checking… • person2.setDOB(24,12,1972); • person1.setDOB(24,12,"Fred"); // NO ERROR COMP319

  21. Inheritance • We can also use Person as a base for another object prototype • var doctor=Object.create(Person); • doctor.yearsExperience=0; • var doctor1=Object.create(Doctor); • doctor1.yearsExperience=5; • doctor1.setSurname(‘Jones’); COMP319

  22. Using constructors function Person(surname) { this.surname=surname; this.dob=null; this.getSurname =function() { return(this.surname); } this.setSurname = function(surname) { this.surname=surname; } this.setDOB=function(day,month,year) { this.dob=new Date(year,month,day,0,0,0,0); } } COMP319

  23. Emulating attribute privacy using closures (no private in Javascript) function Person(surname) { var sname=surname; // private attribute closure var dob=null; // private attribute this.getSurname =function() { // privileged return(sname); // new instance of this // method for each new Person } this.setSurname = function(surname) { sname=surname; } this.setDOB=function(day,month,year) { this.dob=new Date(year,month,day,0,0,0,0); } } COMP319

  24. Fake privacy (pre-fixed names) function Person(surname) { this._surname=surname; this._dob=null; this.getSurname =function() { return(this._surname); } this.setSurname = function(surname) { this._surname=surname; } this.setDOB=function(day,month,year) { this._dob=new Date(year,month,day,0,0,0,0); } } COMP319

  25. Fake privacy using obfuscation function Person(_0x59c4x1){ this["_0x59c4x2"]=_0x59c4x1; this["_0x59c4x3"]=null; this["getSurname"]=function (){ return (this["_0x59c4x2"]);} ; this["setSurname"]=function ( _0x59c4x1){this["_0x59c4x2"]=_0x59c4x1;} ; this["setDOB"]=function (_0x59c4x4,_0x59c4x5,_0x59c4x6){ this["_0x59c4x3"]= new Date(_0x59c4x6,_0x59c4x5,_0x59c4x4,0,0,0,0);} ; } ; COMP319

  26. Privacy comparisons • Closure • Proper privacy • Uses more memory • Prefix • Very weak • Obfuscation • Code hard to read and manage • Requires software tool to do it effectively COMP319

  27. Note usage and interface remains unchanged… • var person1=Object.create(Person); • person1.setSurname("Coope"); • alert(“name is “+person1.getSurname()); • But surname is now hidden…. • alert(“name is “+person.surname); • // Displays undefined.. COMP319

  28. Inheritance function Doctor(surname,experience) { var yearsExperience; Person.apply(this, arguments); // constructor for superclass yearsExperience=experience; this.setYearsExperience =function(experience) { yearsExperience=experience; } this.getYearsExperience=function() { return(yearsExperience); } } COMP319

  29. Inheritance continued var doctor1=new Doctor("Coope",10); var doctor2=new Doctor("Smith",15); doctor2.setDOB(24,12,1972); doctor1.setDOB(24,12,"Fred"); alert("doctor1.getSurname():"+doctor1.getSurname()+" Experience:"+doctor1.getYearsExperience()); alert("doctor2.getSurname():"+doctor2.getSurname()+" Experience:"+doctor2.getYearsExperience()); COMP319

  30. Type checking • Not automatic • Javascript typeof • Limited use typeof doctor1 = object • Javascript objects have the property constructor COMP319

  31. Getting the type function getType(object) { if (object==null) return('null'); if (typeof(object)=="object") { if (object.constructor) { if (object.constructor.name) { return(object.constructor.name) } } } return(typeof(object)); } COMP319

  32. Improving the setDOB method this.setDOB=function(day,month,year) { if (getType(day)!='number') { throw new Error("Day must be number"); } if (getType(month)!='number') { throw new Error("Month must be number"); } if (getType(year)!='number') { throw new Error("Year must be number"); } this.dob=new Date(year,month,day,0,0,0,0); } COMP319

  33. Re-cap open closed (OO patterns) Classes should be closed for modification but open to extension Template pattern (Java example) public interface ICardProvider { boolean makeCardPayment(String number); } public class CardProviderBase implements ICardProvider { private boolean cardStolen(String number) { return(false); } public final Boolean makeCardPayment() { // closed with final If (cardStolen()) return(false); return(onMakeCardPayment(); // extension hook … open } protected boolean onMakeCardPayment() { return(false); } } COMP319

  34. Open closed re-cap public class NatWestCardProvider extends CardProviderBase { // Closed with final.. protected final booleanonCardPayment(String number) { return(true); } } COMP319

  35. Final • Note there is NO final keyword in Javascript • No realistic way to stop the overriding of a function • But • You can follow the same structure as the template method • You can force a sub-class to include an extension COMP319

  36. Renderable object example function Renderable() { this.onRender=function() { throw new Error("Render not implemented"); } this.render =function() { // base functionality here this.onRender(); } } COMP319

  37. Implementing render function function Person(surname) { Renderable.apply(this, arguments); this.onRender=function(id) { var div = document.getElementById(id); div.innerHTML=surname; } } COMP319

  38. Calling render function renderPage() { doctor1.render(“person1”); } <body onload="renderPage()"> <div id="doctor1"></div> </body> COMP319

  39. Interface definition.. // All function’s to throw exception function Renderable() { this.onRender=function() { throw new Error(“function not implemented “); // see code example for more complete // definition } } COMP319

  40. Modular structure • Mostly code is broken up into modules where each module is stored in a different file • In Javascript the modules are included from the HTML page they support <script type="text/javascript"src="src/ErrorCode.js"></script> • So • No way of including 1 Javascript file from another • No way of guaranteeing dependencies for a module are included • Many modules leads to slower load times for the whole page COMP319

  41. RequireJS • Supports • Lazy loading (code only loaded when needed) • Dependency (modules can specify which other modules they depend on) • Concatenation of code for live builds • Improves • Speed of page loading • Reliability COMP319

  42. RequireJS getting started • At the end of your HTML.. Include require.js (note pointer to main source) </body> <script data-main="src/main.js" src="src/require.js"></script> </html> COMP319

  43. main.js // Entry point module require.config({ // configuration paths: { // paths to modules "PIXI": "../../common/bower_components/pixijs/pixi.dev", }, }); // Error handler requirejs.onError = function(err) { var failedId = err.requireModules && err.requireModules[0]; alert("Failed loading modules "+failedId); }; COMP319

  44. Main.js continued.. define(["Doctor","Util"] ,function(Doctor,Util) { // Usually this would be the start of your application // in this case we are just going to run some test code var doctor1=new Doctor("Coope",10); var doctor2=new Doctor("Smith",15); doctor2.setDOB(24,12,1972); alert("doctor1.getSurname():"+doctor1.getSurname()+" Experience:"+doctor1.getYearsExperience()); }); COMP319

  45. Doctor.js (sub class extends Person) define([ "Person" ], function(Person) { 'use strict'; var constructor = function Doctor(surname,experience) { var yearsExperience; Person.apply(this, arguments); // superclass constuct this.setYearsExperience = function(experience) { yearsExperience = experience; }; this.getYearsExperience = function() { return (yearsExperience); }; }; return (constructor); });

  46. Person.js (super class) define([ "Renderable","Util" ], function(Renderable,Util) { 'use strict'; var constructor = function Person(surname) { Renderable.apply(this, arguments); // constructor for superclass var sname=surname; // private var dob=null; // private this.getSurname =function() { // privilidged return(sname); } this.setSurname = function(surname) { sname=surname; } COMP319

  47. this.onRender=function(id) { var div = document.getElementById(id); div.innerHTML=surname; } this.setDOB=function(day,month,year) { if (Util.getType(day)!='number') { throw new Error("Day must be number"); } if (Util.getType(month)!='number') { throw new Error("Monst must be number"); } if (Util.getType(year)!='number') { throw new Error("Year must be number"); } this.dob=new Date(year,month,day,0,0,0,0); } }; return (constructor); });

  48. Renderable.js (interface) define(function() { 'use strict'; var constructor = function Renderable() { this.onRender=function onRender(id) { var fName = arguments.callee.toString().match(/function ([^\(]+)/)[1]; throw new Error("Function not implemented : "+this.constructor.name+"."+fName+"()"); } this.render =function(id) { this.onRender(id); } }; return (constructor); });

  49. Util.js Singleton define(function() { var Util={}; // make util object .. Singleton Util.getType=function(object) { 'use strict'; if (object==null) return('null'); if (typeof(object)=="object") { if (object.constructor) { if (object.constructor.name) { return(object.constructor.name) } } } return(typeof(object)); } return(Util); }); COMP319

  50. Summary • Javascript important language with wide range of applications • Despite its weaknesses it’s possible to develop using OO methods in Javascript • Javascript can support the following • Objects, attributes and functions • Privacy • Inheritance • Type checking (via code additions) COMP319

More Related