2011-02-01 5 views
78

나는 자바 스크립트에서 객체를 생성해야하는 방법에 대해 혼란스러워하고 있습니다. 최소한 두 가지 방법이있는 것 같습니다. 하나는 객체 리터럴 표기법을 사용하는 반면 다른 하나는 생성 함수를 사용하는 것입니다. 다른 것보다 하나의 이점이 있습니까?객체 리터럴 또는 생성자 함수를 사용해야합니까?

+1

가장 좋은 대답은 다음과 같습니다. http://stackoverflow.com/questions/4597926/creating-objects-new-object-or-object-literal-notation 요약하면 인스턴스를 만들 수있는 기능을 설정할 수 있습니다 리터럴 표기법도 작성하십시오. 각 인스턴스는 모든 메소드를 전달하지만, 생성자의 경우 모든 인스턴스는 프로토 타입 메소드를 참조합니다.즉, 생성자가 메모리 성능이 더 좋습니다. – Federico

답변

106

개체와 관련된 동작이없는 경우 (개체가 데이터/상태의 컨테이너 일 경우) 개체 리터럴을 사용합니다.

var data = { 
    foo: 42, 
    bar: 43 
}; 

KISS principle을 적용하십시오. 단순한 데이터 컨테이너가 아닌 다른 것을 필요로하지 않는다면 간단한 리터럴을 사용하십시오.

개체에 비헤이비어를 추가하려는 경우 생성자와 함께 이동 중에 개체에 메서드를 추가하거나 클래스에 프로토 타입을 제공 할 수 있습니다.

function MyData(foo, bar) { 
    this.foo = foo; 
    this.bar = bar; 

    this.verify = function() { 
     return this.foo === this.bar; 
    }; 
} 

// or: 
MyData.prototype.verify = function() { 
    return this.foo === this.bar; 
}; 

이 같은 클래스는 데이터 오브젝트의 스키마와 같은 역할을 : 당신은 지금 (생성자를 통해) 계약의 일종을 가지고있는 개체가 포함되어/초기화 어떤 속성. 무료 리터럴은 단지 비정형 데이터 블롭입니다.

당신은뿐만 아니라 일반 오래된 데이터 개체에 작용하는 외부 verify 기능이있을 수 있습니다 그러나

var data = { 
    foo: 42, 
    bar: 43 
}; 

function verify(data) { 
    return data.foo === data.bar; 
} 

을,이 캡슐에 관해서 유리한되지 않습니다 : 이상적으로,과 관련된 모든 데이터 + 행동 엔티티는 함께 살아야합니다.

+7

큰 설명, 그러나 객체 리터럴에 함수를 넣는 것은 어떨까요? 이전에 이것을 보았습니다. 실제로 아래 게시물에 이에 대한 예제가 있습니다. – chobo

+20

함수 리터럴의 일부로 함수 정의를 포함 시키거나'this.fn = function ... '접근 방식을 사용하면 객체 인스턴스 각각에 고유 한 함수 복사본이 있습니다. 프로토 타입 접근 방식을 사용하면 각 함수를 한 번만 연결하면 프로토 타입 상속을 통해 인스턴스에 상속됩니다. –

+11

I 당신은 중요한 것을 놓쳤다 고 믿는다. 생성자 함수 만이 private 멤버와 public 멤버 (캡슐화)를 객체 리터럴에 제공 할 수있다 - 그들은 모두 public이다. –

0

개체 리터럴로 이동하면 초기 값 도입으로 더 중요 해지고 확장됩니다.

+0

개체 리터럴에 개인 변수를 어떻게 만듭니 까? – EhevuTov

+0

원래 질문과 관련이 없으므로 링크를 제공 할 수는 없습니다. http://javascript.crockford.com/private.html – Tom

+1

실제로 차이점이 있기 때문에 실제로 관련성이 있습니다. 특정 상황에 따라 둘 중 하나를 사용해야하는 이유가 있습니다. 이 경우 개인 변수가 필요한지 아닌지 여부입니다. 리터럴에 closure 함수를 먼저 생성하여 리터럴에 private 변수를 만들 수는 있지만, 필자의 견해로는 읽기가 어렵다. – EhevuTov

5

당신이하고 싶은 일에 달려 있습니다. 당신이 (세미) 개인 변수 나 함수를 객체에 사용하고 싶다면, 생성자 함수가 그것을 수행하는 방법이다. 개체에 속성과 메서드 만 있으면 개체 리터럴이 좋습니다.

