글로벌 네임 스페이스가 오염된다는 것은 무엇을 의미합니까?


92

글로벌 네임 스페이스가 오염된다는 것은 무엇을 의미합니까?

나는 오염되는 글로벌 네임 스페이스가 무엇을 의미하는지 정말로 이해하지 못한다.


1
향후 참조를위한 링크 : JavaScript 네임 스페이스 선언
blong

답변:


124

가비지 수집에 대한 빠른 참고 사항

변수가 범위를 잃으면 가비지 수집 대상이됩니다. 전역으로 범위가 지정된 경우 전역 네임 스페이스가 범위를 잃을 때까지 컬렉션에 적합하지 않습니다.

예를 들면 다음과 같습니다.

var arra = [];
for (var i = 0; i < 2003000; i++) {
 arra.push(i * i + i);
}

이것을 글로벌 네임 스페이스 (적어도 나를 위해)에 추가하면 수집되지 않는 10,000kb의 메모리 사용량 (win7 firefox)이 추가되어야합니다. 다른 브라우저에서는이를 다르게 처리 할 수 ​​있습니다.

다음과 같이 범위를 벗어나는 범위에 동일한 코드가있는 반면 :

(function(){
 var arra = [];
 for (var i = 0; i < 2003000; i++) {
  arra.push(i * i + i);
 }
})();

arra클로저가 실행 된 후 범위를 잃을 수 있으며 가비지 수집에 적합합니다.

글로벌 네임 스페이스는 당신의 친구입니다

글로벌 네임 스페이스 사용에 대한 많은 주장에도 불구하고 그것은 당신의 친구입니다. 좋은 친구처럼 관계를 남용해서는 안됩니다.

부드럽게

전역 네임 스페이스를 남용 (일반적으로 "오염"이라고 함)하지 마십시오. 그리고 내가 의미하는 바는 전역 네임 스페이스를 남용하지 말라는 것입니다. 여러 전역 변수를 만들지 마십시오. 다음은 글로벌 네임 스페이스를 사용 하는 나쁜 예입니다.

var x1 = 5;
var x2 = 20;
var y1 = 3
var y2 = 16;

var rise = y2 - y1;
var run = x2 - x1;

var slope = rise / run;

var risesquared = rise * rise;
var runsquared = run * run;

var distancesquared = risesquared + runsquared;

var distance = Math.sqrt(dinstancesquared);

이것은 덮어 쓰거나 어딘가에서 잘못 해석 될 수있는 11 개의 전역 변수를 생성 할 것입니다.

수완

전역 네임 스페이스를 오염시키지 않는보다 자원이 풍부한 접근 방식은이 모든 것을 모듈 패턴으로 래핑하고 여러 변수를 노출하면서 하나의 전역 변수 만 사용하는 것입니다.

다음은 예입니다. (간단하고 오류 처리가 없습니다.)

//Calculate is the only exposed global variable
var Calculate = function () {
 //all defintions in this closure are local, and will not be exposed to the global namespace
 var Coordinates = [];//array for coordinates
 var Coordinate = function (xcoord, ycoord) {//definition for type Coordinate
   this.x = xcoord;//assign values similar to a constructor
   this.y = ycoord;
  };

  return {//these methods will be exposed through the Calculate object
   AddCoordinate: function (x, y) {
   Coordinates.push(new Coordinate(x, y));//Add a new coordinate
  },

  Slope: function () {//Calculates slope and returns the value
   var c1 = Coordinates[0];
   var c2 = Coordinates[1];
   return c2.y - c1.y / c2.x - c1.x;//calculates rise over run and returns result
  },

  Distance: function () {
   //even with an excessive amount of variables declared, these are all still local
   var c1 = Coordinates[0];
   var c2 = Coordinates[1];

   var rise = c2.y - c1.y;
   var run = c2.x - c1.x;

   var risesquared = rise * rise;
   var runsquared = run * run;

   var distancesquared = risesquared + runsquared;

   var distance = Math.sqrt(distancesquared);

   return distance;
  }
 };
};

