2013-12-14 3 views
0

에서이 키워드를 사용하는 것이 올바른 코드 1과 코드 2를 비교하는 이유는 무엇입니까?생성자 함수

function Rectangle(height, width) { 
    this.height = height; 
    this.width = width; 
    this.calcArea = function() { // why use this here? 
     return this.height * this.width; 
    }; 

} 

코드 2 는 내가이와 괜찮아 생각 :

function Rectangle(height, width) { 
     this.height = height; 
     this.width = width; 
     calcArea = function() { 
      return this.height * this.width; 
     }; 

    } 
+2

첫 번째 스 니펫에서 'calcArea'는'new Rectangle()'에 의해 생성 된'Rectangle'의 속성입니다. 두 번째 스 니펫에서'calcArea'는 전역 변수입니다. –

+0

@ChrisMartin 글로벌인지 확인하려면 어떻게해야합니까? – thefourtheye

+0

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Values,_variables,_and_literals, 특히 "선언 변수"섹션을 읽어보십시오. –

답변

1

당신이 this, calcArea이 Rectangle의 개체를 통해 액세스 할 수 없습니다 사용하지 않는 경우. 당신이 말할 때,

this.calcArea = function() ... 

당신은 객체가에 액세스 할 수 있도록 현재의 오브젝트 ( this)와 기능에 새로운 변수가 할당됩니다 만들 수 있습니다.

this의 유무에 관계없이 다음 문장을 시도해보십시오. 너는 더 잘 이해할 것이다.

var a = new Rectangle(1, 2); 
console.log(a.calcArea()); 
+0

'this.calcArea = function() ...'을 사용하면'Rectangle' 클래스의 인스턴스에 첨부 된 속성을 생성 할 것입니다. 그래서 10,000 개의'Rectangle' 인스턴스를 생성한다면 10,000 개의'calcArea '함수. 해야 할 일은 클래스의 프로토 타입에 멤버 함수를 첨부하는 것입니다 : function Rectangle (w, h) {this.setWidth (w); this.setHeight (h);}; Rectangle.prototype.setWidth = function (w) {this.width = w;}; Rectangle.prototype.setHeight = function (h) {this.height = h;}; Rectangle.prototype.calcArea = function() {return this.width * this.height;}; ' – MT0

+0

@ MT0 OP는'this'가 왜 거기에 사용되는지 알고 싶었습니다. – thefourtheye

+0

OP는 "올바른지 알고 싶습니까?" – MT0

0

두 번째 버전에서는 전역 변수 인 calcArea가 개체 인스턴스가 생성 될 때마다 개체 별 항목을 수행하도록 설정합니다. 이것의 사용은 특정 객체의 속성을 설정하는 데 필요합니다.

0

생성자에서 'this'를 사용하여 메서드 및 속성을 시작하면 해당 생성자로 만든 새 객체가 해당 속성 및 메서드를 사용하고 해당 속성 및 메서드 이 새로 작성된 개체을 가리킬 수 있습니다.

당신은 '이'calcArea에 서문으로 사용하고 다음과 같은 오류 얻을 크롬 디버거에 보이지 않는 사각형 생성자의 버전을 기반으로 새 개체를 만드는 경우 :

Object #<Rectangle> has no method 'calcArea' 

을 즉, 단순히 인식되지 않습니다.

"this"를 사용하지 않는 다른 측면은이 방법이 '글로벌'이된다는 것입니다. 여기

코드 예제 입증하는 것입니다

function Rectangle(height, width) { 
    this.height = height; 
    this.width = width; 
    calcArea = function() { // Not prefaced with 'this' 
     return 'hello world'; 
    }; 

} 


var aNewObj = new Rectangle(10,10); 

console.log(calcArea()) // Notice this is not aNewObj.calcArea() ...just calcArea() but its still accessible. 
1

which one is correct?

이것은 당신이 "올바른"보는 방법에 따라 달라집니다

  • 두 선언은 올바르게 구문 분석 할 실패 할 것인가?
    • 아니요, 둘 다 유효한 JavaScript입니다.
  • 어느 것이 계산할 것인가 calcArea?
    • 코드 1은 올바르게 계산하고 코드 2는 Rectangle 클래스의 멤버 함수를 만들지 않지만 어려움 광고 리디렉션으로 올바르게 계산할 수 있습니다. 아래를 참조하십시오.
  • 클래스를 만드는 좋은 사례가 있습니까?
    • 아니요, 둘 중 어느 것도 아닙니다. 하단을 참조하십시오.

