programing

JavaScript에서 커스텀 오브젝트를 "적절하게" 작성하려면 어떻게 해야 합니까?

projobs 2022. 10. 11. 21:56
반응형

JavaScript에서 커스텀 오브젝트를 "적절하게" 작성하려면 어떻게 해야 합니까?

속성 및 메서드를 가진 JavaScript 객체를 만드는 가장 좋은 방법이 무엇인지 궁금합니다.

를 본 적이 있어요.var self = this 후, 「」를 사용합니다.self.이치노

,그러면요,..prototype다른 사용자가 인라인으로 수행하는 동안 속성을 추가합니다.

속성 및 메서드를 포함한 JavaScript 객체의 적절한 예를 들어줄 수 있습니까?

JavaScript에서 클래스 및 인스턴스를 구현하는 모델은 프로토타이핑 방식과 폐쇄 방식 두 가지가 있습니다.둘 다 장점과 단점을 가지고 있으며, 많은 확장된 변형들이 있습니다.많은 프로그래머와 라이브러리는 언어의 더 추악한 부분을 페이퍼링하는 다양한 접근법과 클래스 처리 유틸리티 기능을 가지고 있습니다.

그 결과, 혼재 기업에서는 메타클래스의 혼란이 발생하게 되어, 모든 것이 조금씩 다릅니다.게다가 대부분의 JavaScript 튜토리얼 자료는 형편없고, 모든 베이스를 커버하기 위한 타협을 하고 있기 때문에 매우 혼란스러울 수 있습니다.(아마도 작성자도 혼란스러울 것입니다.)JavaScript의 오브젝트 모델은 대부분의 프로그래밍 언어와는 매우 다르며, 많은 곳에서 제대로 설계되지 않았습니다.)

시제품부터 시작합시다.이것은 가능한 한 JavaScript 네이티브입니다.최소한의 오버헤드코드가 존재하며 instanceof는 이런 종류의 오브젝트 인스턴스에서 동작합니다.

function Shape(x, y) {
    this.x= x;
    this.y= y;
}

해서 할 수 .new Shape에 써서.prototype다음과 같이 합니다.

Shape.prototype.toString= function() {
    return 'Shape at '+this.x+', '+this.y;
};

서브클래스로 하면 JavaScript가 서브클래싱을 하는 것을 가능한 한 많이 호출할 수 있습니다.는 그 한 마법을 을 할 수 있다.prototype★★★★

function Circle(x, y, r) {
    Shape.call(this, x, y); // invoke the base class's constructor function to take co-ords
    this.r= r;
}
Circle.prototype= new Shape();

메서드를 추가하기 전에 다음을 수행합니다.

Circle.prototype.toString= function() {
    return 'Circular '+Shape.prototype.toString.call(this)+' with radius '+this.r;
}

이 예는 기능하며 많은 튜토리얼에서 이와 같은 코드를 볼 수 있습니다.new Shape()기기흉흉흉흉다다 실제 쉐이프가 생성되지 않더라도 기본 클래스를 인스턴스화합니다.엉성하기 이할 수 이 경우 JavaScript는 인수를 0으로 할 수 있습니다.인수가 전혀 전달되지 않는 경우가 있습니다.x ★★★★★★★★★★★★★★★★★」y되세요undefined되어 있습니다.this.x ★★★★★★★★★★★★★★★★★」this.y컨스트럭터 함수가 더 복잡한 작업을 하고 있다면, 그것은 완전히 무너질 것입니다.

따라서 기본 클래스의 컨스트럭터 함수를 호출하지 않고 클래스 수준에서 원하는 메서드 및 다른 멤버를 포함하는 프로토타입 개체를 만드는 방법을 찾아야 합니다.그러기 위해서는 도우미 코드 작성을 시작해야 합니다.이것은 내가 알고 있는 가장 간단한 접근법입니다.

function subclassOf(base) {
    _subclassOf.prototype= base.prototype;
    return new _subclassOf();
}
function _subclassOf() {};