function SomeConstructor(){ 
    var x = 5; 
    this.multiply5 = function(i){ 
     return x*i; 
    } 
} 
var myObj = new SomeConstructor; 

var SomeLiteral = { 
    multiply5: function(i){ return i*5; } 
} 

지금 myObjSomeLiteral의 방법 multiply5 정확히 같은 일을. 유일한 차이점은 myObj가 전용 변수를 사용한다는 것입니다. 후자는 경우에 따라 유용 할 수 있습니다. 대부분의 경우 객체 리터럴로 충분하고 JS 객체를 생성하는 멋지고 깨끗한 방법입니다.

+0

함수와 메서드의 차이점은 무엇입니까? 나는 C# 배경에서 온다. 그래서 나에게 함수는 독립형이고 메쏘드는 클래스의 일부분 인 함수이다. – chobo

+1

별로 차이가 없습니다. 예를 들어 http://www.web-source.net/javascript_tutorial/javascript_functions_methods.htm을 참조하십시오. 실제로 DOMscripting (브라우저의 클라이언트 측 js)에서 모든 함수는 윈도우 객체 (전역 네임 스페이스)의 메소드가됩니다. 모든 독립 실행 형 함수를 윈도우로 지정할 수 있습니다. [somefunction] – KooiInc

81

개체의 인스턴스가 여러 개 필요한지 여부는 기본적으로 달라집니다. 생성자로 정의 된 객체를 사용하면 해당 객체의 여러 인스턴스를 가질 수 있습니다. 객체 리터럴은 기본적으로 모두 공개 된 변수/메서드를 가진 싱글 톤입니다.

// define the objects: 
var objLit = { 
    x: 0, 
    y: 0, 
    z: 0, 
    add: function() { 
    return this.x + this.y + this.z; 
    } 
}; 

var ObjCon = function(_x, _y, _z) { 
    var x = _x; // private 
    var y = _y; // private 
    this.z = _z; // public 
    this.add = function() { 
    return x + y + this.z; // note x, y doesn't need this. 
    }; 
}; 

// use the objects: 
objLit.x = 3; 
objLit.y = 2; 
objLit.z = 1; 
console.log(objLit.add());  

var objConIntance = new ObjCon(5,4,3); // instantiate an objCon 
console.log(objConIntance.add()); 
console.log((new ObjCon(7,8,9)).add()); // another instance of objCon 
console.log(objConIntance.add()); // same result, not affected by previous line 
+1

결정할 때 명심해야 할 점은 매우 좋습니다. 고마워. – zkent

+0

제 경험상 이것이 정확히 차이점입니다. 아주 명확한 예. – Air

+0

gr8 설명 ... 매우 유용한 정보 – Vikash

7

균일 한 방법으로 개체를 만들 수있는 또 다른 방법은 객체를 반환하는 함수를 사용하는 것입니다 : 자바 스크립트 함수는 우리가 개인 변수와 메소드를 사용하고 new을 피할 수 폐쇄이기 때문에

function makeObject() { 
    var that = { 
     thisIsPublic: "a public variable" 
     thisIsAlsoPublic: function() { 
      alert(that.thisIsPublic); 
     } 
    }; 

    var secret = "this is a private variable" 

    function secretFunction() { // private method 
     secret += "!"; // can manipulate private variables 
     that.thisIsPublic = "foo";  
    } 

    that.publicMethod = function() { 
     secret += "?"; // this method can also mess with private variables 
    } 

    that.anotherPublicVariable = "baz"; 

    return that; // this is the object we've constructed 
} 

makeObject.static = "This can be used to add a static varaible/method"; 

var bar = makeObject(); 
bar.publicMethod(); // ok 
alert(bar.thisIsPublic); // ok 
bar.secretFunction(); // error! 
bar.secret // error! 

.

http://javascript.crockford.com/private.html은 JavaScript의 전용 변수입니다.

5

아래 코드는 개체 리터럴 구문, 함수 생성자 및 Object.create()을 만드는 세 가지 방법을 보여줍니다.객체 리터럴 구문은 즉석에서 객체를 만들고 객체에 넣기 때문에 __prototype__Object 객체이며 Object의 모든 속성 및 메서드에 액세스 할 수 있습니다. 엄밀히 말하면 디자인 패턴 관점에서 간단한 단일 개체 리터럴을 사용하여 단일 데이터 인스턴스를 저장해야합니다.