코드 1-calcArea()

당신은 다음 코드 1의 Rectangle의 새 인스턴스를 만들 경우

function Rectangle(height, width) { 
    this.height = height; 
    this.width = width; 
    this.calcArea = function() { // why use this here? 
     return this.height * this.width; 
    };  
} 

var rect = new Rectangle(3, 4); 
console.log(rect.calcArea()); 

윌 정확하게 출력 12

코드 2 -TypeError: rect.calcArea is not a function

calcArea 대신, 전역에 부착 그래서 우리는 할 수있다 :

function Rectangle(height, width) { 
    this.height = height; 
    this.width = width; 
    calcArea = function() { 
     return this.height * this.width; 
    }; 
} 

var rect = new Rectangle(3, 4); 
console.log(rect.calcArea()); 

이 오류가 발생합니다 : 당신이 다음 코드 2의 Rectangle의 새 인스턴스를 만들 경우

do :

console.log (calcArea()); 전역 범위의 일부 calcArea으로

윌 출력 NaN은 그래서 Rectangle 클래스의 인스턴스에 대한 지식이없고 전역는 height 또는 width 속성이 없습니다.

우리가 할 경우

var rect = new Rectangle(3, 4); 
width = 7; // Set in the global scope. 
height = 10; // Set in the global scope. 
console.log(calcArea()); 

는 그런 다음 ( calcArea(), this 참조 전역이 아닌 rect 객체 내에서, 이후가 아니라 12) 70를 반환합니다.

우리가 this 함수를 호출 할 .call()를 사용하여 말합 무엇을 변경하는 경우 :

var rect = new Rectangle(3, 4); 
width = 7; // Set in the global scope. 
height = 10; // Set in the global scope. 
console.log(calcArea.call(rect)); 

그 다음을 출력 12 (this 이제 전역 rect 객체와하지를 의미하기 때문에).

calcArea()을 사용할 때마다이 작업을 수행하지 않아도됩니다.

코드 1

코드 1이 작동 최적은 아니지만 새 Rectangle 개체를 만들 때마다 그것과는 다른 기능입니다 해당 개체의 calcArea 속성을 만들 수 있기 때문에 최적의 솔루션이 아닙니다 왜 임의의 Rectangle 오브젝트의 임의의 calcArea 속성

당신은 당신이 할 경우이를 볼 수 있습니다

기능이 동일한 지 테스트 할 때 출력 true 기능의 문자열 표현을 테스트 동일하지만 false
function Rectangle(height, width) { 
    this.height = height; 
    this.width = width; 
    this.calcArea = function() { // why use this here? 
     return this.height * this.width; 
    };  
} 

var r1 = new Rectangle(3, 4), 
    r2 = new Rectangle(6, 7); 

console.log(r1.calcArea.toString() === r2.calcArea.toString()); // Line 1 
console.log(r1.calcArea === r2.calcArea);      // Line 2 

.

이것은 무엇을 의미합니까? 10,000 인스턴스의 Rectangle을 생성하면 calcArea 속성의 10,000 개의 인스턴스가 추가됩니다. 각 복사본에는 추가 메모리가 필요합니다 (더하여 해당 메모리를 할당하고 마지막에 가비지 수집 할 시간이 더 필요합니다).

더 나은 방법은 무엇입니까?

function Rectangle(height, width) { 
     this.setHeight(height); 
     this.setWidth(width); 
} 
Rectangle.prototype.setHeight = function(height){ this.height = height; } 
Rectangle.prototype.setWidth = function(width ){ this.width = width; } 
Rectangle.prototype.calcArea = function(){ return this.height * this.width; } 

당신이 그런 경우 : 그것은 모두 true를 반환합니다

var r1 = new Rectangle(3, 4), 
    r2 = new Rectangle(6, 7); 

console.log(r1.calcArea.toString() === r2.calcArea.toString()); // Line 1 
console.log(r1.calcArea === r2.calcArea);      // Line 2 

-r1.calcArear2.calcAreaRectangle의 인스턴스 수에 관계없이 동일한 기능을 참조 것을 의미한다.

+0

메모리 관리! thx 너무 많은 팁! – user3057928