"new Object()"와 객체 리터럴 표기법의 차이점은 무엇입니까?
오브젝트를 작성하기 위한 이 컨스트럭터 기반 구문의 차이점은 무엇입니까?
person = new Object()
...그리고 다음 리터럴 구문:
person = {
property1 : "Hello"
};
JSLint는 오브젝트 리터럴 표기법을 사용하는 것을 선호하지만 둘 다 같은 처리를 하는 것으로 보입니다.
어떤 것이 더 좋고 그 이유는 무엇입니까?
예시와 같이 메서드가 없는 단순한 오브젝트에는 차이가 없습니다.그러나 개체에 메서드를 추가하기 시작하면 큰 차이가 있습니다.
문자 그대로:
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
메서드를 지정합니다.반면 프로토타입 방식에서는 메서드가 객체 프로토타입에 정의되어 모든 객체 인스턴스 간에 공유됩니다.객체가 많거나 메서드가 많으면 문자 그대로 메모리 낭비가 상당히 클 수 있습니다.
두 번째는 오브젝트를 만들고 거기에 속성을 추가하는 것 이외에는 둘 다 같은 일을 합니다(다른 사람이 특이한 일을 하지 않는 한).그러나 리터럴 표기법은 소스 코드의 공간을 적게 차지합니다.무슨 일이 일어나고 있는지 분명히 알 수 있기 때문에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
하지만 (는) 실패한다{}
과가있있 있있있다다
제, 이, 이, 이, 이, 이, 이, 이, 이, in, in, in, in, in을 사용해야 할 이유가 없습니다.new Object
{}
(어느쪽이든)
JavaScript에서는 다음 두 가지 방법으로 새로운 빈 개체를 선언할 수 있습니다.
var obj1 = new Object();
var obj2 = {};
저는 이 두 사람이 이면에서 어떻게 동작하는지에 대해 큰 차이가 있다는 것을 전혀 발견하지 못했습니다(제가 틀렸다면 정정해 주세요.알고 싶습니다).그러나 두 번째 방법(개체 리터럴 표기법 사용)에는 몇 가지 이점이 있습니다.
- 길이가 짧다(정확히는 10자)
- 즉석에서 오브젝트를 작성하는 것이 보다 쉽고 구조화되어 있습니다.
- 일부 버룬이 실수로 개체를 재정의했더라도 상관 없습니다.
멤버 Name과 TelNo를 포함하는 새로운 오브젝트를 검토합니다.새로운 Object() 규칙을 사용하면 다음과 같이 작성할 수 있습니다.
var obj1 = new Object();
obj1.Name = "A Person";
obj1.TelNo = "12345";
JavaScript의 Expando Properties 기능에 의해 새로운 멤버를 즉시 작성할 수 있어 의도한 바를 달성할 수 있습니다.그러나 이 방법은 그다지 구조화되거나 캡슐화되지 않았습니다.expando 속성 및 할당 후 작성에 의존하지 않고 작성 시 멤버를 지정하려면 어떻게 해야 할까요?
여기서 오브젝트 리터럴 표기법을 사용하면 도움이 됩니다.
var obj1 = {Name:"A Person",TelNo="12345"};
이 경우 코드 한 줄에서도 동일한 효과를 달성하고 훨씬 적은 문자를 사용할 수 있습니다.
위의 오브젝트 구축 방법에 대한 자세한 내용은 JavaScript 및 객체 지향 프로그래밍(OOP)을 참조하십시오.
그리고 마지막으로, 오브젝트를 제압한 바보는?불가능하다고 생각했나요?글쎄, 이 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');
이는 다음 내용을 확장한 것입니다.ar = []이(가) ar = 새 어레이보다 빠른 이유는 무엇입니까?
출력은 다음과 같습니다.
Testing Array:
using[]: 1091ms
using new: 2286ms
Testing Object:
using{}: 870ms
using new: 5637ms
따라서 {} 및 []은(는) 빈 객체/클라이언트를 새로 만드는 것보다 더 빠릅니다.
여기 있는 모든 사람들이 그 둘의 유사점에 대해 이야기하고 있다.나는 차이점을 지적할 것이다.
「」를 사용합니다.
new Object()
를 사용하면 다른 오브젝트를 전달할 수 있습니다.그 결과 새로 생성된 오브젝트가 동일한 참조로 설정됩니다.뭇매를 맞다var obj1 = new Object(); obj1.a = 1; var obj2 = new Object(obj1); obj2.a // 1
사용량은 OOP 개체에서처럼 개체로 제한되지 않습니다.다른 유형도 여기에 전달될 수 있습니다.함수는 그에 따라 유형을 설정합니다.예를 들어 정수 1을 전달하면 유형 번호의 개체가 생성됩니다.
var obj = new Object(1); typeof obj // "number"
메서드를 ( 「」 「」 「」).
new Object(1)
는 속성이 추가되면 개체 유형으로 변환됩니다.var obj = new Object(1); typeof obj // "number" obj.a = 2; typeof obj // "object"
객체가 객체의 하위 클래스의 복사본인 경우 유형 변환 없이 속성을 추가할 수 있습니다.
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에서 개체를 만드는 방법은 여러 가지가 있습니다.오브젝트를 작성하기만 하면 "새로운" 연산자를 사용하여 "구성자 기반" 오브젝트를 작성하는 이점은 없습니다.이는 "object literal" 구문을 사용하여 개체를 만드는 것과 같습니다.그러나 "새로운" 연산자로 만들어진 "건설자 기반" 객체는 "원형 유전"을 생각할 때 매우 유용합니다.리터럴 구문을 사용하여 생성된 개체로는 상속 체인을 유지할 수 없습니다.그러나 생성자 함수를 만들고 프로토타입에 특성 및 메서드를 연결할 수 있습니다.그런 다음 "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 construction 함수를 인스턴스화함으로써 원하는 개수의 개체를 만들 수 있습니다.이러한 개체는 모두 풀네임()을 상속받습니다.
참고: "this" 키워드는 생성자 함수 내의 빈 개체를 참조하며 "new" 연산자를 사용하여 Person에서 새 개체를 만들 때마다 "this" 키워드와 함께 연결된 모든 속성 및 메서드를 포함하는 개체를 자동으로 반환합니다.그리고 이러한 오브젝트는 Person Constructor 함수의 프로토타입에 첨부된 메서드와 속성을 상속합니다(이것은 이 접근법의 주요 장점입니다).
덧붙여서 "object literal" 구문을 사용하여 동일한 기능을 가져오려면 다음과 같은 모든 개체에 대해 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 Javascript의 일부에 의하면…(인용)
오브젝트 생성자가 아닌 리터럴을 사용하는 또 다른 이유는 범위 해결이 없기 때문입니다.같은 이름의 로컬컨스트럭터를 작성했을 가능성이 있기 때문에 인터프리터는 오브젝트()를 호출하는 위치에서 글로벌오브젝트 컨스트럭터를 찾을 때까지 스코프 체인을 검색해야 합니다.
2019년 갱신
OSX High Sierra 10.13.6 노드버전 10.13.0에서 @rjloura와 같은 코드를 실행했는데 다음과 같은 결과가 나왔습니다.
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
ES6/ES2015는 ES6/ES2015입니다. 화살표 함수할 수 없습니다.단, 를 반환하려면 , 오브젝트를 「돌아가다」, 「돌아가다」, 「돌아가다」로 둘러싸야 합니다.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 } ]
가 이 컴파일러에 때문입니다.{}
괄호로 '생각'을 합니다.n: i
는 라벨:스테이트먼트 컨스트럭트입니다. 세미콜론은 옵션이기 때문에 불평하지 않습니다.
개체에 다른 속성을 추가하면 오류가 발생합니다.
$ 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 :
개체 초기화에 'new' 키를 사용할 때는 인라인 화살표 함수뿐입니다.
() => new Object({ key: value})
다음 코드가 유효하지 않기 때문에:
() => { key: value} // instead of () => { return { key: value};}
여기 좋은 답변들이 많이 있지만, 저는 제 50센트를 가지고 가고 싶습니다.
이 모든 답변이 결여되어 있는 것은 프로그래밍 언어로 여행을 시작한 지 얼마 안 된 사람에게 도움이 되는 간단한 비유입니다.
이 차이를 이 비유로 메우겠습니다.
오브젝트 리터럴 작성과 컨스트럭터 기반 구문
문장 작성으로 차이를 느껴보세요.
이 "I like cheese"
명확하고 큰 소리로 말할 수 있습니다(문자 그대로 또는 글자 그대로).나는 치즈를 좋아한다.
이것은 내가 문자 그대로 만든 문장이다.
다른 모든 방법들은 내가 정확히 어떤 문장을 만들었는지 당신에게 이해시키는 몇 가지 까다로운 방법입니다.예를 들면, 다음과 같습니다.
- 문장의 는 '아, 아, 아, 아, 아, 아, 아, 아, 아, 아, 아, 아, 아, 아, 아...
"I"
는 " " " 입니다"cheese"
는 , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , 입니다."to like"
이것은 당신이 아무런 모호함 없이 바로 같은 문장을 배울 수 있는 또 다른 방법입니다: "나는 치즈가 좋아요."
아니면...
- 제 문장은 세 단어로 구성되어 있습니다.첫 번째 단어는 영어 사전의 n번째 단어이고, 두 번째 단어는 영어 사전의 m번째 단어이고, 마지막 단어는 영어 사전의 l번째 단어입니다.
이 경우에도 같은 결과가 나옵니다.문장이 무엇인지 정확하게 알 수 있습니다.
"단어별" 문장 작성(Literal)과는 다른 간접(비문자 그대로, 비문자 그대로) 문장 작성 방법을 고안할 수 있습니다.
이것이 여기에 놓여있는 핵심 개념이라고 생각합니다.
10,000개의 인스턴스를 생성하면 메모리 사용량이 달라집니다. new Object()
1개의 카피만 보존할 수 있습니다.{}
1만부를 보관합니다.
언급URL : https://stackoverflow.com/questions/4597926/what-is-the-difference-between-new-object-and-object-literal-notation
'programing' 카테고리의 다른 글
웹 사이트 스크린샷 (0) | 2023.01.20 |
---|---|
spring-boot jpa 하이버네이션에서 4<24를 초과하면 DB로의 접속이 끊어진다. (0) | 2023.01.20 |
& & 로직 및 | 로직테이블의 True와 False (0) | 2023.01.20 |
휴지 상태: "필드 'id'에 기본값이 없습니다." (0) | 2023.01.20 |
PHP 알림을 해제하려면 어떻게 해야 합니까? (0) | 2023.01.20 |