etc./StackOverFlow

JavaScript에서 'new' 키워드는 무엇입니까?

청렴결백한 만능 재주꾼 2021. 12. 28. 01:51
반응형

질문자 :Alon Gubkin


JavaScript의 new 키워드는 처음 접했을 때 상당히 혼란스러울 수 있습니다. 사람들은 JavaScript가 객체 지향 프로그래밍 언어가 아니라고 생각하는 경향이 있기 때문입니다.

  • 그것은 무엇입니까?
  • 어떤 문제를 해결합니까?
  • 언제가 적절하고 언제가 적절하지 않습니까?


5가지 작업을 수행합니다.

  1. 새로운 객체를 생성합니다. 이 객체의 유형은 단순히 object 입니다.
  2. 이 새로운 객체의 내부, 접근 불가, [[prototype]] (즉, __proto__ ) 속성을 생성자 함수의 외부 접근 가능한 프로토타입 객체로 설정합니다(모든 함수 객체는 자동으로 프로토타입 속성을 가집니다).
  3. this 변수가 새로 생성된 객체를 가리키도록 합니다.
  4. 이 때마다 새롭게 생성 된 객체 사용 생성자 함수 실행 this 언급된다.
  5. null 이 아닌 객체 참조를 반환하지 않는 한 새로 생성된 객체를 반환합니다. 이 경우 해당 개체 참조가 대신 반환됩니다.

참고: 생성자 함수 는 다음과 같이 new 키워드 뒤의 함수를 참조합니다.

 new ConstructorFunction(arg1, arg2)

이 작업이 완료되면 새 개체의 정의되지 않은 속성이 요청되면 스크립트는 대신 속성에 대해 개체의 [[prototype]] 개체를 확인합니다. 이것이 JavaScript에서 전통적인 클래스 상속과 유사한 것을 얻을 수 있는 방법입니다.

여기서 가장 어려운 부분은 2번 포인트입니다. 모든 객체(함수 포함)에는 [[prototype]] 이라는 내부 속성이 있습니다. new , Object.create 또는 리터럴(함수는 기본적으로 Function.prototype, 숫자는 Number.prototype 등)을 기반으로 개체 생성 시 에만 설정할 수 있습니다. Object.getPrototypeOf(someObject) 로만 읽을 수 있습니다. 이 값을 설정하거나 읽는 다른 방법은 없습니다.

함수에는 숨겨진 [[prototype]] 속성 외에도 prototype 이라는 속성이 있으며 이 속성을 사용하여 액세스하고 수정할 수 있어 생성한 객체에 상속된 속성과 메서드를 제공할 수 있습니다.


다음은 예입니다.

 ObjMaker = function() {this.a = 'first';}; // ObjMaker is just a function, there's nothing special about it that makes // it a constructor. ObjMaker.prototype.b = 'second'; // like all functions, ObjMaker has an accessible prototype property that // we can alter. I just added a property called 'b' to it. Like // all objects, ObjMaker also has an inaccessible [[prototype]] property // that we can't do anything with obj1 = new ObjMaker(); // 3 things just happened. // A new, empty object was created called obj1. At first obj1 was the same // as {}. The [[prototype]] property of obj1 was then set to the current // object value of the ObjMaker.prototype (if ObjMaker.prototype is later // assigned a new object value, obj1's [[prototype]] will not change, but you // can alter the properties of ObjMaker.prototype to add to both the // prototype and [[prototype]]). The ObjMaker function was executed, with // obj1 in place of this... so obj1.a was set to 'first'. obj1.a; // returns 'first' obj1.b; // obj1 doesn't have a property called 'b', so JavaScript checks // its [[prototype]]. Its [[prototype]] is the same as ObjMaker.prototype // ObjMaker.prototype has a property called 'b' with value 'second' // returns 'second'

new ObjMaker() 사용하여 만드는 모든 객체는 'b' 속성을 상속받은 것처럼 보이기 때문에 클래스 상속과 같습니다.

