[javascript] `new Object ()`와 객체 리터럴 표기법의 차이점은 무엇입니까?

객체 생성을위한이 생성자 기반 구문의 차이점은 무엇입니까?

person = new Object()

… 그리고이 리터럴 구문 :

person = {
    property1 : "Hello"
};

JSLint는 객체 리터럴 표기법을 선호하지만 둘 다 동일한 작업을 수행하는 것으로 보입니다.

어느 것이 더 좋고 왜?



답변

그들은 모두 같은 일을 할 것 이외의 (이상한 사람의 완료 뭔가하지 않는 한), 두 번째 하나는 객체를 생성 하고 여기에 속성을 추가합니다. 그러나 리터럴 표기법은 소스 코드에서 공간을 덜 차지합니다. 무슨 일이 일어나고 있는지 분명히 알 수 있으므로new Object() 하면 실제로 더 많은 것을 입력하고 (이론적으로 JavaScript 엔진에 의해 최적화되지 않은 경우) 불필요한 함수 호출을 수행합니다.

이들

person = new Object() /*You should put a semicolon here too.
It's not required, but it is good practice.*/
-or-

person = {
    property1 : "Hello"
};

기술적으로 같은 일을하지 마십시오. 첫 번째는 객체를 만듭니다. 두 번째는 하나를 만들고 속성을 할당합니다. 첫 번째 것이 동일하려면 속성을 만들고 할당하는 두 번째 단계가 필요합니다.

누군가가 할 수있는 “비정상적인 것”은 기본 Object전역 을 가리거나 할당하는 것입니다 .

// Don't do this
Object = 23;

점에서 높은 특이한 경우, new Object실패하지만,{} 작동합니다.

실제로 new Object{}(이 매우 특이한 일을하지 않은 경우) 보다 사용할 이유가 없습니다 .


답변

예제와 같이 메소드가없는 간단한 객체에는 차이가 없습니다. 그러나 객체에 메소드를 추가하기 시작하면 큰 차이가 있습니다.

리터럴 방식 :

function Obj( prop ) {
    return {
        p : prop,
        sayHello : function(){ alert(this.p); },
    };
} 

프로토 타입 방식 :

function Obj( prop ) {
    this.p = prop;
}
Obj.prototype.sayHello = function(){alert(this.p);}; 

두 가지 방법으로 다음 Obj과 같은 인스턴스를 만들 수 있습니다 .

var foo = new Obj( "hello" ); 

그러나 문자 그대로의 방법으로 sayHello객체의 각 인스턴스 내에 메소드 의 사본을 가지고 있습니다. 반면 프로토 타입 방식에서는 메소드가 오브젝트 프로토 타입에 정의되어 모든 오브젝트 인스턴스간에 공유됩니다.
많은 객체 또는 많은 메소드가있는 경우 문자 그대로의 방법으로 인해 상당한 메모리 낭비가 발생할 수 있습니다.


답변

JavaScript에서 우리는 두 가지 방법으로 새로운 빈 객체를 선언 할 수 있습니다 :

var obj1 = new Object();
var obj2 = {};  

나는 그들이이 무대 뒤에서 어떻게 작동하는지에 관해이 두 가지 큰 차이점이 있음을 시사하는 것을 찾지 못했다 (내가 틀렸다면 나를 교정해라 – 알고 싶다). 그러나 두 번째 방법 (객체 리터럴 표기법 사용)은 몇 가지 장점을 제공합니다.

  1. 짧습니다 (정확한 10 자)
  2. 객체를보다 쉽고 빠르게 생성 할 수있는 구조화
  3. 일부 버푼이 실수로 객체를 재정의했는지 여부는 중요하지 않습니다.

Name 및 TelNo 멤버를 포함하는 새 오브젝트를 고려하십시오. 새로운 Object () 규칙을 사용하여 다음과 같이 만들 수 있습니다.

var obj1 = new Object();
obj1.Name = "A Person";
obj1.TelNo = "12345"; 

는 Expando 속성JavaScript 기능을 사용하면 이런 방식으로 새 멤버를 즉시 만들 수 있으며 의도했던 것을 달성 할 수 있습니다. 그러나이 방법은 구조화되거나 캡슐화되지 않습니다. expando 속성 및 할당 후 생성에 의존하지 않고 생성시 멤버를 지정하려면 어떻게해야합니까?

여기에 객체 리터럴 표기법이 도움이 될 수 있습니다.

var obj1 = {Name:"A Person",TelNo="12345"};  

여기서 우리는 한 줄의 코드에서 동일한 효과를 달성했으며 문자 수가 훨씬 적었습니다.

위의 객체 구성 방법에 대한 자세한 내용은 JavaScript 및 객체 지향 프로그래밍 (OOP) 에서 확인할 수 있습니다 .

마지막으로 Object를 대체 한 바보는 무엇입니까? 불가능하다고 생각 했습니까? 글쎄, 이 JSFiddle 달리 증명한다. 객체 리터럴 표기법을 사용하면 우리가이 버릇을 파울 수 없습니다.