이렇게 하면 기본 클래스의 프로토타입 멤버를 아무것도 하지 않는 새 생성자 함수로 이동한 다음 해당 생성자를 사용합니다.이제 간단하게 쓸 수 있습니다.

function Circle(x, y, r) {
    Shape.call(this, x, y);
    this.r= r;
}
Circle.prototype= subclassOf(Shape);

new Shape() 하다. 이제 만들 수 이 많이 .이제 클래스 구축에 사용할 수 있는 기본 요소 세트가 있습니다.

이 모델에서 고려할 수 있는 몇 가지 개선사항과 확장이 있습니다.예를 들어 구문-설탕 버전은 다음과 같습니다.

Function.prototype.subclass= function(base) {
    var c= Function.prototype.subclass.nonconstructor;
    c.prototype= base.prototype;
    this.prototype= new c();
};
Function.prototype.subclass.nonconstructor= function() {};

...

function Circle(x, y, r) {
    Shape.call(this, x, y);
    this.r= r;
}
Circle.subclass(Shape);

두 버전 모두 컨스트럭터 함수를 여러 언어로 상속할 수 없다는 단점이 있습니다.따라서 서브클래스는 구축 프로세스에 아무것도 추가하지 않더라도 베이스가 원하는 인수를 사용하여 베이스 컨스트럭터를 호출해야 합니다.은 약간 할 수 요, 하다, 하다, 하다, 하다를 사용해서.apply그러나, 다음과 같이 기입할 필요가 있습니다.

function Point() {
    Shape.apply(this, arguments);
}
Point.subclass(Shape);

따라서 일반적인 확장은 초기화를 제작자 자체보다는 자체 기능으로 세분화하는 것입니다.그러면 이 함수는 기본에서 상속할 수 있습니다.

function Shape() { this._init.apply(this, arguments); }
Shape.prototype._init= function(x, y) {
    this.x= x;
    this.y= y;
};

function Point() { this._init.apply(this, arguments); }
Point.subclass(Shape);
// no need to write new initialiser for Point!

각 클래스에 동일한 컨스트럭터 함수 보일러 플레이트가 있습니다., '도움말'이 아니라 '도움말'이 '을 계속 하지 않아도 될 로 이 수 것 .Function.prototype.subclass 기본 합니다.

Function.prototype.makeSubclass= function() {
    function Class() {
        if ('_init' in this)
            this._init.apply(this, arguments);
    }
    Function.prototype.makeSubclass.nonconstructor.prototype= this.prototype;
    Class.prototype= new Function.prototype.makeSubclass.nonconstructor();
    return Class;
};
Function.prototype.makeSubclass.nonconstructor= function() {};

...

Shape= Object.makeSubclass();
Shape.prototype._init= function(x, y) {
    this.x= x;
    this.y= y;
};

Point= Shape.makeSubclass();

Circle= Shape.makeSubclass();
Circle.prototype._init= function(x, y, r) {
    Shape.prototype._init.call(this, x, y);
    this.r= r;
};

구문은 조금 서투르지만, 다른 언어처럼 보이기 시작했습니다.원한다면 몇 가지 추가 기능을 추가할 수 있습니다.아마 당신은 원할 것이다makeSubclass 하고 디폴트 toString사용하고 있습니다.때 컨스트럭터가 하도록 할 .new연산자(그렇지 않으면 종종 매우 성가신 디버깅이 발생합니다):

