source

다중 컨스트럭터용 자바스크립트 패턴

ittop 2023. 9. 19. 21:25
반응형

다중 컨스트럭터용 자바스크립트 패턴

예를 들어 다른 시공자가 필요합니다.일반적인 패턴은 무엇입니까?

자바스크립트에는 메서드나 생성자를 포함한 기능 과부하가 없습니다.

전달하는 매개변수의 수와 유형에 따라 함수가 다르게 동작하려면 수동으로 함수를 스니핑해야 합니다.자바스크립트는 선언된 인수 수보다 많거나 적은 함수를 기꺼이 호출할 것입니다.

function foo(a, b) {
    if (b===undefined) // parameter was omitted in call
        b= 'some default value';

    if (typeof(a)==='string')
        this._constructInSomeWay(a, b);
    else if (a instanceof MyType)
        this._constructInSomeOtherWay(a, b);
}

에도 수 .arguments추가적인 인수 전달을 위해 배열된 것과 같습니다.

좀 더 복잡한 인수가 필요한 경우에는 개체 조회에 일부 또는 전부를 넣는 것이 좋습니다.

function bar(argmap) {
    if ('optionalparam' in argmap)
        this._constructInSomeWay(argmap.param, argmap.optionalparam);
    ...
}

bar({param: 1, optionalparam: 2})

Python은 함수 오버로드보다 더 실용적이고 우아한 방식으로 대부분의 사용 사례를 다루는 데 기본 및 명명된 인수를 어떻게 사용할 수 있는지 보여줍니다.자바스크립트, 별로.

해당 클래스의 인스턴스를 반환하는 정적 메서드와 함께 클래스를 사용할 수 있습니다.

    class MyClass {
        constructor(a,b,c,d){
            this.a = a
            this.b = b
            this.c = c
            this.d = d
        }
        static BAndCInstance(b,c){
            return new MyClass(null,b,c)
        }
        static BAndDInstance(b,d){
            return new MyClass(null,b, null,d)
        }
    }

    //new Instance just with a and other is nul this can
    //use for other params that are first in constructor
    const myclass=new MyClass(a)

    //an Instance that has b and c params
    const instanceWithBAndC = MyClass.BAndCInstance(b,c)

    //another example for b and d
    const instanceWithBAndD = MyClass.BAndDInstance(b,d)

이 패턴으로 멀티 컨스트럭터를 만들 수 있습니다.

이걸 어떻게 찾죠?

function Foobar(foobar) {
    this.foobar = foobar;
}

Foobar.prototype = {
    foobar: null
};

Foobar.fromComponents = function(foo, bar) {
    var foobar = foo + bar;
    return new Foobar(foobar);
};

//usage: the following two lines give the same result
var x = Foobar.fromComponents('Abc', 'Cde');
var y = new Foobar('AbcDef')

보빈스의 답변처럼 손으로 하고 싶지 않아서 jQuery의 플러그인 옵션 패턴을 완전히 뜯어냈습니다.

시공자는 다음과 같습니다.

//default constructor for Preset 'class'
function Preset(params) {
    var properties = $.extend({
        //these are the defaults
        id: null,
        name: null,
        inItems: [],
        outItems: [],
    }, params);

    console.log('Preset instantiated');
    this.id = properties.id;
    this.name = properties.name;
    this.inItems = properties.inItems;
    this.outItems = properties.outItems;
}

인스턴스화 방법은 다음과 같습니다.

presetNoParams = new Preset(); 
presetEmptyParams = new Preset({});
presetSomeParams = new Preset({id: 666, inItems:['item_1', 'item_2']});
presetAllParams = new Preset({id: 666, name: 'SOpreset', inItems: ['item_1', 'item_2'], outItems: ['item_3', 'item_4']});

그리고 이것이 만든 것은 다음과 같습니다.

presetNoParams
Preset {id: null, name: null, inItems: Array[0], outItems: Array[0]}

presetEmptyParams
Preset {id: null, name: null, inItems: Array[0], outItems: Array[0]}

presetSomeParams
Preset {id: 666, name: null, inItems: Array[2], outItems: Array[0]}

presetAllParams
Preset {id: 666, name: "SOpreset", inItems: Array[2], outItems: Array[2]}

이 질문은 구글에서 먼저 회신되지만 답변은 이제 구식이기 때문에 답변합니다.

ES6에서 Destructuring 객체를 Constructor 파라미터로 사용할 수 있습니다.

패턴은 이렇습니다.

생성자를 여러 개 가질 수는 없지만 파괴 및 기본값을 사용하여 원하는 작업을 수행할 수 있습니다.

export class myClass {

  constructor({ myArray = [1, 2, 3], myString = 'Hello World' }) {

    // ..
  }
}

