development

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

big-blog 2020. 5. 14. 20:40
반응형

`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"; 

JavaScript Expando 속성 기능을 사용하면 이런 방식으로 새 멤버를 즉시 만들 수 있으며 의도했던 것을 달성 할 수 있습니다. 그러나이 방법은 구조화되거나 캡슐화되지 않습니다. 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. Using new Object() allows you to pass another object. The obvious outcome is that the newly created object will be set to the same reference. Here is a sample code:

    var obj1 = new Object();
    obj1.a = 1;
    var obj2 = new Object(obj1);
    obj2.a // 1
    
  2. The usage is not limited to objects as in OOP objects. Other types could be passed to it too. The function will set the type accordingly. For example if we pass integer 1 to it, an object of type number will be created for us.

    var obj = new Object(1);
    typeof obj // "number"
    
  3. The object created using the above method (new Object(1)) would be converted to object type if a property is added to it.

    var obj = new Object(1);
    typeof obj // "number"
    obj.a = 2;
    typeof obj // "object"
    
  4. If the object is a copy of a child class of object, we could add the property without the type conversion.

    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
    

Actually, there are several ways to create objects in JavaScript. When you just want to create an object there's no benefit of creating "constructor-based" objects using "new" operator. It's same as creating an object using "object literal" syntax. But "constructor-based" objects created with "new" operator comes to incredible use when you are thinking about "prototypal inheritance". You cannot maintain inheritance chain with objects created with literal syntax. But you can create a constructor function, attach properties and methods to its prototype. Then if you assign this constructor function to any variable using "new" operator, it will return an object which will have access to all of the methods and properties attached with the prototype of that constructor function.

Here is an example of creating an object using constructor function (see code explanation at the bottom):

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();

Now, you can create as many objects as you want by instantiating Person construction function and all of them will inherit fullname() from it.

Note: "this" keyword will refer to an empty object within a constructor function and whenever you create a new object from Person using "new" operator it will automatically return an object containing all of the properties and methods attached with the "this" keyword. And these object will for sure inherit the methods and properties attached with the prototype of the Person constructor function (which is the main advantage of this approach).

By the way, if you wanted to obtain the same functionality with "object literal" syntax, you would have to create fullname() on all of the objects like below:

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();

At last, if you now ask why should I use constructor function approach instead of object literal approach:

*** Prototypal inheritance allows a simple chain of inheritance which can be immensely useful and powerful.

*** It saves memory by inheriting common methods and properties defined in constructor functions prototype. Otherwise, you would have to copy them over and over again in all of the objects.

I hope this makes sense.


Also, according to some of the O'Really javascript books....(quoted)

Another reason for using literals as opposed to the Object constructor is that there is no scope resolution. Because it’s possible that you have created a local constructor with the same name, the interpreter needs to look up the scope chain from the place you are calling Object() all the way up until it finds the global Object constructor.


I have found one difference, for ES6/ES2015. You cannot return an object using the shorthand arrow function syntax, unless you surround the object with new Object().

> [1, 2, 3].map(v => {n: v});
[ undefined, undefined, undefined ]
> [1, 2, 3].map(v => new Object({n: v}));
[ { n: 1 }, { n: 2 }, { n: 3 } ]

This is because the compiler is confused by the {} brackets and thinks n: i is a label: statement construct; the semicolon is optional so it doesn't complain about it.

If you add another property to the object it will finally throw an error.

$ node -e "[1, 2, 3].map(v => {n: v, m: v+1});"
[1, 2, 3].map(v => {n: v, m: v+1});
                           ^

SyntaxError: Unexpected token :

2019 Update

I ran the same code as @rjloura on my OSX High Sierra 10.13.6 node version 10.13.0 and these are the results

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');


Testing Array:
using[]: 117.613ms
using new: 117.168ms
Testing Object:
using{}: 117.205ms
using new: 118.644ms

Memory usage is different if you create 10 thousand instances. new Object() will only keep only one copy while {} will keep 10 thousand copies.

참고URL : https://stackoverflow.com/questions/4597926/what-is-the-difference-between-new-object-and-object-literal-notation

반응형