Function.prototype.makeSubclass= function() {
    function Class() {
        if (!(this instanceof Class))
            throw('Constructor called without "new"');
        ...

시켜, 「」를 가지는 것이 .makeSubclass프로토타입에 추가해서 작성해야 하는 번거로움을 덜 수 있습니다.Class.prototype... 계층 를 들어, '계급은 그렇게 하고 있습니다. §:

Circle= Shape.makeSubclass({
    _init: function(x, y, z) {
        Shape.prototype._init.call(this, x, y);
        this.r= r;
    },
    ...
});

오브젝트 시스템에서는 바람직하다고 생각할 수 있는 기능이 많이 있습니다만, 어느 누구도 특정 공식에 동의하지 않습니다.


그럼 폐쇄하는 방법.이렇게 하면 상속을 전혀 사용하지 않음으로써 JavaScript의 프로토타입 기반 상속 문제를 방지할 수 있습니다.대신:

function Shape(x, y) {
    var that= this;

    this.x= x;
    this.y= y;

    this.toString= function() {
        return 'Shape at '+that.x+', '+that.y;
    };
}

function Circle(x, y, r) {
    var that= this;

    Shape.call(this, x, y);
    this.r= r;

    var _baseToString= this.toString;
    this.toString= function() {
        return 'Circular '+_baseToString(that)+' with radius '+that.r;
    };
};

var mycircle= new Circle();

ShapetoStringmethod(및 추가하는 다른 메서드 또는 클래스 멤버)를 지정합니다.

모든 인스턴스가 클래스 멤버의 복사본을 갖는 것의 단점은 효율성이 떨어진다는 것입니다.다수의 하위 클래스 인스턴스를 처리하는 경우 프로토타입 상속이 더 유용할 수 있습니다.베이스 클래스의 메서드를 호출하는 것도 약간 귀찮습니다.서브 클래스 컨스트럭터가 오버랩하기 전에 메서드가 무엇이었는지 기억해야 합니다.그렇지 않으면 손실됩니다.

여기에는 에 [또또여여 [ [ [ [ [ []instanceof연산자는 작동하지 않습니다.필요에 따라 클래스 교환을 위한 독자적인 메커니즘을 제공해야 합니다.프로토타입 상속과 유사한 방법으로 프로토타입 객체를 조작할 수 있지만, 조금 까다로우므로 단순히 얻을 가치가 없습니다.instanceof]]]]]]]]] 【중략】

모든 인스턴스가 자체 메서드를 갖는 장점은 메서드가 해당 인스턴스를 소유한 특정 인스턴스에 바인딩될 수 있다는 것입니다.은 JavaScript의합니다.this메서드 콜에서 메서드를 소유자에서 분리하면 다음과 같은 결과를 얻을 수 있습니다.

var ts= mycircle.toString;
alert(ts());

this대로 Circle Circle 가 됩니다).window 이것은 되었을 때 합니다.setTimeout,onclick ★★★★★★★★★★★★★★★★★」EventListener일반적으로

프로토타입 방법에서는 이러한 모든 할당에 대해 닫힘을 포함해야 합니다.

setTimeout(function() {
    mycircle.move(1, 1);
}, 1000);

향후Function에는 Function.Function을 사용할 수도 .protype(프로타입),function.bind():

setTimeout(mycircle.move.bind(mycircle, 1, 1), 1000);

방식으로 은 변수으로 "Closure"라고 함)에 대한 .that ★★★★★★★★★★★★★★★★★」selfselfJavaScript를 사용합니다.맞지 .1, 1이 닫아야 .bind()렇그그 면면 면면 면면 면

클로징 방식도 여러 가지 종류가 있습니다.해도 좋습니다.this 「」의 , 「」의that 때 쓰는 것이 돌려보낼 때 쓰는 것입니다.new★★★★★★★★★★★★★★★★★★:

function Shape(x, y) {
    var that= {};

    that.x= x;
    that.y= y;

    that.toString= function() {
        return 'Shape at '+that.x+', '+that.y;
    };

    return that;
}

function Circle(x, y, r) {
    var that= Shape(x, y);

    that.r= r;

    var _baseToString= that.toString;
    that.toString= function() {
        return 'Circular '+_baseToString(that)+' with radius '+r;
    };

    return that;
};

var mycircle= Circle(); // you can include `new` if you want but it won't do anything