그리고 '모수 없는' 생성자를 지원하려면 이렇게 할 수 있습니다.

export class myClass {

      constructor({myArray = [1, 2, 3], myString = 'Hello World'} = {}) {

        // ..
      }
}

더 당신은 의 인 를 로 묶을 수 .new당신을 불러들입니다.init방법.

function Foo () {
    this.bar = 'baz';
}

Foo.prototype.init_1 = function (bar) {
    this.bar = bar;
    return this;
};

Foo.prototype.init_2 = function (baz) {
    this.bar = 'something to do with '+baz;
    return this;
};

var a = new Foo().init_1('constructor 1');
var b = new Foo().init_2('constructor 2');
export default class Order {

    static fromCart(cart) {
        var newOrder = new Order();
        newOrder.items = cart.items;
        newOrder.sum = cart.sum;

        return newOrder;
    }

    static fromOrder(id, order) {
        var newOrder = new Order();
        newOrder.id = id;
        newOrder.items = order.items;
        newOrder.sum = order.sum;

        return newOrder;
    }
}

용도:

  var newOrder = Order.fromCart(cart)
  var newOrder = Order.fromOrder(id, oldOrder)

모수에 대한 기본값이 여러 생성자에 충분할 수도 있습니다.그리고 그것으로 충분하지 않을 때, 저는 대부분의 컨스트럭터 기능을 나중에 호출되는 init(다른-params) 함수로 감싸려고 노력합니다.또한 공장 개념을 사용하여 원하는 다른 개체를 효과적으로 만들 수 있는 개체를 만드는 것도 고려해 볼 수 있습니다.

http://en.wikipedia.org/w/index.php?title=Factory_method_pattern&oldid=363482142#Javascript

일반적으로 더 많은 매개 변수를 전달할 수 있으며 개체를 인스턴스화할 때 일부 값이 누락될 수 있으며 기본값이 정의되지 않은 상태가 됩니다. 정의되지 않은 상태로 관리하지 않으려면 다중 생성기를 쉽게 구축할 수 있는 방법은 다음과 같습니다.

class Car {
  constructor(brand, year = '', owner = '') { // assign default value
    this.carname = brand;
    this.year = year;
    this.owner = owner;
  }
  presentCarName() {
    return 'I have a ' + this.carname;
  }
  presentCarNameAndYear() {
    return 'I have a ' + this.carname + ' year: ' + this.year;
  }
}

let myCar = new Car("Ford");
console.log(myCar.presentCarName());
myCar = new Car("Ford", 1996);
console.log(myCar.presentCarNameAndYear());

이것은 나의 해결책입니다, 간단히 사용하세요.methods그리고.return this예.

class Person{
  name;
  age;
  gender;
  cash;

  constructor() {

  }

  init(name, age, gender, cash){
    this.name = name;
    this.age = age;
    this.gender = gender;
    this.cash = cash;

    return this;
  }

  initCyborg(name, age){
    this.name = name + ' Reborn';
    this.age = age + 5;
    this.cash = 999999;
    this.gender = "cyborg";

    return this;
  }

  initMale(name, age, salariesOf2000Received){
    this.name = name;
    this.age = age;
    this.gender = "male";
    this.cash = 2000 * salariesOf2000Received;

    return this;
  }
}

그리고나서

var john = new Person().init("John Doe", 30, "male", 2000);
var cyborg = new Person().initCyborg("Terminator-6000", 3000);
var rickAstley = new Person().initMale("Rick Astley", 56, 2);

console.log(john);
console.log(cyborg);
console.log(rickAstley);

두 가지 답이 있다고 생각합니다.IIFE 기능이 있는 '순수한' 자바스크립트를 사용하여 보조 건축 기능을 숨기는 것.그리고 다른 하나는 노드를 사용합니다.보조 시공 기능도 숨기는 JS 모듈.

노드가 있는 예제만 보여드리겠습니다.JS 모듈.

클래스 벡터2d.js:



/*

    Implement a class of type Vetor2d with three types of constructors.

*/

// If a constructor function is successfully executed,
// must have its value changed to 'true'.let global_wasExecuted = false;  
global_wasExecuted = false;   

//Tests whether number_value is a numeric type
function isNumber(number_value) {
    
    let hasError = !(typeof number_value === 'number') || !isFinite(number_value);

    if (hasError === false){
        hasError = isNaN(number_value);
    }

    return !hasError;
}

// Object with 'x' and 'y' properties associated with its values.
function vector(x,y){
    return {'x': x, 'y': y};
}

//constructor in case x and y are 'undefined'
function new_vector_zero(x, y){

    if (x === undefined && y === undefined){
        global_wasExecuted = true;
        return new vector(0,0);
    }
}