( http://www.jameswiseman.com/blog/2011/01/19/jslint-messages-use-the-object-literal-notation/에서 )


답변

Node.js를 사용하는 컴퓨터에서 다음을 실행했습니다.

console.log('Testing Array:');
console.time('using[]');
for(var i=0; i<200000000; i++){var arr = []};
console.timeEnd('using[]');

console.time('using new');
for(var i=0; i<200000000; i++){var arr = new Array};
console.timeEnd('using new');

console.log('Testing Object:');

console.time('using{}');
for(var i=0; i<200000000; i++){var obj = {}};
console.timeEnd('using{}');

console.time('using new');
for(var i=0; i<200000000; i++){var obj = new Object};
console.timeEnd('using new');

이것은 다음에서 발견되는 것의 확장입니다. arr = []가 arr = new Array보다 빠른 이유는 무엇입니까?

내 결과는 다음과 같습니다.

Testing Array:
using[]: 1091ms
using new: 2286ms
Testing Object:
using{}: 870ms
using new: 5637ms

따라서 빈 객체 / 배열을 만드는 데 new를 사용하는 것보다 {} 및 []가 더 빠릅니다.


답변

여기의 모든 사람들은이 둘의 유사점에 대해 이야기하고 있습니다. 차이점을 지적하겠습니다.

  1. 를 사용 new Object()하면 다른 객체를 전달할 수 있습니다. 명백한 결과는 새로 작성된 오브젝트가 동일한 참조로 설정된다는 것입니다. 다음은 샘플 코드입니다.

    var obj1 = new Object();
    obj1.a = 1;
    var obj2 = new Object(obj1);
    obj2.a // 1
  2. 사용법은 OOP 객체에서와 같이 객체로 제한되지 않습니다. 다른 유형도 전달 될 수 있습니다. 이 기능은 그에 따라 유형을 설정합니다. 예를 들어 정수 1을 전달하면 숫자 유형의 객체가 생성됩니다.

    var obj = new Object(1);
    typeof obj // "number"
  3. 위의 방법 ( new Object(1))을 사용하여 생성 된 객체 는 속성이 추가되면 객체 유형으로 변환됩니다.

    var obj = new Object(1);
    typeof obj // "number"
    obj.a = 2;
    typeof obj // "object"
  4. 객체가 객체의 하위 클래스의 복사 본인 경우 유형 변환없이 속성을 추가 할 수 있습니다.

    var obj = new Object("foo");
    typeof obj // "object"
    obj === "foo" // true
    obj.a = 1;
    obj === "foo" // true
    obj.a // 1
    var str = "foo";
    str.a = 1;
    str.a // undefined

답변

실제로 JavaScript로 객체를 생성하는 방법에는 여러 가지가 있습니다. 객체를 만들고 싶을 때는 ” new “연산자를 사용하여 ” 생성자 기반 “객체를 만들면 아무런 이점이 없습니다 . ” 객체 리터럴 “구문을 사용하여 객체를 만드는 것과 같습니다 . 그러나 ” new “연산자로 생성 된 ” 생성자 기반 “개체 는 ” 프로토 타입 상속 “에 대해 생각할 때 매우 유용합니다 . 리터럴 구문으로 작성된 오브젝트로 상속 체인을 유지할 수 없습니다. 그러나 생성자 함수를 만들고 속성과 메서드를 프로토 타입에 연결할 수 있습니다 .“연산자를 사용하면 해당 생성자 함수의 프로토 타입에 연결된 모든 메서드 및 속성에 액세스 할 수있는 개체가 반환됩니다.

다음은 생성자 함수를 사용하여 객체를 생성하는 예입니다 (하단의 코드 설명 참조).

function Person(firstname, lastname) {
    this.firstname = firstname;
    this.lastname = lastname;
}

Person.prototype.fullname = function() {
    console.log(this.firstname + ' ' + this.lastname);
}

var zubaer = new Person('Zubaer', 'Ahammed');
var john = new Person('John', 'Doe');

zubaer.fullname();
john.fullname();

이제 Person 생성 함수를 인스턴스화하여 원하는 수의 객체를 만들 수 있으며 모든 객체는 fullname ()을 상속합니다.

참고 : ” this “키워드는 생성자 함수 내에서 빈 객체를 참조하며 ” new “연산자를 사용하여 Person에서 새 객체를 만들 때마다 ” this “키워드로 연결된 모든 속성과 메서드가 포함 된 객체를 자동으로 반환 합니다. . 그리고이 객체는 Person 생성자 함수 의 프로토 타입 에 첨부 된 메소드와 속성을 확실히 상속합니다 (이 접근 방식의 주요 이점).

그런데 ” 객체 리터럴 “구문 과 동일한 기능을 얻으려면 다음과 같이 모든 객체에 대해 fullname ()을 만들어야합니다.

var zubaer = {
    firstname: 'Zubaer',
    lastname: 'Ahammed',
    fullname: function() {
        console.log(this.firstname + ' ' + this.lastname);
    }
};

var john= {
    firstname: 'John',
    lastname: 'Doe',
    fullname: function() {
        console.log(this.firstname + ' ' + this.lastname);
    }
};

zubaer.fullname();
john.fullname();

마지막으로, 왜 객체 리터럴 접근법 대신 생성자 함수 접근법을 사용해야하는지 묻는다면 :

*** 프로토 타입 상속은 매우 유용하고 강력 할 수있는 간단한 상속 체인을 허용합니다.

*** 생성자 함수 프로토 타입에 정의 된 공통 메소드 및 특성을 상속하여 메모리를 절약합니다. 그렇지 않으면 모든 객체에서 반복해서 복사해야합니다.

이것이 의미가 있기를 바랍니다.


답변

또한, O’Really 자바 스크립트 책 중 일부에 따르면 … (인용)

Object 생성자와 달리 리터럴을 사용하는 또 다른 이유는 범위 확인이 없기 때문입니다. 동일한 이름으로 로컬 생성자를 만들었을 수 있으므로 인터프리터는 전역 Object 생성자를 찾을 때까지 Object ()를 호출하는 위치에서 스코프 체인을 찾아야합니다.