道格拉斯克罗克福德的构造模式

时间:2014-12-02 19:30:42

标签: javascript oop constructor

最近我看了道格拉斯·克罗克福德的一次演讲(他的演讲让我着迷,但总是让我感到困惑)。他给出了一个构造函数的例子,但我不太清楚如何在实践中使用它:

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

  that.method = method;
  return that;      
}

也许有人可以根据这种模式给我一个简单的工作示例?

4 个答案:

答案 0 :(得分:15)

这是在工厂函数中使用另一个构造函数来返回对象的示例。在这种情况下,other_constructor是构造函数,它创建一个other_constructor类型的对象(理想情况下,实际上这将是大写的)。该对象存储在that中。在此工厂函数中,method是一个已定义的函数,它被添加到that以便以某种方式扩展对象的功能。

构造函数和工厂函数之间的区别在于工厂函数只是返回对象的普通函数,而构造函数有this指向新对象,并且通常必须使用{调用{它前面的{1}}关键字。

典型的构造函数:

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

及其用法:

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
}

对它们与每种用例的不同用例之间的区别的一个很好的解释是at Eric Elliot's blog

答案 1 :(得分:15)

这是道格拉斯·克罗克福德的原始资料,因为它出现在他的幻灯片中:

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

以下示例是Douglas Crockford的对象创建模式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();
})();

根据Douglas Crockford的讲话,他避免使用:

  • 的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

答案 2 :(得分:2)

Vanilla 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's 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);

答案 3 :(得分:0)



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())




阅读有关构造函数模式http://www.sga.su/constructor-pattern-javascript/

的更多信息