//this is a "self executing closure" and is used because these variables will be
//scoped to the function, and will not be available globally nor will they collide
//with any variable names in the global namespace
(function () {
 var calc = Calculate();
 calc.AddCoordinate(5, 20);
 calc.AddCoordinate(3, 16);
 console.log(calc.Slope());
 console.log(calc.Distance());
})();

10
클로저 내부에 변수를 유지하면 가비지 수집됩니다.
theJava

2
매우 흥미로운 대답입니다. 스코프에서했던 것처럼 반환을 사용하고 예를 들어 Calculate.prototype.Slope()범위 밖에서 사용하는 것의 차이점이 무엇인지 설명해 주 시겠습니까? 이 문제에 가까운 다른 개념을 이해하는 것은 매우 완벽 할 것입니다!
Ludo

좋은 설명에 감사드립니다. 빠른 질문 : 해당 스 니펫에서 오류 처리에 대해 무엇을보고 싶습니까?
Sentenza

@Sentenza-라인에 오류가 발생하면 어떤 일이 발생하는지에 따라 다릅니다. 아무것도 없으면 실제로 오류 처리가 필요하지 않습니다. 중요한 경우 0으로 나누기가 발생하지 않는지 확인하는 몇 가지 테스트와 실패한 시도를 나타내는 메시지 또는 응답 (때로는 조용히 실패 함을 의미 함)이있을 수 있습니다. 아마도 숫자가 텍스트가 아니라 실제로 숫자인지 확인하는 몇 가지 테스트 일 것입니다. 전반적으로 오류 처리는 코드를 사용하는 사람에 따라 다릅니다. 당신 만 있다면, 당신은 아마도 특정한 속보를 전달하지 않는 것을 알 것입니다. 이것은 또한 다소 간단한 예입니다. :)
Travis J

20

JavaScript에서 함수 외부의 선언은 전역 범위에 있습니다. 이 작은 예를 고려하십시오.

var x = 10;
function example() {
    console.log(x);
}
example(); //Will print 10

위의 예에서는 x전역 범위에서 선언됩니다. example함수에 의해 생성 된 것과 같은 모든 자식 범위는 부모 범위에서 선언 된 항목을 효과적으로 상속합니다 (이 경우 전역 범위).

전역 범위에서 선언 된 변수를 재 선언하는 자식 범위는 전역 변수를 섀도 잉하여 잠재적으로 원치 않는 버그를 추적하기 어렵게 만듭니다.

var x = 10;
function example() {
    var x = 20;
    console.log(x); //Prints 20
}
example();
console.log(x); //Prints 10

전역 변수는 이와 같은 문제를 일으킬 수 있으므로 일반적으로 권장되지 않습니다. 함수 var내 에서 문을 사용하지 않았다면 example실수로 x전역 범위에서의 값을 덮어 썼을 것입니다 .

var x = 10;
function example() {
    x = 20; //Oops, no var statement
    console.log(x); //Prints 20
}
example();
console.log(x); //Prints 20... oh dear

더 많이 읽고 제대로 이해하고 싶다면 ECMAScript 사양을 살펴 보는 것이 좋습니다 . 가장 흥미 진진한 읽기는 아니지만 끝없이 도움이 될 것입니다.


8

전역 변수, 함수 등을 선언 할 때 그 (ehm)는 전역 네임 스페이스로 이동합니다. 성능 / 메모리 문제 (발생할 수 있음)를 제외하고, 중요한 변수를 재정의하거나 사용한다고 생각하는 값을 사용하지 않을 때 불행한 이름 충돌이 발생할 수 있습니다.

전역 네임 스페이스에서 정의하는 것은 피해야합니다.


1
전역 네임 스페이스에서 정의하는 것을 피하는 방법은 지역 변수 (함수 내에서 "var"로 선언 됨)를 사용하는 것입니다. 그러나 변수는 함수에 대해 지역적입니다. 가능한 한 많이해야합니다.
Stéphane Glondu
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.