Що означає глобальний простір імен буде забрудненим?
Я насправді не розумію, що означає забруднення глобального простору імен.
Відповіді:
Коротка примітка про збір сміття
Оскільки змінні втрачають обсяг, вони зможуть збирати сміття. Якщо їх масштабують у всьому світі, вони не матимуть права на збір, доки глобальний простір імен не втратить сферу дії.
Ось приклад:
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втратити обсяг після закриття та мати право на вивезення сміття.
Глобальний простір імен - ваш друг
Незважаючи на багато претензій до використання глобального простору імен, це ваш друг. І як добрий друг, не слід зловживати своїми стосунками.
Будь ніжним
Не зловживайте (зазвичай називають "забруднюючим") глобальним простором імен. І що я маю на увазі, не зловживаючи глобальним простором імен, - не створюйте кілька глобальних змінних. Ось поганий приклад використання глобального простору імен.
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());
})();
Calculate.prototype.Slope()поза обсягом? Було б ідеально зрозуміти ще одну концепцію, близьку до цієї проблематики!
У 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 . Це може бути не найзахоплююче читання, але це не допоможе кінцю.
Коли ви оголошуєте глобальні змінні, функції тощо, вони, е-е, переходять до глобального простору імен. Окрім проблем із продуктивністю / пам'яттю (які можуть виникнути), ви, швидше за все, зіткнетеся з прикрим зіткненням назв, коли ви перевизначите важливу змінну або використаєте не значення, яке, на вашу думку, використовуєте.
Варто уникати визначення речей у глобальному просторі імен.