하위 클래스와 같은 것을 원하면 다음을 수행하십시오.

 SubObjMaker = function () {}; SubObjMaker.prototype = new ObjMaker(); // note: this pattern is deprecated! // Because we used 'new', the [[prototype]] property of SubObjMaker.prototype // is now set to the object value of ObjMaker.prototype. // The modern way to do this is with Object.create(), which was added in ECMAScript 5: // SubObjMaker.prototype = Object.create(ObjMaker.prototype); SubObjMaker.prototype.c = 'third'; obj2 = new SubObjMaker(); // [[prototype]] property of obj2 is now set to SubObjMaker.prototype // Remember that the [[prototype]] property of SubObjMaker.prototype // is ObjMaker.prototype. So now obj2 has a prototype chain! // obj2 ---> SubObjMaker.prototype ---> ObjMaker.prototype obj2.c; // returns 'third', from SubObjMaker.prototype obj2.b; // returns 'second', from ObjMaker.prototype obj2.a; // returns 'first', from SubObjMaker.prototype, because SubObjMaker.prototype // was created with the ObjMaker function, which assigned a for us

나는 마침내 이 페이지를 찾기 전에 이 주제에 관한 수많은 쓰레기를 읽었습니다. 여기에서 이것은 멋진 다이어그램으로 아주 잘 설명되어 있습니다.


Community Wiki

다음 기능이 있다고 가정합니다.

 var Foo = function(){ this.A = 1; this.B = 2; };

이것을 다음과 같이 독립형 함수로 호출하면:

 Foo();

window 객체( AB )에 두 개의 속성이 추가됩니다. 그것은에 추가 window 때문에 window 당신이 그런 식으로 실행할 때 함수를 호출 한 객체이며, this 함수에서이 함수를 호출 한 개체입니다. 적어도 자바스크립트에서는.

new 다음과 같이 호출하십시오.

 var bar = new Foo();

함수 호출에 new 를 추가하면 새 객체가 생성되고(단지 var bar = new Object() ) this 가 호출한 객체 대신 방금 생성 Object 를 가리킵니다. 함수. 따라서 bar 는 이제 속성 AB 가진 객체입니다. 모든 함수는 생성자가 될 수 있지만 항상 의미가 있는 것은 아닙니다.


JulianR

Daniel Howard의 답변 외에도 다음은 new 가 수행하는 것(또는 최소한 수행하는 것으로 보이는 것)입니다.

 function New(func) { var res = {}; if (func.prototype !== null) { res.__proto__ = func.prototype; } var ret = func.apply(res, Array.prototype.slice.call(arguments, 1)); if ((typeof ret === "object" || typeof ret === "function") && ret !== null) { return ret; } return res; }

하는 동안

 var obj = New(A, 1, 2);

와 동등하다

 var obj = new A(1, 2);

basilikum

초보자가 더 잘 이해할 수 있도록

브라우저 콘솔에서 다음 코드를 시도하십시오.

 function Foo() { return this; } var a = Foo(); //returns window object var b = new Foo(); //returns empty object of foo a instanceof Window; // true a instanceof Foo; // false b instanceof Window; // false b instanceof Foo; // true

이제 커뮤니티 위키 답변을 읽을 수 있습니다. :)


Anulal S

그래서 아마도 객체의 인스턴스를 생성하기 위한 것이 아닐 것입니다.

그것은 바로 그것을 위해 사용됩니다. 다음과 같이 함수 생성자를 정의합니다.

 function Person(name) { this.name = name; } var john = new Person('John');

그러나 ECMAScript의 추가 이점은 .prototype 속성으로 확장할 수 있으므로 다음과 같은 작업을 수행할 수 있다는 것입니다.

 Person.prototype.getName = function() { return this.name; }

이 생성자에서 생성된 모든 객체는 액세스할 수 있는 프로토타입 체인으로 인해 getName


meder omuraliev

JavaScript 객체 지향 프로그래밍 언어이며 인스턴스 생성에 정확히 사용됩니다. 클래스 기반이 아니라 프로토타입 기반이지만 객체 지향이 아니라는 의미는 아닙니다.


Michael

요약:

new 키워드는 자바스크립트에서 생성자 함수에서 객체를 생성하는 데 사용됩니다. new 키워드는 생성자 함수 호출 전에 위치해야 하며 다음 작업을 수행합니다.

  1. 새 개체를 만듭니다.
  2. 이 객체의 프로토타입을 생성자 함수의 프로토타입 속성으로 설정합니다.
  3. this 키워드를 새로 생성된 객체에 바인딩하고 생성자 함수를 실행합니다.
  4. 새로 생성된 객체를 반환

예시:

 function Dog (age) { this.age = age; } const doggie = new Dog(12); console.log(doggie); console.log(Object.getPrototypeOf(doggie) === Dog.prototype) // true

정확히 어떤 일이 발생합니까?

  1. const doggie 는 다음과 같이 말합니다. 변수 선언을 위한 메모리가 필요합니다.
  2. 할당 연산자 = = 뒤에 있는 표현식으로 이 변수를 초기화할 것입니다.
  3. 표현식은 new Dog(12) 입니다. JS 엔진은 new 키워드를 보고 새 객체를 만들고 프로토타입을 Dog.prototype으로 설정합니다.
  4. 생성자 함수는 this 값을 새 객체로 설정하여 실행됩니다. 이 단계에서는 새로 생성된 강아지 개체에 연령을 할당합니다.
  5. 새로 생성된 객체가 반환되어 doggie 변수에 할당됩니다.

Willem van der Veen

이 매우 큰 응답은 이미하지만 난 당신이 당신이 함수에 명시 적 return 문이있을 때 일어나는 일에 대해 아래의 경우 III에 내 관찰을 강조하기 위해 새 게시하도록하겠습니다 new 까지 보내고있다. 아래의 경우를 살펴보십시오.

사례 I :

 var Foo = function(){ this.A = 1; this.B = 2; }; console.log(Foo()); //prints undefined console.log(window.A); //prints 1

Foo 가리키는 익명 함수를 호출하는 일반적인 경우입니다. 이 함수를 호출하면 undefined 반환합니다. 명시적인 return 문이 없기 때문에 JavaScript 인터프리터는 return undefined; 함수의 끝에 있는 문. AB 속성을 가져오는 호출 객체(문맥적 this

사례 II :

 var Foo = function(){ this.A = 1; this.B = 2; }; var bar = new Foo(); console.log(bar()); //illegal isn't pointing to a function but an object console.log(bar.A); //prints 1

new 키워드를 보는 JavaScript 인터프리터 Foo 가리키는 익명 함수 this ) 역할을 하는 새 객체를 생성합니다. 이 경우 AB 는 새로 생성된 객체의 속성이 됩니다(창 객체 대신). new 키워드 사용으로 인해 생성된 새 객체를 반환하기 위해 return 문을 강제로 삽입합니다.

사례 III :

 var Foo = function(){ this.A = 1; this.B = 2; return {C:20,D:30}; }; var bar = new Foo(); console.log(bar.C);//prints 20 console.log(bar.A); //prints undefined. bar is not pointing to the object which got created due to new keyword.

new 키워드를 보는 JavaScript 인터프리터 Foo 가리키는 익명 함수 this ) 역할을 하는 새 객체를 생성합니다. 다시 AB 는 새로 생성된 객체의 속성이 됩니다. 그러나 이번에는 명시적인 return 문이 있으므로 JavaScript 인터프리터는 자체적으로 아무 것도 하지 않습니다.

Case III 에서 주의할 점은 new 키워드로 인해 생성되는 객체가 레이더에서 사라졌다는 것입니다. bar new 키워드로 인해 JavaScript 인터프리터가 생성한 객체가 아닌 완전히 다른 객체를 가리키고 있습니다.

JavaScripit: The Definitive Guide(6판), Ch.의 David Flanagan 인용. 4, 페이지 번호 62:

객체 생성 표현식이 평가될 때 JavaScript는 객체 이니셜라이저 {}에 의해 생성된 것과 마찬가지로 먼저 비어 있는 새 객체를 생성합니다. 그런 다음 지정된 인수를 사용하여 지정된 함수를 호출하고 새 객체를 this 키워드의 값으로 전달합니다. 그런 다음 함수는 이를 사용하여 새로 생성된 객체의 속성을 초기화할 수 있습니다. 생성자로 사용하기 위해 작성된 함수는 값을 반환하지 않으며, 객체 생성 표현식의 값은 새로 생성되어 초기화된 객체이다. 생성자가 객체 값을 반환하는 경우 해당 값은 객체 생성 표현식의 값이 되고 새로 생성된 객체는 버려집니다.