어느 쪽이 적절한가요?둘 다요 어느 게 제일 좋아요?그것은 당신의 상황에 따라 다릅니다.WWIW 저는 강력한 OO 작업을 할 때 실제 JavaScript 상속을 위한 프로토타입 제작과 간단한 일회용 페이지 효과를 위한 클로징을 선호합니다.

그러나 두 방법 모두 대부분의 프로그래머에게는 매우 직관에 반합니다.둘 다 잠재적으로 지저분한 변형을 많이 가지고 있다.다른 사람의 코드/라이브러리를 사용하면 둘 다(또한 중간 구성 및 일반적으로 실패한 구성도 다수) 충족됩니다.일반적으로 받아들여지는 답변은 없습니다.JavaScript 객체의 멋진 세계에 오신 것을 환영합니다.

[JavaScript가 내가 좋아하는 프로그래밍 언어가 아닌 이유 94부입니다]

저는 이 패턴을 꽤 자주 사용하고 있습니다.필요할 때 매우 유연하게 사용할 수 있다는 것을 알게 되었습니다.사용방법은 Java 스타일의 클래스와 비슷합니다.

var Foo = function()
{

    var privateStaticMethod = function() {};
    var privateStaticVariable = "foo";

    var constructor = function Foo(foo, bar)
    {
        var privateMethod = function() {};
        this.publicMethod = function() {};
    };

    constructor.publicStaticMethod = function() {};

    return constructor;
}();

생성 시 호출되는 익명 함수를 사용하여 새 생성자 함수를 반환합니다.익명 함수는 한 번만 호출되므로 이 함수에 개인 정적 변수를 만들 수 있습니다(이러한 변수는 닫힘 내부에 있으며 클래스의 다른 구성원이 볼 수 있습니다). 속성을 Javascript에 합니다.그 안에서 프라이빗 속성을 정의하면 퍼블릭 속성이 에 부가됩니다.this★★★★★★ 。

기본적으로 이 접근 방식은 Crokfordian 접근 방식을 표준 Javascript 객체와 결합하여 보다 강력한 클래스를 만듭니다.

다른 Javascript 오브젝트와 마찬가지로 사용할 수 있습니다.

Foo.publicStaticMethod(); //calling a static method
var test = new Foo();     //instantiation
test.publicMethod();      //calling a method

더글라스 크록포드는 그 주제에 대해 The Good Parts에서 폭넓게 논의한다.새로운 오퍼레이터가 새로운 오브젝트를 작성하지 않도록 권장합니다.대신 그는 맞춤형 컨스트럭터를 만들 것을 제안한다.예:

var mammal = function (spec) {     
   var that = {}; 
   that.get_name = function (  ) { 
      return spec.name; 
   }; 
   that.says = function (  ) { 
      return spec.saying || ''; 
   }; 
   return that; 
}; 

var myMammal = mammal({name: 'Herb'});

Javascript에서 함수는 객체이며 새로운 연산자와 함께 객체를 구성하는 데 사용할 수 있습니다.관례상 컨스트럭터로 사용하는 함수는 대문자로 시작한다.다음과 같은 경우가 자주 있습니다.

function Person() {
   this.name = "John";
   return this;
}

var person = new Person();
alert("name: " + person.name);**

새 객체를 인스턴스화하는 동안 새 연산자를 사용하는 것을 잊은 경우 일반 함수 호출이 수신되며, 는 새 객체가 아닌 글로벌 객체에 바인딩됩니다.

보빈스의 대답에서 벗어나다

es6를 수 .class

이제 다음을 수행할 수 있습니다.

class Shape {
    constructor(x, y) {
        this.x = x;
        this.y = y;
    }

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

(다른 답변과 같이) 원으로 확장하면 다음과 같은 작업을 수행할 수 있습니다.

class Circle extends Shape {
    constructor(x, y, r) {
        super(x, y);
        this.r = r;
    }

