2014-12-02 17 views
21

Gần đây tôi đã xem một trong những cuộc hội đàm của Douglas Crockford (những bài nói chuyện của ông mê hoặc tôi, nhưng luôn khiến tôi bối rối). Ông đưa ra một ví dụ về một nhà xây dựng, nhưng tôi không hoàn toàn hiểu làm thế nào tôi sẽ sử dụng nó trong thực tế:Mô hình xây dựng của Douglas Crockford

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

    that.method = method; 
    return that;  
} 

Có lẽ một số người ta có thể cho tôi một ví dụ làm việc đơn giản dựa trên mô hình này?

Trả lời

14

Đây là ví dụ về cách sử dụng một hàm tạo khác bên trong một hàm nhà máy để trả về một đối tượng. Trong trường hợp này, other_constructor là hàm hàm tạo, tạo đối tượng thuộc loại other_constructor (lý tưởng trong thực tế điều này sẽ được viết hoa). Đối tượng đó được lưu trữ trong that. Trong chức năng nhà máy này, method là một hàm được xác định được thêm vào that để mở rộng chức năng của đối tượng theo một cách nào đó.

Sự khác biệt giữa chức năng xây dựng và nhà máy là một chức năng nhà máy chỉ là một chức năng bình thường trả về một đối tượng, trong khi một hàm constructor có this trỏ đến các đối tượng mới, và thường phải được gọi với từ khóa new trước nó .

Một chức năng xây dựng điển hình:

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

Và nó sử dụng:

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 

Một chức năng nhà máy tiêu biểu:

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 
} 

Và sử dụng của nó:

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 

Một lời giải thích tốt về sự khác biệt giữa họ và các trường hợp sử dụng khác nhau của mỗi là at Eric Elliot's blog

+0

Cảm ơn, cái này có ý nghĩa với tôi. Tương tự như một hàm tạo lớp trong các ngôn ngữ hướng đối tượng –

14

Đây là Douglas Crockford nguồn gốc như nó xuất hiện trong slide của mình:

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

Ví dụ sau đây là một nhiều phiên bản bê tông của mẫu tạo đối tượng Douglas Crockford năm 2014.

Douglas Crockford sử dụng nhiều tính năng ECMAScript 6 như destructuring etc. !!

Bắt đầu mã trong Node.js với các tùy chọn sau đây (cho phép 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(); 
})(); 

Theo talk Douglas Crockford, ông tránh được việc sử dụng:

  • mới
  • Object.create
  • điều này !!!

Xem bản gốc Crockford video: https://www.youtube.com/watch?v=PSGEjv3Tqo0

Một lời giải thích tốt cho Crockford Douglas Object Tạo Pattern 2014 là blog này: https://weblogs.asp.net/bleroy/crockford%E2%80%99s-2014-object-creation-pattern

+0

đã bỏ phiếu xuống vì các hàm tạo nên luôn được viết hoa trong JS. –

+5

Ổn định ở đó. Nó đã được thực hiện để phù hợp với Crockford của nói rằng nó không cần một tiền tố mới. – jiku

+1

@Rob Raisch Nếu tôi nhớ chính xác, anh ấy đã đề cập đến, để không nhầm lẫn với các nhà thầu, anh ấy đã chọn không sử dụng mũ. – LiweiZ

1

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

Đọc thêm về Mẫu Constructor http://www.sga.su/constructor-pattern-javascript/

2

ví dụ Vanilla JavaScript của mẫu nhà xây dựng mới của Douglas Crockford với lời giải thích:

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

Các vấn đề liên quan