--- 추가 정보 ---

위의 경우의 코드 스니펫에 사용된 함수는 JS 세계에서 아래와 같은 특수 이름을 가집니다.

사례 I 및 II - 생성자 함수

사례 III - 공장 기능. 팩토리 함수 현재 스레드에서 개념을 설명하기 위해 수행한 new 키워드와 함께 사용하면 안 됩니다.

스레드에서 차이점에 대해 읽을 수 있습니다.


RBT

Javascript는 객체 지향 프로그래밍 패러다임을 지원하는 동적 프로그래밍 언어로, 객체의 새로운 인스턴스를 생성하는 데 사용됩니다.

객체에는 클래스가 필요하지 않습니다. Javascript는 프로토타입 기반 언어입니다.


Greg

new 키워드는 함수가 실행되는 컨텍스트를 변경하고 해당 컨텍스트에 대한 포인터를 반환합니다.

new 키워드를 사용하지 않는 경우 Vehicle() 함수가 실행되는 컨텍스트는 Vehicle 함수를 호출하는 컨텍스트와 동일합니다. this 키워드는 동일한 컨텍스트를 참조합니다. new Vehicle() 을 사용하면 새 컨텍스트가 생성되어 this 키워드가 새 컨텍스트를 참조합니다. 그 대가로 얻는 것은 새로 생성된 컨텍스트입니다.


Juzer Ali

때로는 코드가 말보다 쉽습니다.

 var func1 = function (x) { this.x = x; } // used with 'new' only var func2 = function (x) { var z={}; zx = x; return z; } // used both ways func1.prototype.y = 11; func2.prototype.y = 12; A1 = new func1(1); // has A1.x AND A1.y A2 = func1(1); // undefined ('this' refers to 'window') B1 = new func2(2); // has B1.x ONLY B2 = func2(2); // has B2.x ONLY

프로토타입을 만들지 않는 한 func2 스타일을 사용하면 함수 내부와 외부에서 좀 더 유연하게 사용할 수 있습니다.


rsbkk

 " Every object (including functions) has this internal property called [[prototype]]"

모든 함수에는 해당 함수로 생성된 객체의 프로토타입으로 자동 설정되는 프로토타입 객체가 있습니다.

당신은 쉽게 확인할 수 있습니다:

 const a = { name: "something" }; console.log(a.prototype); // undefined because it is not directly accessible const b = function () { console.log("somethign");}; console.log(b.prototype); // returns b {}

그러나 모든 함수와 객체에는 해당 객체 또는 함수의 프로토타입을 가리키는 __proto__ __proto__prototype 은 2개의 다른 용어입니다. 나는 우리가이 댓글을 만들 수 있다고 생각 : "모든 객체는 프로토를 통해 프로토 타입에 연결되어"그러나 __proto__ 자바 스크립트에 존재하지 않습니다. 이 속성은 디버깅을 돕기 위해 브라우저에 의해 추가됩니다.

 console.log(a.__proto__); // returns {} console.log(b.__proto__); // returns [Function]

터미널에서 쉽게 확인할 수 있습니다. 그렇다면 생성자 함수는 무엇입니까?

 function CreateObject(name,age){ this.name=name; this.age =age }

먼저 주의해야 할 5가지:

new 생성자 함수를 호출하면 함수의 내부 [[Construct]] 메서드가 호출되어 새 인스턴스 개체를 만들고 메모리를 할당합니다.

2- 우리는 return 키워드를 사용하지 않습니다. new 가 처리합니다.

3- 함수 이름은 대문자로 표시되므로 개발자가 코드를 볼 때 new 키워드를 사용해야 한다는 것을 이해할 수 있습니다.

