我正在努力提高对javascript中全局命名空间的理解,我对以下几点很好奇:
-
是否有一个"GOD"(即父对象)对象,所有对象(因为除了基元之外的所有事物都是对象)都要回答,如果是,那个对象会是"窗口"吗?
-
为什么在全局级别上拥有vars/函数是个坏主意?
-
如果将vars/函数放在全局范围内真的是个坏主意,那么闭包是避免这种情况的最佳方法吗?示例:
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()
-
是否存在神(即父对象)对象?
是的。更严格地说,所有这些基元都是全局对象的成员;恰好在浏览器中,
window
对象是全局对象。> window.String === String; true
-
为什么在全局级别上拥有vars/函数是个坏主意?
因为如果你添加了很多第三方库/脚本,它们都共享同一个全局对象,那么就有可能发生名称冲突。这是所有使用
$
作为别名的库(jQuery、Prototype等)的实际问题。 -
如果将vars/函数放在全局范围内真的是个坏主意,那么闭包是避免这种情况的最佳方法吗?
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
的存在。请记住,如果使用var
在这些子函数中重新声明x
,则不会影响parent()
中的x
。
-
是的,在浏览器环境中,"上帝对象"就是窗口。它通常被称为全局对象,而不是上帝对象.)在nodejs等非浏览器环境中,全局对象可能使用除window之外的其他名称。
-
如果将所有内容都作为全局变量,则可能会遇到名称冲突的风险。还有封装的问题——换句话说,通过只将变量放在需要的范围内,你的代码通常会更好
-
是的,这几乎是首选的方法。您也可以使用IIFE的
-
据我所知,我会说是的,window是父对象。然而,在Iframe中,您有自己的窗口对象,与您可以通过window.parent 访问的周围窗口不同
-
有很多全局var是个坏主意,因为可能会发生名称冲突,因此很难检测到错误。通常,设计一些名称空间更安全(请参阅jQuery的
$
等)并模块化代码。 -
注意,
parent
是一个潜在的窗口领域。这取了一个物体,函数是物体,所以与2)中的观察结果相同。
如果需要将变量放入全局命名空间,并且您可能会在某个时候创建一个对象变量,并将其他变量作为属性或方法添加到其中。为对象指定一个其他人不太可能使用的名称(诚然,这是出现冲突问题的地方,但可以通过谨慎、标准化的命名来缓解)。
例如代替:
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 ) );