Подтвердить что ты не робот

Конструкторский рисунок Дугласа Крокфорда

Недавно я смотрел один из переговоров Дугласа Крокфорда (его разговоры очаровывают меня, но всегда оставляют меня в замешательстве). Он привел пример конструктора, но я не совсем понимаю, как использовать его на практике:

function constructor(spec) {
  var that = other_constructor(spec),
    member,
    method = function () {
      //spec , member, method
    };

  that.method = method;
  return that;      
}

Может кто-нибудь может дать мне простой рабочий пример, основанный на этом шаблоне?

4b9b3361

Ответ 1

Это пример использования другого конструктора внутри функции factory для возврата объекта. В этом случае other_constructor - это функция конструктора, которая создает объект типа other_constructor (в идеале на практике это будет заглавное). Этот объект хранится в that. В этой функции factory method - это определенная функция, которая добавляется к that, чтобы каким-то образом расширить функциональность объекта.

Разница между конструкторами и функциями factory заключается в том, что функция factory - это просто нормальная функция, которая возвращает объект, тогда как функция-конструктор имеет this, указывающую на новый объект и обычно должна вызываться с ключевое слово new, предшествующее ему.

Типичная конструкторская функция:

function Dog(breed, height, name){
  this.breed = breed;
  this.animalType = "dog";
  this.height = height;
  this.name = name;
  // calling `return` isn't necessary here
}

И это использование:

var lab = new Dog("labrador", 100, "Sugar"); // `new` is necessary (usually)
console.log(lab.animalType); // prints out "dog"
console.log(lab.height); // prints out 100

Типичная функция factory:

function createDog(breed, height, name){
  var dog = {
    breed: breed,
    height: height,
    animalType: "dog",
    name: name
  };
  return dog; 
  // `return` is necessary here, because `this` refers to the 
  // outer scope `this`, not the new object
}

И его использование:

var lab = createDog("labrador", 100, "Sugar"); // notice no need for `new`
console.log(lab.animalType); // prints out "dog"
console.log(lab.height); // prints out 100

Хорошее объяснение различий между ними и различными вариантами использования каждого из них - в блоге Эрика Эллиота

Ответ 2

Это оригинальный источник Дугласа Крокфорда, который появляется в его слайдах:

function constructor(spec) {
  let {member} = spec,
      {other} = other_constructor(spec),
      method = function () {
        // member, other, method, spec
      };
  return Object.freeze({
    method,
    other
  });
}

Следующий пример - более конкретная версия шаблона создания объектов Дугласа Крокфорда 2014.

Дуглас Крокфорд активно использует ECMAScript 6, такие как деструктурирование и т.д.

Запустите код в node.js со следующими параметрами (включите ES6):

node --harmony --harmony_destructuring demo.js

demo.js

// Douglas Crockford 2014 Object Creation
(function() {
  'use strict';

  function adress(spec) {

    let {
      street, city
    } = spec,
    logAdress = function() {
      console.log('Adress:', street, city);
    };
    return Object.freeze({
      logAdress
    });
  };

  function person(spec) {

    let {
      preName,
      name
    } = spec, {
      logAdress
    } = adress(spec),
      logPerson = function() {
        // member, other, method, spec
        console.log('Name: ', preName, name);
        logAdress();
      };
    return Object.freeze({
      logPerson,
      logAdress
    });
  };


  let myPerson = person({
    preName: 'Mike',
    name: 'Douglas',
    street: 'Newstreet',
    city: 'London'
  });

  myPerson.logPerson();
})();

По словам Дугласа Крокфорда, он избегает использования:

  • новый
  • Object.create
  • это!!!

Посмотрите оригинальное видео Crockford: https://www.youtube.com/watch?v=PSGEjv3Tqo0

Хорошим объяснением для проекта Crockford Douglas Object Creation Pattern 2014 является этот блог: https://weblogs.asp.net/bleroy/crockford%E2%80%99s-2014-object-creation-pattern

Ответ 3

Ванильные JavaScript-примеры нового шаблона конструктора Дугласа Крокфорда с пояснениями:

console.clear();
var fauna = (function (){
  privitizeNewVariables=function (specs) {
    if (!specs.is_private) {
      var members = Object.assign({}, specs);
      members.is_private = true;
      return members;
    }
    return specs;
  },
  newAnimal=function (specs) {
    var members = privitizeNewVariables(specs);
    members.inheritance_type_list = ['Animal'];
    whenInDanger = function () {
      try{
        console.log('When in danger ', members.common_name);
        members.movesBy();
      }catch (e){
        console.log('Error - whenInDanger() has no movesBy()');
      }
    };
    var isA = function(object_type){
      if (members.inheritance_type_list.indexOf(object_type)>-1) {
        console.log(members.common_name, 'is a', object_type);
      }else{
        console.log(members.common_name, 'is not a', object_type);
      }
    }
    return Object.freeze({
      whenInDanger: whenInDanger,
      isA: isA
    });
  },
  newSnake=function (specs){
    var members = privitizeNewVariables(specs);
    members.movesBy = function () {
      console.log('Moves By: slithering');
    };
    colorScheme = function () {
      console.log('Color scheme :', members.color_scheme);
    };
    aPrivateFunction = function (){
      console.log('I only exist inside a Snake object');
    };
    var an_animal = newAnimal(members);
    members.inheritance_type_list.unshift('Snake');
    return Object.freeze({
      whenInDanger: an_animal.whenInDanger,
      isA: an_animal.isA,
      movesBy: members.movesBy,
      colorScheme: colorScheme
    });
  };
  return {
    newAnimal:newAnimal,
    newSnake: newSnake
  }
})();
var animal_specs = {common_name: 'Alf the animal'};
var an_animal = fauna.newAnimal(animal_specs);
animal_specs.common_name = "does not change Alf common_name";
an_animal.whenInDanger();
console.log(an_animal);
console.log('-');
var snake_specs = {common_name: 'Snorky the snake',
 color_scheme:'yellow'};
var a_snake = fauna.newSnake(snake_specs);
a_snake.whenInDanger();
console.log('-');
a_snake.colorScheme();
a_snake.isA('Animal');
a_snake.isA('Snake');
a_snake.isA('Bear');
console.log('-');
console.log(fauna);

Ответ 4

function Car(model, year, miles, price) {

  this.model = model;
  this.year = year;
  this.miles = miles;
  this.price = price;

  this.toString = function() {
    return this.model + " has done " + this.miles + " miles and cost $" + this.price;
  };
}

// We can create new instances of the car
var civic = new Car("Toyota Prius", 2015, 1500, 12000);
var mondeo = new Car("Ford Focus", 2010, 5000, 3000);

// these objects
console.log(civic.toString());
console.log(mondeo.toString())