4- 화살표 기능을 사용하지 않습니다. this 매개변수의 값은 "창"인 화살표 기능이 생성되는 순간 선택되기 때문입니다. 화살표 함수는 동적으로 범위가 지정되지 않고 어휘 범위가 지정됩니다. 여기에서 사전적으로는 지역적으로 의미합니다. 화살표 함수는 로컬 "this" 값을 전달합니다.

5- 일반 함수와 달리 화살표 함수는 [[Construct]] 메서드가 없기 때문에 new 키워드로 호출할 수 없습니다. 화살표 함수에는 프로토타입 속성도 존재하지 않습니다.

 const me=new CreateObject("yilmaz","21")

new 는 함수를 호출한 다음 빈 객체 {}를 생성한 다음 "name" 값으로 "name" 키를 추가하고 인수 "age" 값으로 "age" 키를 추가합니다.

함수를 호출할 때 "this" 및 "arguments"로 새 실행 컨텍스트가 생성되기 때문에 "new"가 이러한 인수에 액세스할 수 있습니다.

기본적으로 생성자 함수 내부의 this는 "window" 객체를 가리키지만 new 는 이를 변경합니다. "this"는 생성된 빈 객체 {}를 가리키고 새로 생성된 객체에 속성이 추가됩니다. "this" 속성 없이 정의된 변수가 있는 경우 개체에 추가되지 않습니다.

 function CreateObject(name,age){ this.name=name; this.age =age; const myJob="developer" }

myJob 속성은 새로 생성된 객체를 참조하는 것이 없기 때문에 객체에 추가되지 않습니다.

 const me= {name:"yilmaz",age:21} // there is no myJob key

