Что это значит, что глобальное пространство имен будет загрязнено? - PullRequest
81 голосов
/ 14 января 2012

Что означает загрязнение глобального пространства имен?

Я не совсем понимаю, что означает загрязнение глобального пространства имен.

Ответы [ 3 ]

115 голосов
/ 13 ноября 2012

Краткое примечание о сборке мусора

Поскольку переменные теряют область видимости, они будут иметь право на сборку мусора.Если они имеют глобальную область, то они не будут иметь права на сбор, пока глобальное пространство имен не потеряет область действия.

Вот пример:

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

Добавление этого в ваше глобальное пространство имен (по крайней мере,для меня) должно рекламировать 10 000 КБ памяти (win7 firefox), которая не будет собираться.Другие браузеры могут обрабатывать это по-разному.

Принимая во внимание тот же код в области видимости, которая выходит из области видимости следующим образом:

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

Позволит arra потерять область действия после выполнения замыканияи иметь право на сбор мусора.

Глобальное пространство имен - ваш друг

Несмотря на многочисленные претензии против использования глобального пространства имен, это ваш друг.И, как хороший друг, вы не должны злоупотреблять своими отношениями.

Будьте нежны

Не злоупотребляйте (обычно называемым "загрязняющим") глобальным пространством имен.И что я имею в виду, не злоупотребляйте глобальным пространством имен - не создавайте несколько глобальных переменных.Вот bad пример использования глобального пространства имен.

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());
})();
19 голосов
/ 14 января 2012

В 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 .Это может быть не самое захватывающее из прочтений, но это поможет без конца.

7 голосов
/ 14 января 2012

Когда вы объявляете глобальные переменные, функции и т. Д., Они попадают в глобальное пространство имен.Помимо проблем с производительностью / памятью (которые могут возникнуть), вы, скорее всего, столкнетесь с неудачным конфликтом имен, когда будете переопределять важную переменную или использовать не то значение, которое, по вашему мнению, используете.

Определение вещей вследует избегать глобального пространства имен.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...