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();
의 Shape
인 toString
method(및 추가하는 다른 메서드 또는 클래스 멤버)를 지정합니다.
모든 인스턴스가 클래스 멤버의 복사본을 갖는 것의 단점은 효율성이 떨어진다는 것입니다.다수의 하위 클래스 인스턴스를 처리하는 경우 프로토타입 상속이 더 유용할 수 있습니다.베이스 클래스의 메서드를 호출하는 것도 약간 귀찮습니다.서브 클래스 컨스트럭터가 오버랩하기 전에 메서드가 무엇이었는지 기억해야 합니다.그렇지 않으면 손실됩니다.
여기에는 에 [또또여여 [ [ [ [ [ []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
★★★★★★★★★★★★★★★★★」self
는 self
JavaScript를 사용합니다.맞지 .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
는 를 사용하는 경우 실행되지 않습니다.이는 보다 직관적이고 클래스 기반 상속과 유사합니다.
할 수 있습니다.A
시B
을 '만들기'의 컨스트럭터에 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
여기 있습니다.
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 렛츠고
var
function
- 보다
{}
★★★★★★★★★★★★★★★★★」[]
) - let let 렛츠고
public
private
Function.prototype.bind
에 걸쳐서thus
,self
,vm
,etc
- 다음 경우를 제외하고 다른 클래스 내에서 클래스를 선언하지 마십시오.
- 두 사람은 떼려야 뗄 수 없는 관계라는 것은 분명해야 한다
- 내부 클래스는 명령 패턴을 구현합니다.
- Inner 클래스는 싱글톤 패턴을 구현합니다.
- 내부 클래스는 상태 패턴을 구현합니다.
- 내부 클래스는 이를 보장하는 다른 설계 패턴을 구현합니다.
- 반환하다
this
폐쇄 공간의 어휘적 범위 내에서.
다음은 도움이 되는 이유:
Constructor Hijackingvar 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
붙이지 thus
INSTANCE
더 많은 정보를 전달합니다.★★★의 Model
돌아오다.this
해서 할 수 있습니다..call
우리가 전달한 인스턴스를 되돌리는 거죠.인 '아까', '아까'에했습니다.updated
,, 른, 른, 른, 른, 른, 른, 른
저는 사물을 를 쓰는 합니다.new
{filename over {filename}:
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
★★★★★★★★★★★★★★★★★★:
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
'programing' 카테고리의 다른 글
Django - make migrations - 변경된 내용이 없습니다. (0) | 2022.10.11 |
---|---|
MySQL과 SQL Server의 차이점 (0) | 2022.10.11 |
속성 합계를 위해 객체 배열에 대한 감소를 호출하려면 어떻게 해야 합니까? (0) | 2022.10.11 |
Python 3 회전 범위를 목록으로 설정 (0) | 2022.10.11 |
C에서 C++를 우아하게 호출하다 (0) | 2022.10.11 |