처음에는 모든 함수에 생성자 함수를 포함한 "프로토타입" 속성이 있다고 말했습니다. 생성자의 프로토타입에 메서드를 추가할 수 있으므로 해당 함수에서 생성된 모든 객체가 액세스할 수 있습니다.

 CreateObject.prototype.myActions=function(){ //define something}

이제 "me" 개체는 "myActions" 메서드를 사용할 수 있습니다.

자바 스크립트에는 내장 생성자 함수가 있습니다: Function,Boolean,Number,String..

내가 만들면

 const a = new Number(5); console.log(a); // [Number: 5] console.log(typeof a); // object

new 를 사용하여 생성된 모든 것은 객체 유형이 있습니다. 이제 "a"는 Number.prototype 내부에 저장된 모든 메소드에 액세스할 수 있습니다. 내가 정의한다면

 const b = 5; console.log(a === b);//false

a와 b는 5이지만 객체이고 b는 원시적입니다. b는 원시 유형이지만 생성될 때 javascript는 자동으로 이를 Number()로 래핑하므로 b는 Number.prototype 내부의 모든 메소드에 액세스할 수 있습니다.

생성자 함수는 속성과 메서드가 같은 유사한 객체를 여러 개 생성하려는 경우에 유용합니다. 그렇게 하면 코드가 더 효율적으로 실행될 수 있도록 추가 메모리를 할당하지 않습니다.


Yilmaz

new 키워드는 새 개체 인스턴스를 만들기 위한 것입니다. 그리고 예, javascript는 객체 지향 프로그래밍 패러다임을 지원하는 동적 프로그래밍 언어입니다. 개체 이름 지정에 대한 규칙은 new 키워드로 인스턴스화해야 하는 개체에 항상 대문자를 사용하는 것입니다.

 obj = new Element();

erenon

new 키워드는 함수를 생성자로 사용하여 개체의 인스턴스를 만듭니다. 예를 들어:

 var Foo = function() {}; Foo.prototype.bar = 'bar'; var foo = new Foo(); foo instanceof Foo; // true

인스턴스는 생성자 함수 prototype 에서 상속됩니다. 그래서 위의 예를 들자면...

 foo.bar; // 'bar'

eyelidlessness

자바스크립트는 객체지향 프로그래밍(OOP) 언어가 아니므로 자바스크립트 의 LOOK UP 프로세스는 프로토타입 위임 또는 프로토타입 상속이라고도 하는 'DELEGATION PROCESS'를 사용하여 작동합니다.

가지고 있지 않은 객체에서 속성 값을 얻으려고 하면 JavaScript 엔진은 객체의 프로토타입(및 프로토타입, 한 번에 한 단계 위)을 찾습니다. 체인이 null이 될 때까지 프로토타입 체인입니다. Object.prototype == null (표준 개체 프로토타입)입니다. 이 시점에서 정의되지 않은 것보다 속성이나 메서드가 정의 되지 않은 경우 가 반환됩니다.

따라서 new 키워드를 사용하여 수동으로 수행한 작업 중 일부 예를 들면

  1. 수동 개체 생성(예: newObj).
  2. JS 사양 [[prototype]] (ie proto ) 에서 proto (일명: dunder proto )를 사용하여 숨겨진 채권 생성
  3. newObj 속성 참조 및 할당
  4. newObj 객체의 반환.

모두 수동으로 수행됩니다.

 function CreateObj(value1, value2) { const newObj = {}; newObj.property1 = value1; newObj.property2 = value2; return newObj; } var obj = CreateObj(10,20); obj.__proto__ === Object.prototype; // true Object.getPrototypeOf(obj) === Object.prototype // true

Javascript 키워드 new 이 프로세스를 자동화하는 데 도움이 됩니다.

  1. 다음으로 식별되는 새 객체 리터럴이 생성됩니다 this:{}
  2. 참조 및 할당 특성 this
  3. Function.prototype 공유 공간에 대한 숨겨진 결합 생성 [[prototype]](즉, proto ).
  4. this 객체의 암시적 반환 {}
 function CreateObj(value1, value2) { this.property1 = value1; this.property2 = value2; } var obj = new CreateObj(10,20); obj.__proto__ === CreateObj.prototype // true Object.getPrototypeOf(obj) == CreateObj.prototype // true

새 키워드 없이 생성자 함수 호출:

=> this: Window

 function CreateObj(value1, value2) { var isWindowObj = this === window; console.log("Is Pointing to Window Object", isWindowObj); this.property1 = value1; this.property2 = value2; } var obj = new CreateObj(10,20); // Is Pointing to Window Object false var obj = CreateObj(10,20); // Is Pointing to Window Object true window.property1; // 10 window.property2; // 20

khizer

si 당 JavaScript는 항상 원래 사양 EcmaScript의 구현이므로 플랫폼마다 크게 다를 수 있습니다.

어쨌든 EcmaScript 사양을 따르는 모든 JavaScript 구현은 구현과 별개로 객체 지향 언어를 제공합니다. ES 표준에 따르면:

ECMAScript는 호스트 환경 내에서 계산을 수행하고 계산 객체를 조작하기 위한 객체 지향 프로그래밍 언어입니다.

이제 JavaScript가 EcmaScript의 구현이고 따라서 객체 지향 언어라는 데 동의했습니다. new 작업의 정의는 이러한 키워드가 특정 유형(C#과 같은 경우 익명 유형 포함)의 클래스에서 객체 인스턴스를 만드는 데 사용된다고 말합니다.

사양에서 읽을 수 있듯이 EcmaScript에서는 클래스를 사용하지 않습니다.

ECMAScript는 C++, Smalltalk 또는 Java와 같은 클래스를 사용하지 않습니다. 대신 객체는 리터럴 표기법을 통해 또는 객체를 생성한 다음 속성에 초기 값을 할당하여 전체 또는 일부를 초기화하는 코드를 실행하는 생성자를 포함하여 다양한 방법으로 생성될 수 있습니다. 각 생성자는 프로토타입 기반 상속 및 공유 속성을 구현하는 데 사용되는 ― 프로토타입 ‖이라는 속성을 가진 함수입니다. 객체는 다음에 의해 생성됩니다.
새로운 표현식에서 생성자 사용하기; 예를 들어, new Date(2009,11)는 새 Date 객체를 생성합니다. new를 사용하지 않고 생성자를 호출하면 생성자에 따라 결과가 달라집니다. 예를 들어, Date()는 객체가 아닌 현재 날짜 및 시간의 문자열 표현을 생성합니다.


João Pinho

출처 : http:www.stackoverflow.com/questions/1646698/what-is-the-new-keyword-in-javascript

반응형