    toString() {
        let shapeString = super.toString();
        return `Circular ${shapeString} with radius ${this.r}`;
    }
}

es6는 조금 더 깔끔하고 읽기 쉬워요.


다음으로 동작의 예를 제시하겠습니다.

class Shape {
  constructor(x, y) {
    this.x = x;
    this.y = y;
  }

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

class Circle extends Shape {
  constructor(x, y, r) {
    super(x, y);
    this.r = r;
  }

  toString() {
    let shapeString = super.toString();
    return `Circular ${shapeString} with radius ${this.r}`;
  }
}

let c = new Circle(1, 2, 4);

console.log('' + c, c);

구조체를 사용하여 다음과 같이 할 수도 있습니다.

function createCounter () {
    var count = 0;

    return {
        increaseBy: function(nb) {
            count += nb;
        },
        reset: function {
            count = 0;
        }
    }
}

그 후, 다음과 같이 합니다.

var counter1 = createCounter();
counter1.increaseBy(4);

또 다른 방법은 http://jsfiddle.net/nnUY4/입니다(이러한 종류의 오브젝트 작성 및 공개 기능이 특정 패턴을 따르고 있는지 알 수 없습니다).

// Build-Reveal

var person={
create:function(_name){ // 'constructor'
                        //  prevents direct instantiation 
                        //  but no inheritance
    return (function() {

        var name=_name||"defaultname";  // private variable

        // [some private functions]

        function getName(){
            return name;
        }

        function setName(_name){
            name=_name;
        }

        return {    // revealed functions
            getName:getName,    
            setName:setName
        }
    })();
   }
  }

  // … no (instantiated) person so far …