함수 생성자에는 .prototype이라는 특수 속성이 있습니다. 이 속성은 함수 생성자가 만든 모든 개체의 __prototype__이됩니다. 함수 생성자의 .prototype 속성에 추가 된 모든 속성과 메서드는 해당 함수가 만드는 모든 개체에서 사용할 수 있습니다. 데이터의 여러 인스턴스가 필요하거나 개체의 동작이 필요한 경우 생성자를 사용해야합니다. 함수 생성자는 private/public 개발 패턴을 시뮬레이트 할 때 가장 잘 사용됩니다. 모든 공유 메소드를 .prototype에 두어 각 객체 인스턴스에서 생성되지 않도록하십시오.

Object.create()으로 개체를 만드는 것은이 메서드로 만든 개체의 개체 리터럴을 __prototype__으로 사용합니다. 객체 리터럴에 추가 된 모든 속성 및 메서드는 실제 프로토 타입 상속을 통해 생성 된 모든 객체에서 사용할 수 있습니다. 이것이 제가 선호하는 방법입니다.

//Object Example 

//Simple Object Literal 
var mySimpleObj = { 
    prop1 : "value", 
    prop2 : "value" 
} 

// Function Constructor 
function PersonObjConstr() { 
    var privateProp = "this is private"; 
    this.firstname = "John"; 
    this.lastname = "Doe"; 
} 
PersonObjConstr.prototype.greetFullName = function() { 
    return "PersonObjConstr says: Hello " + this.firstname + 
    " " + this.lastname; 
}; 

// Object Literal 
var personObjLit = { 
    firstname : "John", 
    lastname: "Doe", 
    greetFullName : function() { 
     return "personObjLit says: Hello " + this.firstname + 
     ", " + this.lastname; 
    } 
} 

var newVar = mySimpleObj.prop1; 
var newName = new PersonObjConstr(); 
var newName2 = Object.create(personObjLit); 
+0

개체 리터럴 내부에서 함수를 선언 했으므로. 즉,'Object.create'를 사용하여 객체를 생성하면 리터럴 내부의 함수가 인스턴스마다 고유하게됩니다. – JohnnyQ

-1

// 생성자 리터럴 객체와 객체

function MyData(foo, bar) { 
     this.foo = foo; 
     this.bar = bar; 

    } 
MyData.prototype.verify = function() { 
     return this.foo === this.bar; 
    }; 

//add property using prototype 

var MD = new MyData;//true. 
var MD = new MyData();//true. 
MD.verify// return only the function structure. 
MD.verify(); //return the verify value and in this case return true coz both value is null. 
var MD1 = new MyData(1,2); // intialized the value at the starting. 
MD1.verify// return only the function structure. 
MD1.verify(); // return false coz both value are not same. 
MD1.verify(3,3);// return false coz this will not check this value intialized at the top 
MyData.prototype.verify = function (foo,bar) { 
    return this.foo === this.bar; 
}; 
var MD1 = new MyData(1,2); 
MD1.verify(); 
MD1.verify(3,3);// return false coz this keyword used with foo and bar that will check parent data 
+1

예제에서 Object 리터럴이 선언 되었습니까? – JohnnyQ

2

enter image description here

당신은 페이지의 객체의 단일 인스턴스를 원하십니까 - 리터럴을. , 생성자 함수를 OOP 원칙, 상속을 따라 -

당신이 방법 행동, 여러 인스턴스와 실제 객체를 만드시겠습니까 리터럴 - : - 생성자 함수

은 DTO는 간단한 GET 세트를 객체처럼 단지 데이터를 전송 하시겠습니까 .

다음은 리터럴이 무엇인지, 생성자 함수가 무엇인지, 서로 어떻게 다른지에 대해 자세히 설명하는 YouTube 동영상입니다.

https://www.youtube.com/watch?v=dVoAq2D3n44

0

객체 리터럴을 사용하여 https://www.w3schools.com/js/js_object_definition.asp

에서 언급 한 바와 같이, 당신은 둘 성명에서 객체,을 만들 정의합니다.

또한

객체 리터럴 단 하나의 개체를 만듭니다. 때로 많은 유형의 개체를 만드는 데 사용할 수 있습니다.

관련 문제