Понимание глобального пространства имен javascript и закрытия
Я пытаюсь улучшить свое понимание глобального пространства имен в javascript, и мне любопытно несколько вещей:
-
существует ли "БОГ" (т.е. родительский) объект, чтобы все объекты (поскольку все объекты, кроме примитивов, являются объектами), чтобы отвечать, и если бы этот объект был "окном"?
-
почему плохая идея иметь вары/функции на глобальном уровне?
-
Если это действительно плохая идея иметь вары/функции в глобальной области, то закрытие будет лучшим способом избежать этого? Пример:
function parent(){
var x = 'some value';//this var would be considered global to all children functions but not in the true global namespace
function child1(){
x.someMethod()
}
function child2(){
x*something;
}
function child3(){
x+=something;
child2()
child1()
}
child3()
}
parent()
Ответы
Ответ 1
-
Есть ли бог (т.е. родительский)?
Да. Более технически это глобальный объект, в который входят все эти примитивы; просто в браузере объект window
является глобальным объектом.
> window.String === String;
true
-
Почему плохая идея иметь vars/functions на глобальном уровне?
Потому что, если вы добавляете много сторонних библиотек/скриптов, все они имеют один и тот же глобальный объект, есть вероятность совпадений имен. Это проблема реальной жизни со всеми библиотеками, которые используют $
как псевдоним (jQuery, Prototype и т.д.).
-
Если это действительно плохая идея иметь vars/functions в глобальной области, то закрытие будет лучшим способом избежать этого?
x
не следует считать глобальным. Это часть замыкания, образованного объявлением дочерних функций внутри функции parent()
. Проблемная часть вашего фрагмента заключается в том, что parent()
является глобальным; что произойдет, если какой-либо другой код повторно объявлен parent()
? Это было бы лучше:
(function () {
function parent(){
var x = 'some value';
function child1(){
x.someMethod()
}
function child2(){
x*something;
}
function child3(){
x+=something;
child2()
child1()
}
child3()
}
parent()
}());
Тот факт, что x
доступен в дочерних функциях, неплох; вы должны были написать эти функции самостоятельно, поэтому вы должны знать о существовании x
. Имейте в виду, что если вы повторно объявите x
внутри этих дочерних функций с помощью var
, вы не будете влиять на x
в parent()
.
Ответ 2
-
Да, в среде браузера "объект-бог" - это окно. Обычно он называется глобальным объектом, а не объектом-богом;) В нерабочих средах, таких как nodejs, глобальный объект может использовать другое имя, кроме окна.
-
Если вы ставите все как глобальные, вы рискуете столкнуться с сталкивающимися именами. Существует также вопрос encapsulation - другими словами, ставя переменные только в область, в которой это необходимо, ваш код обычно лучше.
-
Да, это в значительной степени предпочтительный подход. Вы также можете использовать IIFE
Ответ 3
-
Насколько я знаю, я бы сказал, да, окно - это родительский объект. Однако внутри iframe у вас есть свой собственный объект окна, отличный от окружающего окна, к которому вы можете получить доступ через window.parent
-
Это плохая идея иметь много глобального var из-за потенциального столкновения имен и поэтому трудно обнаружить ошибки. В общем, безопаснее создавать некоторые пространства имен (см.
$
из jQuery и т.д.) и модульный код.
-
Будьте осторожны, parent
- потенциальное существующее поле окна. Это принятое appart, функция - объект, поэтому здесь применяется одно и то же наблюдение, чем в 2).
Ответ 4
Если вы НУЖДЫ помещаете переменные в глобальное пространство имен, и, вероятно, в какой-то момент вы создадите единую переменную объекта и добавите в нее другие переменные в качестве свойств или методов. Дайте объекту имя, которое вряд ли будет использоваться кем-либо еще (по общему признанию, именно там возникают проблемы с столкновением, но это может быть смягчено тщательным стандартизованным наименованием).
например. Вместо:
var thing1 = 'table';
var anotherthing = 'chair';
var mypet = 'dog';
var count = 4;
var show_something: function( _txt ) { return _txt.trim(); };
Сделайте это:
var cmjaimet_obj = {
thing1: 'table',
anotherthing: 'chair',
mypet: 'dog',
count: 4,
show_something: function( _txt ) { return _txt.trim(); }
};
Затем назовем их свойствами:
например. Вместо:
count += 2;
anotherthing = 'sofa';
console.log( show_something( 'Thing: ' + anotherthing ) );
Сделайте это:
cmjaimet_obj.count += 2;
cmjaimet_obj.anotherthing = 'sofa';
console.log( cmjaimet_obj.show_something( 'Thing: ' + cmjaimet_obj.anotherthing ) );
Ответ 5
var com = {};
com.Bookstore = {};
com.Bookstore.Book = {
title: 'my book',
genre: 'fiction'
};
com.Bookstore.Author = {
firstName: 'R',
lastName: 'D'
}