  var p=person.create(); // name will be set to 'defaultname'
  p.setName("adam");        // and overwritten
  var p2=person.create("eva"); // or provide 'constructor parameters'
  alert(p.getName()+":"+p2.getName()); // alerts "adam:eva"

컨스트럭터 호출 중에 "this"를 닫는 트릭을 사용할 경우 오브젝트에 메서드를 호출하지 않는 다른 오브젝트에 의해 콜백으로 사용할 수 있는 함수를 쓰기 위해서입니다.스코프를 올바르게 하는 것과는 관계가 없습니다.

다음은 vanilla JavaScript 객체입니다.

function MyThing(aParam) {
    var myPrivateVariable = "squizzitch";

    this.someProperty = aParam;
    this.useMeAsACallback = function() {
        console.log("Look, I have access to " + myPrivateVariable + "!");
    }
}

// Every MyThing will get this method for free:
MyThing.prototype.someMethod = function() {
    console.log(this.someProperty);
};

더글라스 크록포드가 JavaScript에 대해 말하는 을 읽으면 많은 것을 얻을 수 있을 것이다. 레식 또한 똑똑하다.행운을 빕니다.

Closure는 다용도입니다.bobince는 오브젝트 작성 시 프로토타입 접근법과 클로징 접근 방식을 잘 요약하고 있습니다.단, 몇 가지 측면은 모방할 수 있습니다.OOP기능적 프로그래밍 방식으로 폐쇄를 사용합니다.함수는 JavaScript의 객체이므로 함수를 객체로 사용하는 방법은 다릅니다.

다음은 닫힘의 예입니다.

function outer(outerArg) {
    return inner(innerArg) {
        return innerArg + outerArg; //the scope chain is composed of innerArg and outerArg from the outer context 
    }
}

얼마 전에 나는 Mozilla의 Closure에 관한 기사를 우연히 접했다."폐쇄를 통해 일부 데이터(환경)를 해당 데이터에 대해 작동하는 기능과 연결할 수 있습니다.는 객체 지향 프로그래밍과 분명히 유사하며 객체 지향 프로그래밍에서는 객체에서 일부 데이터(객체의 속성)를 하나 이상의 메서드와 연결할 수 있습니다."시제품에 대한 언급 없이 폐쇄와 고전적인 OOP의 평행성을 읽은 것은 이번이 처음입니다.

어떻게?

일부 항목의 VAT를 계산하려고 합니다.VAT는 애플리케이션 수명 동안 안정적으로 유지될 가능성이 높습니다.OOP(의사 코드)에서 이를 수행하는 한 가지 방법:

public class Calculator {
    public property VAT { get; private set; }
    public Calculator(int vat) {
        this.VAT = vat;
    }
    public int Calculate(int price) {
        return price * this.VAT;
    }
}

기본적으로 VAT 값을 컨스트럭터에 전달하면 계산 방법은 닫힘을 통해 VAT 값을 조작할 수 있습니다.이제 클래스/컨스트럭터를 사용하는 대신 VAT를 인수로 함수에 전달합니다.관심 있는 것은 계산 자체뿐이므로는 계산 방식인 새로운 함수를 반환합니다.

function calculator(vat) {
    return function(item) {
        return item * vat;
    }
}
var calculate = calculator(1.10);
var jsBook = 100; //100$
calculate(jsBook); //110

프로젝트에서 VAT의 계산에 적합한 최상위 값을 식별합니다.경험칙으로, 같은 인수를 계속 전달할 때마다 닫힘을 사용하여 개선할 수 있는 방법이 있습니다.기존 개체를 만들 필요가 없습니다.

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Closures

오브젝트 작성

JavaScript에서 개체를 만드는 가장 쉬운 방법은 다음 구문을 사용하는 것입니다.

var test = {
  a : 5,
  b : 10,
  f : function(c) {
    return this.a + this.b + c;
  }
}

console.log(test);
console.log(test.f(3));

이것은 구조화된 방식으로 데이터를 저장하는 데 매우 효과적입니다.

그러나 더 복잡한 사용 사례의 경우 다음과 같은 기능의 인스턴스를 만드는 것이 좋습니다.

function Test(a, b) {
  this.a = a;
  this.b = b;
  this.f = function(c) {
return this.a + this.b + c;
  };
}

var test = new Test(5, 10);
console.log(test);
console.log(test.f(3));

이를 통해 의 클래스를 사용하는 방법과 유사하게 동일한 "청사진"을 공유하는 여러 개체를 만들 수 있습니다.자바

그러나 프로토타입을 사용하면 더 효율적으로 작업을 수행할 수 있습니다.

함수의 여러 인스턴스가 동일한 메서드 또는 속성을 공유할 때마다 해당 개체의 프로토타입으로 이동할 수 있습니다.이렇게 하면 함수의 모든 인스턴스가 해당 메서드 또는 속성에 액세스할 수 있지만 모든 인스턴스에 대해 중복될 필요는 없습니다.

이 하는 것이 .f : to to to시 to to to :

function Test(a, b) {
  this.a = a;
  this.b = b;
}

Test.prototype.f = function(c) {
  return this.a + this.b + c;
};

var test = new Test(5, 10);
console.log(test);
console.log(test.f(3));

상속

JavaScript에서 상속을 수행하는 단순하지만 효과적인 방법은 다음과 같은 두 줄을 사용하는 것입니다.

B.prototype = Object.create(A.prototype);
B.prototype.constructor = B;

이는 다음과 같습니다.

B.prototype = new A();

은 쪽orororor of of 의 컨스트럭터가A는 를 사용하는 경우 실행되지 않습니다.이는 보다 직관적이고 클래스 기반 상속과 유사합니다.

할 수 있습니다.AB을 '만들기'의 컨스트럭터에 B:

function B(arg1, arg2) {
    A(arg1, arg2); // This is optional
}

의 인수를 모두 B로로 합니다.A, 를 사용할 수도 있습니다.

function B() {
    A.apply(this, arguments); // This is optional
}

B , 를 조합할 수 .Object.create다음과 같이 설정합니다.

B.prototype = Object.assign(Object.create(A.prototype), mixin.prototype);
B.prototype.constructor = B;

데모

function A(name) {
  this.name = name;
}

A.prototype = Object.create(Object.prototype);
A.prototype.constructor = A;

function B() {
  A.apply(this, arguments);
  this.street = "Downing Street 10";
}

B.prototype = Object.create(A.prototype);
B.prototype.constructor = B;

function mixin() {

}

mixin.prototype = Object.create(Object.prototype);
mixin.prototype.constructor = mixin;

mixin.prototype.getProperties = function() {
  return {
    name: this.name,
    address: this.street,
    year: this.year
  };
};

function C() {
  B.apply(this, arguments);
  this.year = "2018"
}

C.prototype = Object.assign(Object.create(B.prototype), mixin.prototype);
C.prototype.constructor = C;

var instance = new C("Frank");
console.log(instance);
console.log(instance.getProperties());


메모

Object.create는 IE9를 한 모든 할 수 . Object.assign는 IE 또는 일부 모바일브라우저에서는 동작하지 않습니다.폴리필을 권장합니다. Object.create "/"/"Object.assign를 사용하고, 실장하지 않는 브라우저를 서포트하고 싶은 경우.

''로 되어 요.Object.create 위해 여기와 하나를Object.assign 여기 있습니다.

A Pattern That Serves Me Well
var Klass = function Klass() {
    var thus = this;
    var somePublicVariable = x
      , somePublicVariable2 = x
      ;
    var somePrivateVariable = x
      , somePrivateVariable2 = x
      ;

    var privateMethod = (function p() {...}).bind(this);

    function publicMethod() {...}

    // export precepts
    this.var1 = somePublicVariable;
    this.method = publicMethod;

    return this;
};

먼저 생성자 개체 대신 인스턴스에 메서드를 추가하는 기본 설정을 변경할 수 있습니다.저는 상속 및 장식 관련 목적으로 컨스트럭터 하이잭을 자주 사용하기 때문에 컨스트럭터 내부에 메서드를 항상 선언합니다.

어떤 선언문을 쓸지 결정하는 방법은 다음과 같습니다.

