2014-04-08 2 views
8

자바 스크립트 (What is the 'new' keyword in JavaScript?)의 "new"키워드에 대한 주제를 읽었습니다. 그러나 나는 여전히 안개 속에있다.자바 스크립트에서 키워드 "신규"의미

var foo = function() { 
    return { 
     setA: function(a) { 
      this.a = a; 
     }, 
     readA: function() { 
      console.log(this.a); 
     } 
    }; 
}; 

를 이제 코드의이 두 가지에 대해 무엇 :

하나 :

var bob1 = foo(); 
bob1.setA(10); 
bob1.readA(); 

2 :

var bob2 = new foo(); 
bob2.setA(10); 
bob2.readA(); 

내가 어떤 차이를 볼 수의이 예에 대해 이야기하자 내 수준에서. 그렇다면 "new"라는 키워드를 사용하는 게 무엇이겠습니까?

+3

관련 : [공장 기능에 대 생성자 기능 (http://stackoverflow.com/questions/8698726/constructor-function-vs-factory-functions) –

+0

내가 생각 그것과 관련이 있습니다 http://stackoverflow.com/questions/1646698/what-is-the-new-keyword-in-javascript –

+1

@ 3506238 : OP가 이미 그것을 읽었습니다. –

답변

4

함수가 객체를 직접 반환하는 경우 new 연산자가 필요하지 않습니다. new 키는 그 이상을 수행합니다.

Animal 함수의 prototype 객체의 프로토 타입 상속을 할 것입니다 다음과 같은 일

var o = Object.create(Animal.prototype) 
    Animal.apply(o, arguments); 
    return o; 

Object.create을 할 것입니다

var animal = new Animal(); 

자바 스크립트 엔진을하고

다음
function Animal(kind, name) { 
    this.kind = kind; 
    this.name = name; 
} 

Animal.prototype.walk = function() { 
    console.log('Walking'); 
} 

말할 수 있습니다 . 따라서 animal 개체는 자체 속성과 상속 된 속성을 갖게됩니다.

1

생성자 함수 foo이 객체를 반환하면 new foo()은 함수 foo()을 직접 호출하는 것과 동일합니다. 우리는 이것이 ECMAScript behavior for new 검사하여 너무 증명할 수

반환에게 호출의 결과를 ... 생성자 [즉, 생성자 함수]에 내부 방법 [[구축]을

함수의 [[Construct]] internal method은 함수의 [[Call]] 내부 메소드를 호출하기위한 특수 래퍼입니다 (이것은 단지 함수의 정상적인 동작입니다). ,

8)하자 결과가 F [new에 의해 호출 기능]의 [[전화] 내부 속성을 호출의 결과이 래퍼의 작동 방식의보고 [[Construct]]의 끝을 보자 objthis 값으로 제공하고 [[Construct]]로 전달 된 인수 목록을 args로 제공하십시오.

9) 유형 (결과)이 객체 인 경우 결과는입니다.

10) Return obj.귀하의 경우에는

, 생성자의 객체를 반환 foo 기능, 그래서 [[Construct]]의 9 단계는 (따라서, 회전, new foo()에서) 그 객체를 반환합니다. 그러나 10 단계에서 [[Construct]]은 obj이라는 다른 값을 반환하며 이는 생성자 내부의 this 값과 같습니다. 의 되감기 및 그 모든에 대해 무엇을 보자 :

1) OBJ 새로 만든 원본 인 ECMAScript 객체하자.

...

4)하자 프로토 인수 "prototype"와 F의 [위젯] 내부 호출 속성의 값. 유형 (프로토)의 객체 인 경우

5) 프로토OBJ의 [원형] 내부 속성을 설정.

가 여기에 우리가 new의 진정한 힘을 참조 : 생성자 함수는 객체 (따라서 new에 의해 발사 [[Construct]] 작업이 obj를 반환 할 수있다)을 반환하지 않는 경우, 다음 프로토 타입 상속이 일어난다. [[Prototype]]obj (a.k.a. obj.__proto__)은 생성자 메서드의 prototype 속성으로 설정됩니다. 즉, foo이 객체를 반환하지 않고 대신 this을 수정하고 foo.prototype.someProp이 설정된 경우 var instance = new foo()에서 반환 된 인스턴스는 instance.someProp에 액세스 할 수 있습니다.

따라서, 코드를 작성하는 다른 방법으로는 다음과 같을 수 있습니다 foo()하지 않는 동안

이 경우
var foo = function() { }; 
foo.prototype.setA = function(a) { this.a = a; }; 
foo.prototype.setA = function(a) { console.log(this.a); }; 

, new foo()는 누구의 프로토 타입 체인 foo.prototype을 포함하는 객체를 생성합니다. 이것은 메모리 사용의 이점을 가지고 있습니다. 모든 foo 인스턴스는 각 인스턴스가 고유 한 별도의 기능을 수행하는 대신 일반적인 프로토 타입 메소드를 공유합니다.

3

나는 여전히 안개에 약 new입니다. 의이 예에 대해 이야기하자

var foo = function() { 
    return { 
     setA: function(a) { 
      this.a = a; 
     }, 
     readA: function() { 
      console.log(this.a); 
     } 
    }; 
}; 

우리는이 예제에 대해 이야기해서는 안된다. 여부 때문에 우리 the way new works의, 변화를하지 않는이 기능을 new를 사용

  1. 새로운 객체가 생성, foo.prototype에서 상속.
  2. 지정된 인수로 생성자 함수 foo이 호출되고 새로 작성된 개체가 this bound to 입니다.
  3. 생성자 함수에 의해 반환 된 객체는 전체 새 표현식의 결과 인 이됩니다. 생성자 함수가 개체를 명시 적으로 반환하지 않으면 1 단계에서 만든 개체가 대신 사용됩니다. (일반적으로 생성자는 값을 반환하지 않는, 그러나 일반 객체 생성 과정을 무시하려는 경우 그들은 그렇게 할 수 있습니다.)

3 단계는 여기에서 볼 수있는 일이다. 객체 (객체 리터럴)를 만들고 반환하면 bob1에 할당됩니다. 일반적으로 생성자 함수는 return이 아니며 step1에서 암시 적으로 작성된 새 인스턴스 (함수 내에서 this로 사용 가능)가 결과가됩니다.

new foo()foo()은 모두 객체 리터럴을 bob 변수에만 할당합니다. 결과에는 차이가 없습니다. new에 의해 생성 된 인스턴스는 코드에서 완전히 무시됩니다. 그것은 다음의 예에서 다른 것 :

function foo() { 
    this.setA = function(a) { 
     this.a = a; 
    }; 
    this.readA = function() { 
     console.log(this.a); 
    }; 
    // return this; is implicit 
} 
var bob = new foo; // OK 
var bob = foo(); // horrible error 
관련 문제