//constructor in case x and y are numbers
function new_vector_numbers(x, y){

    let x_isNumber = isNumber(x);
    let y_isNumber = isNumber(y);

    if (x_isNumber && y_isNumber){
        global_wasExecuted = true;
        return new vector(x,y);
    }
}

//constructor in case x is an object and y is any
//thing (he is ignored!)
function new_vector_object(x, y){

    let x_ehObject = typeof x === 'object';
    //ignore y type

    if (x_ehObject){

        //assigns the object only for clarity of code
        let x_object = x;

        //tests whether x_object has the properties 'x' and 'y'
        if ('x' in x_object && 'y' in x_object){

            global_wasExecuted = true;

            /*
            we only know that x_object has the properties 'x' and 'y',
            now we will test if the property values ​​are valid,
            calling the class constructor again.            
            */
            return new Vector2d(x_object.x, x_object.y);
        }

    }
}


//Function that returns an array of constructor functions
function constructors(){
    let c = [];
    c.push(new_vector_zero);
    c.push(new_vector_numbers);
    c.push(new_vector_object);

    /*
        Your imagination is the limit!
        Create as many construction functions as you want.    
    */

    return c;
}

class Vector2d {

    constructor(x, y){

        //returns an array of constructor functions
        let my_constructors = constructors(); 

        global_wasExecuted = false;

        //variable for the return of the 'vector' function
        let new_vector;     

        //traverses the array executing its corresponding constructor function
        for (let index = 0; index < my_constructors.length; index++) {

            //execute a function added by the 'constructors' function
            new_vector = my_constructors[index](x,y);
            
            if (global_wasExecuted) {
            
                this.x = new_vector.x;
                this.y = new_vector.y;

                break; 
            };
        };
    }

    toString(){
        return `(x: ${this.x}, y: ${this.y})`;
    }

}

//Only the 'Vector2d' class will be visible externally
module.exports = Vector2d;  

useVector2d.js 파일은 Vector2d.js 모듈을 사용합니다.

const Vector = require('./Vector2d');

let v1 = new Vector({x: 2, y: 3});
console.log(`v1 = ${v1.toString()}`);

let v2 = new Vector(1, 5.2);
console.log(`v2 = ${v2.toString()}`);

let v3 = new Vector();
console.log(`v3 = ${v3.toString()}`);

터미널 출력:

v1 = (x: 2, y: 3)
v2 = (x: 1, y: 5.2)
v3 = (x: 0, y: 0)

이를 통해 유지보수 및 테스트가 어려운 더러운 코드(많은 if 및 스위치가 코드 전체에 퍼지는 것)를 방지할 수 있습니다.각 건물 함수는 테스트할 조건을 알고 있습니다.빌딩 기능을 늘리거나 줄이는 것은 이제 간단합니다.

이것은 자바스크립트와 CSS3 - Exam Ref로 HTML5의 프로그래밍에서 여러 컨스트럭터에 주어진 예입니다.

function Book() {
    //just creates an empty book.
}


function Book(title, length, author) {
    this.title = title;
    this.Length = length;
    this.author = author;
}

Book.prototype = {
    ISBN: "",
    Length: -1,
    genre: "",
    covering: "",
    author: "",
    currentPage: 0,
    title: "",

    flipTo: function FlipToAPage(pNum) {
        this.currentPage = pNum;
    },

    turnPageForward: function turnForward() {
        this.flipTo(this.currentPage++);
    },

    turnPageBackward: function turnBackward() {
        this.flipTo(this.currentPage--);
    }
};

var books = new Array(new Book(), new Book("First Edition", 350, "Random"));

12년만에 Js를 사용할 수 있게 되었습니다.class&static이와 같은 방법

class Human {
    static Person1(){
        let o = new Human();
        o.name = "Person1";
        return o;
    }

    static Person2(){
        let o = new Human();
        o.name = "Person2";
        return o;
    }

    sayhello(){
        alert(`Hello ${this.name}`);
    }
}

그래서 위의 코드에서 나는 a를 정의했습니다.class둘이서static그리고 하나instance method. 그래서 이제.static인스턴스 개체 없이 호출할 수 있으므로 두 사람을 생성할 수 있습니다.


var p1 = Human.Person1();
var p2 = Human.Person2();

그리고 인스턴스 메소드를 호출할 수 있습니다.

p1.sayhello();
p2.sayhello();

돌아올 것입니다.

Hello Person1
Hello Person2

콘솔로 테스트까지 해봤습니다.

enter image description here

언급URL : https://stackoverflow.com/questions/3220721/javascript-pattern-for-multiple-constructors

반응형