Object Oriented JavaScript


Published on

An overview of object-oriented programming concepts in JavaScript.

Published in: Technology
1 Comment
  • Even those who THINK they know OO JavaScript need to refresh themselves once in a while to avoid being stuck in the 'production, deliver yesterday, fake it' cycle. Thanks for a a concise presentation that refocuses attention to how it -should- be done.
    Are you sure you want to  Yes  No
    Your message goes here
No Downloads
Total views
On SlideShare
From Embeds
Number of Embeds
Embeds 0
No embeds

No notes for slide

Object Oriented JavaScript

  1. 1. Getting from Scripts to Applications Donald J. Sipe | Refresh Jacksonville | November 11 th 2008
  2. 2. JavaScript <ul><li>We are here </li></ul>Pseudoclassical Inheritance Hello World!
  3. 3. JavaScript <ul><li>What we’ll be talking about </li></ul><ul><li>OOP Basics </li></ul><ul><li>Scope </li></ul><ul><li>Closures </li></ul><ul><li>Context </li></ul><ul><li>Appling to OOP </li></ul><ul><li>Constructors </li></ul><ul><li>Methods </li></ul><ul><ul><li>Public </li></ul></ul><ul><ul><li>Private </li></ul></ul><ul><ul><li>Privileged </li></ul></ul>
  4. 4. But First... Some handy tools <ul><li>Here are some handy things you might not know JavaScript can do: </li></ul><ul><li>Object-literal notation </li></ul><ul><li>Anonymous functions </li></ul><ul><li>Binary assignment </li></ul><ul><li>Dot-style and array-style access of properties </li></ul>
  5. 5. Handy Tools <ul><li>Object Literal Notation— Makes JSON possible </li></ul><ul><li>// The old way var myObject = new Object(); myObject.val = “test”; </li></ul><ul><li>// Using object literal notation var myObject = { val: “test” }; </li></ul>
  6. 6. Handy Tools <ul><li>Object Literal Notation </li></ul><ul><li>// The old way var myArray = new Array(1, 30, “Refresh”); </li></ul><ul><li>// Using object literal notation var myArray = [1, 30, “Refresh”]; </li></ul>
  7. 7. Handy Tools <ul><li>Anonymous Functions </li></ul><ul><li>In JavaScript, functions are treated as values, which means: </li></ul><ul><ul><li>Functions can be assigned to variables </li></ul></ul><ul><ul><li>Functions can be passed as arguments to other functions </li></ul></ul>
  8. 8. Handy Tools <ul><li>Anonymous Functions </li></ul><ul><li>// Using an anonymous function as an argument setTimeout( function () { alert( “Refresh” ); }, 1000 ); </li></ul><ul><li>// Using a function as a variable var myFunc = function () { alert( “Refresh” ); }; setTimeout(myFunc, 1000); </li></ul>
  9. 9. Handy Tools <ul><li>Anonymous Functions : Building a “scope bubble” Using an anonymous function to wrap code you don’t want in the global scope </li></ul><ul><li>var globalVar = “Refresh”; // Global scope </li></ul><ul><li>// Create a scope bubble ( function () { var privateVar = “Jacksonville”; alert( globalVar + “ ” + privateVar ); } )(); </li></ul><ul><li>alert (privateVar == undefined ); </li></ul>
  10. 10. Handy Tools <ul><li>Binary Assignment Set a default value only if the variable doesn’t have a value yet </li></ul><ul><li>// Traditional ternary assignment var myVar = myVar ? myVar : 0; </li></ul><ul><li>// Binary assignment var myVar = myVal || 0; </li></ul>
  11. 11. Handy Tools <ul><li>Dot-Style and Array-Style property access </li></ul><ul><li>var sampleObj = { color: “blue”, width: “16px” }; </li></ul><ul><li>// Traditional dot-style access alert( sampleObj.color == “blue” ); </li></ul><ul><li>// Alternative array-style access alert( sampleObj[“width”] == “16px” ); </li></ul>
  12. 12. <ul><li>Scope, Closures, and Context </li></ul>
  13. 13. Scope <ul><li>Only functions have scope. Blocks ( if , while , for , switch ) do not. </li></ul><ul><li>All variables are within the global scope unless they are defined within a function . </li></ul><ul><li>All global variables actually become properties of the window object </li></ul><ul><li>When variables are not declared using the var keyword, they decared globally. </li></ul>
  14. 14. Scope <ul><li>var foo = “orig”; // foo is now a global variable </li></ul><ul><li>if ( true ) { foo = “new”; // Global foo now equals “new” } </li></ul><ul><li>// create function to modify its own foo variable function test () { var foo = “old”; } </li></ul><ul><li>test(); alert( foo == “new” ); // Global foo still equals “new” </li></ul>
  15. 15. Scope <ul><li>If you forget to use the var keyword to define a value within a function—even if it’s only used within the function—the value will be defined globally. </li></ul><ul><li>var foo = “new”; alert( foo == “new” ); </li></ul><ul><li>// Omitting the var keyword reverts scope // of foo to global level function badTest () { foo = “bad news”; } </li></ul><ul><li>badTest(); // Global foo now equals “bad news” alert( foo == “bad news” ); </li></ul>
  16. 16. Scope: Inner Functions <ul><li>Functions can be defined within one another </li></ul><ul><li>Inner functions have access to the outer function’s variables and parameters. </li></ul><ul><li>function getRandomInt(max) { var randNum = Math.random() * max; function ceil() { return Math.ceil(randNum); } return ceil(); // Notice that no arguments are passed } // Alert random number between 1 and 5 alert(getRandomInt(5)); </li></ul>
  17. 17. Closures <ul><li>Inner functions maintain the scope they enjoyed when their parent function was called—even after the parent function has terminated. </li></ul><ul><li>This allows you to effectively pass variables to functions that may not be called for some time. </li></ul>
  18. 18. Closures <ul><li>function delayedAlert (message, delay) { // Set an enclosed callback setTimeout( function () { // Use message variable passed to outer function alert(message); }, delay); } </li></ul><ul><li>// Display a message with a 5 second delay delayedAlert(“Refresh”, 5000); </li></ul>
  19. 19. Context <ul><li>Your code will always be running within the context of another object </li></ul><ul><li>Context is maintained through the use of the this variable. </li></ul><ul><li>function increment() { this .x = this .x || 0; return this .x++; }; </li></ul><ul><li>alert( increment() == 0 ); </li></ul><ul><li>alert( increment() == 1 ); </li></ul>
  20. 20. Context <ul><li>var myObject = { set: function (newVal) { this .val = newVal; } }; </li></ul><ul><li>alert( myObject.val == null ); // val property not set yet </li></ul><ul><li>myObject.set(“Refresh”); alert( myObject.val == “Refresh” ); // val equals “Refresh” </li></ul><ul><li>// Change the context of set() to the window object window.set = myObject.set; window.set( “Refresh Jacksonville” ); </li></ul><ul><li>alert( myObject.val == “Refresh” ); </li></ul><ul><li>alert( window.val == “Refresh Jacksonville” ); </li></ul>
  21. 21. Context: Changing Contexts <ul><li>JavaScript provides two handy functions for executing a function within the context of another function: </li></ul><ul><li>call( ) </li></ul><ul><li>apply( ) </li></ul>
  22. 22. Context: Changing Contexts <ul><li>Using call() — Arguments passed by name </li></ul><ul><li>// Simple function to change the color style of a node function changeColor (newColor) { this .style.color = newColor; } </li></ul><ul><li>// window.changeColor has no style property, so call fails changeColor( “red” ); </li></ul><ul><li>// Grab the DOM node with the id “required” var reqField = document.getElementById( “required” ); </li></ul><ul><li>// Call changeColor() within reqField’s context changeColor.call( reqField, “red” ); </li></ul>
  23. 23. Context: Changing Contexts <ul><li>Using apply() — Arguments passed as an array </li></ul><ul><li>// Simple function to change the color style of a node function changeColor (newColor) { this .style.color = newColor; } </li></ul><ul><li>// Set the text color of the body element function setBodyTextColor () { changeColor.apply( document.body, arguments ); } </li></ul><ul><li>setBodyTextColor( “black” ); </li></ul>
  24. 24. <ul><li>Constructors and methods </li></ul>
  25. 25. Object Oriented Programming <ul><li>Now let’s apply all of this information to a more classical view of OOP in JavaScript: </li></ul><ul><li>Constructors </li></ul><ul><li>Object Methods </li></ul><ul><ul><li>Public </li></ul></ul><ul><ul><li>Private </li></ul></ul><ul><ul><li>Privileged </li></ul></ul>
  26. 26. About Objects <ul><li>Almost everything written in JavaScript is an object </li></ul><ul><li>Objects can be though of as a collection of properties—much like a hash in other languages </li></ul><ul><li>JavaScript doesn’t have a concept of classes like other object-oriented languages </li></ul><ul><li>Classes are simulated using a concept called prototypal inheritance </li></ul>
  27. 27. Constructors <ul><li>Like other languages, JavaScript uses the new operator to create new instances of objects. </li></ul><ul><li>// Create User object constructor function User ( name ) { this .name = name; } </li></ul><ul><li>// Create a new instance of a User var me = new User(“Bob”); </li></ul><ul><li>// Alert new user’s name alert( me.name == “Bob” ); </li></ul><ul><li>// Cannot call User directly alert( User.name == undefined ); // window.name is undefined </li></ul>
  28. 28. Methods
  29. 29. Public Methods <ul><li>One way to create a public method—a function that can be freely reference by code outside your object—is to attach it to the object’s prototype . </li></ul><ul><li>An object’s prototype is a special property that acts as a base reference of your object. </li></ul><ul><li>This prototype object is copied and applied to all new instances of your object. </li></ul>
  30. 30. Public Methods <ul><li>// Our User object written a different way var User = function (name) { this .name = name; } </li></ul><ul><li>// Add a public accessor method for name User. prototype .getName = function () { return this .name; } </li></ul><ul><li>var me = new User( “Bob” ); </li></ul><ul><li>alert( me.getName() == “Bob” ); </li></ul>
  31. 31. Private Methods <ul><li>Private methods are functions that are only accessible to methods inside your object and cannot be accessed by external code. </li></ul>
  32. 32. Private Methods <ul><li>// Our User object with some changes var User = function (name) { this .name = name; function welcome () { alert( “Welcome back, ” + this .name + “.”); } welcome(); } </li></ul><ul><li>// Create a new User var me = new User( “Bob” ); // Alerts: “Welcome, Bob.” </li></ul><ul><li>// Fails because welcome is not a public method me.welcome(); </li></ul>
  33. 33. “ Privileged” Methods <ul><li>The term privileged method was coined by Douglas Crockford. It is not a formal construct, but rather a technique. </li></ul><ul><li>Privileged methods essentially have one foot in the door: </li></ul><ul><ul><li>Then can access private methods and values within the object </li></ul></ul><ul><ul><li>They are also publicly accessible </li></ul></ul>
  34. 34. “ Privileged” Methods <ul><li>// Our User object with some tweaks var User = function (name, age) { var year = (new Date()).getFullYear() – age; this .getYearBorn = function () { return year; }; }; </li></ul><ul><li>// Create a new User var me = new User( “Bob”, 28 ); </li></ul><ul><li>// Access privileged method to access private year value alert( me.getYearBorn() == 1980 ); </li></ul><ul><li>// Fails because year is private alert( me.year == null ); </li></ul>
  35. 35. Grand Finale <ul><li>Using Scope , Closures , Contexts , and what we’ve discussed about OOP, we can dynamically generate classes based on information supplied to the constructor. </li></ul>
  36. 36. Grand Finale <ul><li>// Our User object modified to accept an object of properties function User (properties) { // Loop through properties and create getter and setter methods for ( var i in properties ) { function () { this [“get” + i] = function () { return properties[i]; }; this [“set” + i] = function (val) { properties[i] = val; }; })(); } } </li></ul><ul><li>// Create a new user, automatically creating get and set methods var me = new User( { name: “Bob”, age: 28 }); </li></ul>
  37. 37. Grand Finale <ul><li>// …continued </li></ul><ul><li>// Note that name is private within properties alert( me.name == null ); </li></ul><ul><li>// Access privileged getname() method alert( me.getname() == “Bob” ); </li></ul><ul><li>// Use the dynamically generated setter // to change the user’s age me.setage(21); alert( me.getage() == 21 ); </li></ul>
  38. 39. References <ul><li>Pro JavaScript Techniques, by John Resig </li></ul><ul><li>Douglas Crockford’s </li></ul><ul><li>YUI Theater Presentations </li></ul><ul><li>http://developer.yahoo.com/yui/theater </li></ul>