  • 오브젝트에 (「」).this)
  • let let 렛츠고varfunction
  • 보다 {} ★★★★★★★★★★★★★★★★★」[])
  • let let 렛츠고publicprivate
  • Function.prototype.bind에 걸쳐서thus,self,vm,etc
  • 다음 경우를 제외하고 다른 클래스 내에서 클래스를 선언하지 마십시오.
    • 두 사람은 떼려야 뗄 수 없는 관계라는 것은 분명해야 한다
    • 내부 클래스는 명령 패턴을 구현합니다.
    • Inner 클래스는 싱글톤 패턴을 구현합니다.
    • 내부 클래스는 상태 패턴을 구현합니다.
    • 내부 클래스는 이를 보장하는 다른 설계 패턴을 구현합니다.
  • 반환하다this폐쇄 공간의 어휘적 범위 내에서.

다음은 도움이 되는 이유:

Constructor Hijacking
var Super = function Super() {
    ...
    this.inherited = true;
    ...
};
var Klass = function Klass() {
    ...
    // export precepts
    Super.apply(this);  // extends this with property `inherited`
    ...
};
Model Design
var Model = function Model(options) {
    var options = options || {};

    this.id = options.id || this.id || -1;
    this.string = options.string || this.string || "";
    // ...

    return this;
};
var model = new Model({...});
var updated = Model.call(model, { string: 'modified' });
(model === updated === true);  // > true
Design Patterns
var Singleton = new (function Singleton() {
    var INSTANCE = null;

    return function Klass() {
        ...
        // export precepts
        ...

        if (!INSTANCE) INSTANCE = this;
        return INSTANCE;
    };
})();
var a = new Singleton();
var b = new Singleton();
(a === b === true);  // > true

저는 필요 .thus(또는 )보다 더 좋기 때문에저희 회사에서는Singleton붙이지 thusINSTANCE더 많은 정보를 전달합니다.★★★의 Model 돌아오다.this 해서 할 수 있습니다..call우리가 전달한 인스턴스를 되돌리는 거죠.인 '아까', '아까'에했습니다.updated,, 른, 른, 른, 른, 른, 른, 른

