Javascript




Object creation patterns




Leonardo garcia crespo

@leogcrespo
gh/leoasis

Patrones


  1. Object literal
  2. Function that returns object
  3. Constructor function
  4. Constructor function with prototype
  5. Object.create

Object Literal


//Example
var point = {x: 10, y: 20};

// With functions
var configuration = {
  allowResize: true,
  resize: function(width, height) {
    if (this.allowResize) {
      this.width = width;
      this.height = height;
    }
  }
};

Pros

  • Super simple


Cons

  • No reuso
  • Explícita creación


Mejor para

  • Objetos one-time
  • Singletons
  • Hashes

Function that returns an object

function createPoint(x, y) {
  return {x: x, y: y};
}
var createSegment = function(pointA, pointB) {
  function distance(axis) {
    return Math.abs(this.a[axis] - this.b[axis]);
  }

  return {
    a: pointA,
    b: pointB,
    getSize: function() {
      var x = distance.call(this, 'x');
      var y = distance.call(this, 'y');
      return Math.sqrt(x * x + y * y);
    }
  }
};
    
var pointA = createPoint(1, 1);
var pointB = createPoint(5, 3);

var segment = createSegment(pointA, pointB);
console.log(segment.getSize());

Pros

  • Un solo lugar
  • Métodos privados


Cons

  • Uso de memoria
  • Performance
  • Recordar retornar el objeto creado


Mejor para

  • Lo anterior con construcción compleja.

Constructor Function

function Car(model, wheels, maxSpeed) {
  this.model = model;
  this.wheels = wheels;
  this.maxSpeed = maxSpeed;
  this.velocity = 0;

  this.accelerate = function() {
    this.velocity += 10;
  },

  this.brake = function() {
    this.velocity -= 10;
  }
}
var car = new Car('mini', 4, 240);
console.log(car);

Pros

    • Un solo lugar
    • Métodos privados
    • Usa this como objeto a retornar


    Cons

      • Uso de memoria
      • Performance
      • Requiere 'new' (sino this es el global object)


      Mejor para

      • Idem anterior

      Constructor function + prototype

      function Car(model, wheels, maxSpeed) {
        this.model = model;
        this.wheels = wheels;
        this.maxSpeed = maxSpeed;
        this.velocity = 0;
      }
      
      // Assigning properties to prototype object
      Car.prototype.accelerate = function() {
        this.velocity += 10;
      };
      Car.prototype.brake = function() {
        this.velocity -= 10;
      };
      
      // Replacing prototype object with new one
      Car.prototype = {
        accelerate: function() {
          this.velocity += 10;
        },
        brake: function() {
          this.velocity -= 10;
        }
      };
      

      Pros

      • Performante (reusa lo definido en los prototipos)
      • Permite herencia de prototipos


      Cons

      • Requiere 'new'
      • Métodos e inicializacion separados
      • No métodos privados (convención "_")


      Mejor para

      • Herencia
      • Creación de muchos objetos de ese tipo

      interlude: prototype chain




      • Un prototipo es un objeto
      • Prototype del prototype del prototype...
      • Se hace method lookup en la cadena.
      • Function.prototype
      • Única forma estándar de asignar prototipos es con 'new'
      • Caso: Backbone prototype chain
        • Define una property especial "constructor" para inicializar.

      Object.create

      // Crockford's shim
      Object.create = function (o) {
          function F() {}
          F.prototype = o;
          return new F();
      };
      // Optimized version: Reuse function F
      Object.create = (function () {
        function F() {} // created only once
        return function (o) {
          F.prototype = o; // reused on each invocation
          return new F();
        };
      })();
      
      var proto = {
        sayHello: function() {
          return "My name is " + this.name + " and I salute you!";
        }
      };
      
      var someone = Object.create(proto);
      
      someone.name = "Lenny";
      
      console.log(someone.sayHello());

      Pros

      • No necesita 'new'
      • Más claro que se usan prototipos
      • Performance


      Cons

      • Difícil de inicializar el objeto
      • No disponible en IE (necesario shim)


      Mejor para

      • Creación de muchos objetos similares
      • Herencia
      • Objetos sin inicialización compleja

      to read

      1. Google: "Javascript object creation patterns"
      2. Javascript: The Good Parts
      3. http://javascript.crockford.com/
      4. http://leoasis.github.io
      5. Ver librerias qué estan haciendo
        1. Backbone
        2. jQuery
        3. Angular (ngResource)




      gracias!


      (preguntas?)

      @leogcrespo
      gh/leoasis
      http://leoasis.github.io
      @meetupjs_ar
      @amplifiedapp
      Made with Slides.com