$30 off During Our Annual Pro Sale. View Details »

Understanding JavaScript Prototypes

sporto
August 11, 2013

Understanding JavaScript Prototypes

sporto

August 11, 2013
Tweet

More Decks by sporto

Other Decks in Programming

Transcript

  1. Understanding JS
    prototypes
    Sebastian Porto

    View Slide

  2. + Prototypes
    !
    + Object.create
    !
    + Constructor functions
    !
    + ES6

    View Slide

  3. The wrong way to learn
    function Liquid() {
    }
    Liquid.prototype.fluid = true;
    !
    function Beer() {
    Liquid.call(this);
    }
    !
    Beer.prototype =
    Object.create(Liquid.prototype);
    Beer.prototype.alcohol = 5.1;
    !
    var beer = new Beer();

    View Slide

  4. __proto__

    View Slide


  5. var liquid = {}

    var beer = {}

    beer.__proto__ = liquid
    A simple chain

    View Slide

  6. A simple chain
    liquid
    beer
    __proto__
    liquid is the
    prototype of beer

    View Slide

  7. Property look-ups

    var liquid = {

    fluid: true

    }

    var beer = {}

    beer.__proto__ = liquid

    beer.fluid //-> true

    View Slide

  8. A simple chain
    liquid
    beer
    __proto__
    fluid
    fluid? fluid?

    View Slide

  9. A longer chain
    liquid
    coopers
    fluid
    fluid?
    beer drink

    View Slide

  10. Long chain example

    var liquid = { fluid: true }

    var drink = {}

    drink.__proto__ = liquid

    var beer = {}

    beer.__proto__ = drink

    var coopers = {}

    coopers.__proto__ = beer

    coopers.fluid; //-> true

    View Slide

  11. Many object can have
    same prototype
    liquid
    beer
    __proto__
    cider
    __proto__

    View Slide

  12. Prototype can be shared

    var liquid = { fluid: true }

    var beer = {}

    beer.__proto__ = liquid

    var cider = {}

    cider.__proto__ = liquid

    beer.fluid; //-> true

    cider.fluid; //-> true

    View Slide

  13. Prototypes are not copies

    var beer = { tasty: true };

    var coopers = {};

    coopers.__proto__ = beer;

    coopers.tasty; //-> true

    beer.tasty = false;

    cooper.tasty; //-> false

    View Slide

  14. beer
    coopers
    ethanol
    Prototypes are dynamic
    .__proto__

    View Slide

  15. Prototypes are dynamic

    var beer = { alcohol: 6 }

    var ethanol = { alcohol: 100 }

    var coopers = {}

    coopers.__proto__ = beer

    coopers.alcohol //-> 6

    coopers.__proto__ = ethanol

    coopers.alcohol //-> 100

    View Slide

  16. Writing creates properties

    var beer = { alcohol: 6 }

    var coopers = {}

    coopers.__proto__ = beer

    coopers.alcohol = 4

    beer.alcohol //-> still 6

    View Slide

  17. Creates ‘own’ property
    beer
    coopers
    alcohol = 6
    .alcohol = 4
    alcohol = 4
    “own” property

    View Slide

  18. beer
    coopers
    alcohol = 6
    alcohol = 4
    creatures
    Same property can be in
    several places

    View Slide

  19. Arrays

    var beer = { 

    ingredients: [‘wheat’, ‘yeast’] 

    }

    var coopers = {}

    coopers.__proto__ = beer

    coopers.ingredients.push(‘oats’)

    beer.ingredients

    //->[‘wheat’, ‘yeast’, ‘oats’];

    View Slide

  20. Direct modification
    beer
    coopers
    ingredients
    .ingredients.push(‘oats’)

    View Slide

  21. coopers.ingredients.push(‘oats’);
    !
    creatures.ingredients; //->
    [‘wheat’, ‘yeast’, ‘oats’];
    Arrays are modified directly in
    the prototype
    beer
    coopers
    creatures
    ingredients

    ['wheat', 'yeast']

    __proto__
    __proto__

    View Slide

  22. Objects are the same

    var beer = { 

    ingredients: {wheat: 10, yeast: 20} 

    }

    var coopers = {}

    coopers.__proto__ = beer

    coopers.ingredients.wheat = 30

    beer.ingredients.wheat

    //-> 30

    View Slide

  23. __proto__ == great for
    learning
    !
    Not for use

    View Slide

  24. Object.create

    View Slide

  25. Object.create

    var beer = { 

    tasty: true

    }

    var coopers = Object.create(beer)

    coopers.tasty //-> true

    View Slide

  26. Object.create
    var coopers = Object.create(beer);
    !
    Just like:
    !
    var coopers = {};
    coopers.__proto__ = beer;

    View Slide

  27. Object.create
    is just setting __proto__
    !
    so same rules apply
    - not copies
    - dynamic

    View Slide

  28. getPrototypeOf
    var beer = {
    tasty: true
    };
    !
    var coopers = Object.create(beer);
    !
    !
    Object.getPrototypeOf(coopers)
    //-> beer object

    View Slide

  29. isPrototypeOf
    var beer = {
    tasty: true
    };
    !
    var coopers = Object.create(beer);
    !
    !
    beer.isPrototypeOf(coopers);
    //-> true

    View Slide

  30. ES6 setPrototypeOf
    var beer = {
    tasty: true
    };
    !
    var coopers = {};
    !
    !
    Object.setPrototypeOf(coopers, beer);

    View Slide

  31. Constructor Functions

    View Slide

  32. Functions as constructors
    function Beer(){
    !
    }
    !
    var beer = new Beer();
    Uppercase by
    convention

    View Slide

  33. function Beer(){
    !
    !
    !
    !
    !
    }
    !
    var beer = new Beer();
    Implicit this
    !
    var this = {}
    this.__proto__ = Beer.prototype
    (yield to your code)
    return this

    View Slide

  34. Implicit this
    function Beer(){
    var this = {};
    this.__proto__ = Beer.prototype;
    this.tasty = true;
    return this;
    }
    !
    var beer = new Beer();
    !
    beer.tasty; // true

    View Slide

  35. function Beer(){
    this.tasty = true;
    }
    !
    var beer = new Beer();
    !
    beer.tasty; //-> true
    Implicit this

    View Slide

  36. Don’t forget new
    function Beer(){
    this.kind = ‘beer’;
    }
    !
    var beer = Beer();
    this will the
    global object

    View Slide

  37. function Beer(){
    !
    this.__proto__ = Beer.prototype;
    !
    }
    function.prototype

    View Slide

  38. function.prototype
    function Beer(){
    !
    }
    !
    Beer.prototype
    Every function has
    this special property

    View Slide

  39. But this is not the prototype
    Beer.prototype !== Beer.__proto__
    Call this ‘function
    prototype’

    View Slide

  40. function.prototype
    function Beer(){
    !
    }
    !
    var beer = new Beer();
    beer.__proto__ ????
    What is the
    __proto__ of beer?

    View Slide

  41. It is assigned as the
    prototype of the instance
    function Beer(){
    var this = {};
    this.__proto__ = Beer.prototype;
    this.tasty = true;
    return this;
    }
    It is assigned as the
    prototype of the new
    created object

    View Slide

  42. Function
    instance
    new
    __proto__
    Function
    prototype
    .prototype

    View Slide


  43. function Beer(){}

    Beer.prototype.tasty = true

    var coopers = new Beer()

    coopers.__proto__ == Beer.prototype

    //-> true

    coopers.tasty //-> true
    It is the prototype assigned
    to the instance

    View Slide

  44. function Beer(){
    }
    !
    Beer.prototype.brew = function () {}
    !
    var coopers = new Beer();
    var creatures = new Beer();
    !
    coopers.brew();
    creatures.brew();
    !
    Useful for performance

    View Slide


  45. function Beer(){...}

    Beer.prototype.ingredients =
    ['honey']

    var coopers = new Beer()

    var vb = new Beer()

    coopers.ingredients.push('oats')

    vb.ingredients //-> ['honey',
    'oats']
    Again, same rules!

    View Slide


  46. function Beer(){

    this.ingredients = [‘yeast’]

    }

    var coopers = new Beer()

    var creatures = new Beer()

    coopers.ingredients.push(‘wheat’)

    creatures.ingredients

    //-> [‘yeast’]
    Isolation

    View Slide

  47. function Beer(){
    !
    }
    !
    var coopers = new Beer();
    !
    coopers instanceof Beer;
    //-> true
    !
    instanceof

    View Slide

  48. coopers instanceof Beer;
    !
    !
    Checks that
    !
    coopers.__proto__ == Beer.prototype
    !
    instanceof

    View Slide

  49. var Beer = function () {
    !
    };
    !
    Beer.findAll = function () {
    ...
    }
    !
    Beer.findAll();
    "Class methods"

    View Slide

  50. ES6

    View Slide

  51. class Beer {
    constructor(a) {
    this.alcohol = a;
    }
    !
    drink() {
    ...
    }
    }
    ES6 Classes

    View Slide

  52. ES6 Classes
    function Beer(a){
    this.alcohol = a;
    }
    !
    Beer.prototype.drink =
    function () {
    ...
    }
    !
    var beer = new Beer(5)
    class Beer {
    constructor(a) {
    this.alcohol = a;
    }
    !
    drink() {
    ...
    }
    }
    !
    var beer = new Beer(5)

    View Slide

  53. Questions? Thanks

    View Slide