저는 사물을 를 쓰는 합니다.new{filename over {filename}:

Preferred
var klass = new (function Klass(Base) {
    ...
    // export precepts
    Base.apply(this);  //
    this.override = x;
    ...
})(Super);
Not Preferred
var klass = Super.apply({
    override: x
});

보시다시피 후자는 Superclass의 "override" 속성을 재정의할 수 없습니다.

의 메서드를 prototype합니다.--------------------------------------------------------------------------------------------------------------------new★★★★★★★★★★★★★★★★★★:

Preferred
Klass.prototype = new Super();
// OR
Klass.prototype = new (function Base() {
    ...
    // export precepts
    Base.apply(this);
    ...
})(Super);
// OR
Klass.prototype = Super.apply({...});
// OR
Klass.prototype = {
    method: function m() {...}
};
Not Preferred
Klass.prototype.method = function m() {...};

Title 또는 String사용하여 객체를 선언할 수 있습니다.
각 타입에 따라 다른 방법으로 호출할 수 있습니다.아래를 참조해 주세요.

var test = {

  useTitle : "Here we use 'a Title' to declare an Object",
  'useString': "Here we use 'a String' to declare an Object",
  
  onTitle : function() {
    return this.useTitle;
  },
  
  onString : function(type) {
    return this[type];
  }
  
}

console.log(test.onTitle());
console.log(test.onString('useString'));

var Person = function (lastname, age, job){
this.name = name;
this.age = age;
this.job = job;
this.changeName = function(name){
this.lastname = name;
}
}
var myWorker = new Person('Adeola', 23, 'Web Developer');
myWorker.changeName('Timmy');

console.log("New Worker" + myWorker.lastname);

2009년부터 인정된 답변에 더하여.최신 브라우저를 대상으로 할 수 있다면 Object.defineProperty를 사용할 수 있습니다.

Object.defineProperty() 메서드는 객체에 직접 새 속성을 정의하거나 객체의 기존 속성을 변경하여 객체를 반환합니다.출처 : Mozilla

var Foo = (function () {
    function Foo() {
        this._bar = false;
    }
    Object.defineProperty(Foo.prototype, "bar", {
        get: function () {
            return this._bar;
        },
        set: function (theBar) {
            this._bar = theBar;
        },
        enumerable: true,
        configurable: true
    });
    Foo.prototype.toTest = function () {
        alert("my value is " + this.bar);
    };
    return Foo;
}());

// test instance
var test = new Foo();
test.bar = true;
test.toTest();

데스크톱 및 모바일 호환성 목록을 보려면 Mozilla의 브라우저 호환성 목록을 참조하십시오.네, IE9+는 Safari 모바일과 함께 지원합니다.

이것도 시도해 보세요.

    function Person(obj) {
    'use strict';
    if (typeof obj === "undefined") {
        this.name = "Bob";
        this.age = 32;
        this.company = "Facebook";
    } else {
        this.name = obj.name;
        this.age = obj.age;
        this.company = obj.company;
    }

}

Person.prototype.print = function () {
    'use strict';
    console.log("Name: " + this.name + " Age : " + this.age + " Company : " + this.company);
};

var p1 = new Person({name: "Alex", age: 23, company: "Google"});
p1.print();

기본적으로 JS에는 클래스 개념이 없으므로 기존 설계 패턴과 관련된 클래스 생성자로 함수를 사용합니다.

//Constructor Pattern
function Person(name, age, job){
 this.name = name;
 this.age = age;
 this.job = job;
 this.doSomething = function(){
    alert('I am Happy');
}
}

지금까지 JS는 당신이 오브젝트를 만들고 싶다는 단서를 가지고 있지 않기 때문에 새로운 키워드가 등장합니다.

var person1 = new Person('Arv', 30, 'Software');
person1.name //Arv

참조: 웹 개발자를 위한 프로페셔널 JS - Nik Z

언급URL : https://stackoverflow.com/questions/1595611/how-to-properly-create-a-custom-object-in-javascript

반응형