In this video we’ll review pretty much everything about Object Oriented JavaScript. We’ll cover : JavaScript Objects, Objects in Objects, Constructor Functions, instanceof, Passing Objects to Functions, Prototypes, Adding Properties to Objects, List Properties in Objects, hasOwnProperty, Add Properties to Built in Objects, Private Properties, Getters / Setters, defineGetter, defineSetter, call, defineProperty, Constructor Function Getters / Setters, Inheritance, Intermediate Function Inheritance, Call Parent Functions, ECMAScript 6, Singleton Pattern, Factory Pattern, Decorator Pattern, Observer Pattern and more.
If you like videos like this, it helps me when you tell Google with a click here [googleplusone]
Code From the Video
oojavascript.html
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 |
<!DOCTYPE HTML> <html lang="en"> <head> <meta charset="UTF-8"> <title>Object Oriented JavaScript</title> </head> <body> <script type="text/javascript"> // A basic JavaScript object with properties and a method var customer = { name: 'Tom Smith', speak: function(){ // this allows you to reference a specific objects value // without knowing the objects name return "My name is " + this.name; }, // Objects can contain other objects address: { street: '123 Main St', city: 'Pittsburgh', state: 'PA' } }; document.write(customer.speak()+ "<br />"); // You access properties and object properties like this document.write(customer.name + " lives at " + customer.address.street + "<br />"); // You can add properties customer.address.country = "US"; document.write(customer.address.country + "<br />"); // Creating multiple objects of the same type with Constructor // Functions. Constructors provide the functions that classes // provide in other languages function Person(name, street) { // this allows us to refer to an object even though we // don't know its name before it is created this.name = name; this.street = street; this.info = function(){ return "My name is " + this.name + " and I live on " + this.street; } } // You call constructor functions with new var bobSmith = new Person("Bob Smith", "234 Main St"); document.write(bobSmith.info() + "<br />"); // instanceof tells you if an object is of a certain type document.write("Bob is a person : " + (bobSmith instanceof Person) + "<br />"); // You can pass an object to a function and change values function changeName(person){ person.name = "Sue Smith"; } changeName(bobSmith); document.write("Bob became " + bobSmith.name + "<br />"); // Objects are only equal if they reference the same object var person1 = new Person("Paul", "123 Main"); var person2 = new Person("Paul", "123 Main"); document.write("Are they equal " + (person1 == person2) + "<br />"); // ---------- PROTOTYPE ---------- // Every function has a prototype property that contains an object // You can add properties and methods to the prototype object // and then when you call for them to execute they are used // just as if they belonged to the object function getSum(num1, num2){ return num1 + num2; } // Get the number of function arguments document.write("Num of arguments : " + getSum.length + "<br />"); // You can add properties and methods to this object function Mammal(name){ this.name = name; this.getInfo = function(){ return "The mammals name is " + this.name; } } // Use prototype to add a property Mammal.prototype.sound = "Grrrrr"; // Use it to add a method Mammal.prototype.makeSound = function() { return this.name + " says " + this.sound; }; var grover = new Mammal("Grover"); document.write(grover.makeSound() + "<br />"); // List all properties of an object for( var prop in grover){ document.write(prop + " : " + grover[prop] + "<br />"); } // Check which property belongs to prototype vs. the object grover document.write("name Property of Grover : " + grover.hasOwnProperty("name") + "<br />"); document.write("sound Property of Grover : " + grover.hasOwnProperty("sound") + "<br />"); // You can add methods to built in JS objects Array.prototype.inArray = function inArray(value){ for(i = 0; i < this.length; i++){ if(this[i] === value){ return true; } } return false; } var sampArray = [1,2,3,4,5]; document.write("3 in array : " + sampArray.inArray(3) + "<br />"); // ---------- PRIVATE PROPERTIES ---------- // All properties in an object are public in that any function // can modify or delete these properties. // You can make properties private by declaring them as // variables in a constructor function SecretCode(){ // This value can't be accessed directly var secretNum = 78; // This function can access secretNum this.guessNum = function(num){ if(num > 78){ return "Lower"; } else if(num < 78){ return "Higher"; } else { return "You Guessed It"; } } } var secret = new SecretCode(); // Returns undefined document.write("Value of secretNum : " + secret.secretNum + "<br />"); document.write("Is 70 the number : " + secret.guessNum(70) + "<br />"); // Even if we add another function it can't access the secretNum SecretCode.prototype.getSecret = function(){ return this.secretNum; } document.write("The secret number is " + secret.getSecret() + "<br />"); // ---------- GETTERS AND SETTERS ---------- // Getters and Setters can protect data, or provide useful // ways to set its value // I'll show you a bunch of getters and setters you may come // in contact with var address = { street: "No Street", city: "No City", state: "No State", // Provides styled data all at once get getAddress() { return this.street + ", " + this.city + ", " + this.state; }, // Allows the user to set 3 values with 1 set setAddress (theAddress) { var parts = theAddress.toString().split(", "); this.street = parts[0] || ''; this.city = parts[1] || ''; this.state = parts[2] || ''; } } address.setAddress = "123 Main St, Pittsburgh, PA"; document.write("Address : " + address.getAddress + "<br />"); document.write("City : " + address.city + "<br />"); // ---------- CONSTRUCTOR GETTERS AND SETTERS ---------- // Still used even though it is (Deprecated) function Coordinates(){ this.latitude = 0.0; this.longitude = 0.0; } // Define the getter with the prototype to assign it to with // the property name and the getter function Object.__defineGetter__.call(Coordinates.prototype, "getCoords", function(){ return "Lat : " + this.latitude + " Long: " + this.longitude; }); // Define the setter with the prototype to assign it to with // the property name and the setter function Object.__defineSetter__.call(Coordinates.prototype, "setCoords", function(coords){ var parts = coords.toString().split(", "); this.latitude = parts[0] || ''; this.longitude = parts[1] || ''; }); var testCoords = new Coordinates(); testCoords.setCoords = "40.71, 74.00"; document.write("Coordinates : " + testCoords.getCoords + "<br />"); // ---------- GETTERS AND SETTERS WITH DEFINEPROPERTY ---------- function Point(){ this.xPos = 0; this.yPos = 0; } // Use defineProperty to set getters and setters // Pass the prototype to attach to along with the property name // and define the functions to associate with get and set Object.defineProperty(Point.prototype, "pointPos", { get: function(){ return "X: " + this.xPos + " Y: " + this.yPos; }, set: function(thePoint){ var parts = thePoint.toString().split(", "); this.xPos = parts[0] || ''; this.yPos = parts[1] || ''; } }); var aPoint = new Point(); aPoint.pointPos = "100, 200"; document.write("Point Position : " + aPoint.pointPos + "<br />"); // ---------- ECMASCRIPT 5.1 GETTERS AND SETTERS ---------- var Circle = function (radius) { this._radius = radius; }; Circle.prototype = { set radius(radius) { this._radius = radius; }, get radius() { return this._radius; }, get area() { return Math.PI * (this._radius * this._radius); } }; var circ = new Circle(10); circ.radius = 15; document.write("A circle with radius " + circ.radius + " has an area of " + circ.area.toFixed(2) + "<br />"); // ---------- INHERITANCE ---------- // When we ask for a property if it isn't found in the main object // then it is searched for in the prototype object. We are able // to inherit methods and variables from any object in a // chain of objects. function Animal(){ this.name = "Animal"; // toString is a function in the main Object that every // object inherits from this.toString = function() { return "My name is : " + this.name; }; } function Canine(){ this.name = "Canine"; } function Wolf(){ this.name = "Wolf"; } // Overwrite the prototype for Canine and Wolf Canine.prototype = new Animal(); Wolf.prototype = new Canine(); // After you overwrite prototype its constructor points to the // main object object so you have to reset the constructor after Canine.prototype.constructor = Canine; Wolf.prototype.constructor = Wolf; var arcticWolf = new Wolf(); // Wolf inherits toString from Animal document.write(arcticWolf.toString() + "<br />"); document.write("Wolf instance of Animal : " + (arcticWolf instanceof Animal) + "<br />"); // Properties added to any object in the chain is inherited Animal.prototype.sound = "Grrrrr"; Animal.prototype.getSound = function(){ return this.name + " says " + this.sound; } Canine.prototype.sound = "Woof"; Wolf.prototype.sound = "Grrrr Wooof"; document.write(arcticWolf.getSound() + "<br />"); // More often then not it makes more sense to just inherit the // prototype to speed up the lookup process function Rodent(){ this.name = "Rodent"; } function Rat(){ this.name = "Rat"; } Rodent.prototype = new Animal(); Rat.prototype = Rodent.prototype; Rodent.prototype.constructor = Rodent; Rat.prototype.constructor = Rat; var caneRat = new Rat(); // Wolf inherits toString from Animal document.write(caneRat.toString() + "<br />"); // ---------- INTERMEDIATE FUNCTION INHERITANCE ---------- function extend(Child, Parent){ var Temp = function(){}; Temp.prototype = Parent.prototype; Child.prototype = new Temp(); Child.prototype.constructor = Child; } function Deer(){ this.name = "Deer"; this.sound = "Snort"; } extend(Deer, Animal); var elk = new Deer(); document.write(elk.getSound() + "<br />"); // ---------- CALL PARENT METHODS ---------- function Vehicle(name) { this.name = "Vehicle" } // Functions for the parent object Vehicle.prototype = { drive: function(){ return this.name + " drives forward"; }, stop: function(){ return this.name + " stops"; } } function Truck(name) { this.name = name } // Inherit from Vehicle Truck.prototype = new Vehicle(); Truck.prototype.constructor = Truck; // Overwrite drive parent method Truck.prototype.drive = function(){ // Call the parent method with apply so that the parent // method can access the Trucks name value var driveMsg = Vehicle.prototype.drive.apply(this); return driveMsg += " through a field"; } var jeep = new Truck("Jeep"); document.write(jeep.drive() + "<br />"); document.write(jeep.stop() + "<br />"); // ---------- SINGLETON PATTERN ---------- // Singletons are used when you only ever want 1 object to // be created // Let's say you want to create a game character with fixed // stats function Hero(name){ // Check if the object exists if(typeof Hero.instance === 'object'){ // If it does return it return Hero.instance; } // if it doesn't then create the hero this.name = name; Hero.instance = this; return this; } var derekHero = new Hero("Derek"); document.write("Are hero is " + derekHero.name + "<br />"); // This won't change the name to Paul var paulHero = new Hero("Paul"); document.write("Are hero is " + paulHero.name + "<br />"); // ---------- FACTORY PATTERN ---------- // The factory pattern can be used to generate different // objects on request function Sword(desc){ this.weaponType = "Sword"; this.metal = desc.metal || "Steel"; this.style = desc.style || "Longsword"; this.hasMagic = desc.hasMagic || false; } function Bow(desc){ this.weaponType = "Bow"; this.material = desc.material || "Wood"; this.style = desc.style || "Longbow"; this.hasMagic = desc.hasMagic || false; } function WeaponFactory(){}; WeaponFactory.prototype.makeWeapon = function(desc){ var weaponClass = null; if(desc.weaponType === "Sword"){ weaponClass = Sword; } else if (desc.weaponType === "Bow"){ weaponClass = Bow; } else { return false; } return new weaponClass(desc); } var myWeaponFact = new WeaponFactory(); var bladeFist = myWeaponFact.makeWeapon({ weaponType: "Sword", metal: "Dark Iron", style: "Scythe", hasMagic: true }); document.write(bladeFist.weaponType + " of type " + bladeFist.style + " crafted from " + bladeFist.metal + "<br />"); // ---------- DECORATOR PATTERN ---------- // The decorator pattern allows you alter an object at run time function Pizza(price){ this.price = price || 10; } Pizza.prototype.getPrice = function(){ return this.price; } function ExtraCheese(pizza){ var prevPrice = pizza.price; pizza.price = prevPrice + 1; } var myPizza = new Pizza(10); ExtraCheese(myPizza); document.write("Cost of Pizza : $" + myPizza.price + "<br />"); // ---------- OBSERVER PATTERN ---------- // A single object notifies many objects (observers) when a // state change occurs var Observable = function() { this.subscribers = []; } Observable.prototype = { subscribe: function(subscriber) { // Add the subscriber object to the list this.subscribers.push(subscriber); }, unsubscribe: function(unsubscriber) { // Cycle through the subscriber array and delete // the unsubscriber for (i = 0; i < this.subscribers.length; i++) { if (this.subscribers[i] === unsubscriber) { this.subscribers.splice(i, 1); // We assume it only subscribed once so we // leave after it is found return unsubscriber.name; } } }, publish: function(data) { // Cycle through all subscribers and send them the update for (i = 0; i < this.subscribers.length; i++) { this.subscribers[i].receiveData(data); } } }; var OrganFanny = { name: "Organ Fanny", receiveData: function(data){ document.write(this.name + " received your info : " + data + "<br />"); } } var BoldmanYaks = { name: "Boldman Yaks", receiveData: function(data){ document.write(this.name + " received your info : " + data + "<br />"); } } // Add subscribers and alert them observable = new Observable(); observable.subscribe(OrganFanny); observable.subscribe(BoldmanYaks); observable.publish('IBM at $145.30'); document.write(observable.unsubscribe(OrganFanny) + " Unsubscribed<br />"); observable.publish('IBM at $145.33'); </script> </body> </html> |
ECMAScript 6 Object Oriented JavaScript
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 |
// ECMAScript 6 OOP with JavaScript // ----- Method Notation in Object Property Definitions ----- // EC5 WAY var addStuff = { sum: function(num1, num2){ return num1 + num2; } }; document.write("1 + 2 = ", addStuff.sum(1,2) + "<br />"); // EC6 WAY var addStuff = { sum(num1, num2){ return num1 + num2; } } document.write("1 + 2 = ", addStuff.sum(1,2) + "<br />"); // ----- CLASSES IN JAVASCRIPT ----- // EC5 WAY var Point = function(xPos, yPos){ this.xPos = xPos; this.yPos = yPos; }; Point.prototype.getPos = function(){ return "X: " + this.xPos + " Y: " + this.yPos; }; var point = new Point(100, 200); document.write("Point Pos : " + point.getPos() + "<br />"); // EC6 WAY class Point { constructor(xPos, yPos){ this.xPos = xPos; this.yPos = yPos; } getPos(){ return "X: " + this.xPos + " Y: " + this.yPos; } } var point = new Point(100,200); document.write("Point Pos : " + point.getPos() + "<br />"); // ----- MORE OOP IN JAVASCRIPT ----- // EC6 WAY class Animal { constructor(name){ this.name = name; } toString(){ return "Animal is named " + this.name; } // We can create static functions as well static getAnimal(){ return new Animal("No Name"); } } class Dog extends Animal{ constructor(name, owner){ // We can call the super class now super(name); this.owner = owner; } toString(){ // You can call super class methods as well return super.toString() + "<br />Dog is named " + this.name; } } var rover = new Dog("Rover", "Paul"); document.write(rover.name + " is owned by " + rover.owner + "<br />"); document.write(rover.toString() + "<br />"); // Call the static function var bowser = Animal.getAnimal(); document.write("Bowser info : " + bowser.toString() + "<br />"); |
Leave a Reply