如何在JavaScript中创建命名空间,使我的对象和函数不被其他同名对象和函数覆盖?我使用了以下方法:
if (Foo == null || typeof(Foo) != "object") { var Foo = new Object();}
有没有更优雅或更简洁的方式来做到这一点?
如何在JavaScript中创建命名空间,使我的对象和函数不被其他同名对象和函数覆盖?我使用了以下方法:
if (Foo == null || typeof(Foo) != "object") { var Foo = new Object();}
有没有更优雅或更简洁的方式来做到这一点?
当前回答
因为您可能会编写不同的JavaScript文件,然后在应用程序中组合或不组合它们,所以每个文件都需要能够恢复或构造名称空间对象,而不会破坏其他文件的工作……
一个文件可能打算使用命名空间namespace.namespace1:
namespace = window.namespace || {};
namespace.namespace1 = namespace.namespace1 || {};
namespace.namespace1.doSomeThing = function(){}
另一个文件可能想要使用命名空间namespace2:
namespace = window.namespace || {};
namespace.namespace2 = namespace.namespace2 || {};
namespace.namespace2.doSomeThing = function(){}
这两个文件可以共存,也可以分开而不会发生碰撞。
其他回答
我喜欢Jaco Pretorius的解决方案,但我想通过将“this”关键字指向模块/名称空间对象来使其更有用。 我的煎锅版本:
(function ($, undefined) {
console.log(this);
}).call(window.myNamespace = window.myNamespace || {}, jQuery);
有没有更优雅或更简洁的方式来做到这一点?
是的。例如:
var your_namespace = your_namespace || {};
然后你就可以
var your_namespace = your_namespace || {};
your_namespace.Foo = {toAlert:'test'};
your_namespace.Bar = function(arg)
{
alert(arg);
};
with(your_namespace)
{
Bar(Foo.toAlert);
}
我对名称空间使用以下语法。
var MYNamespace = MYNamespace|| {};
MYNamespace.MyFirstClass = function (val) {
this.value = val;
this.getValue = function(){
return this.value;
};
}
var myFirstInstance = new MYNamespace.MyFirstClass(46);
alert(myFirstInstance.getValue());
jsfiddle: http://jsfiddle.net/rpaul/4dngxwb3/1/
我通常在闭包中构建它:
var MYNS = MYNS || {};
MYNS.subns = (function() {
function privateMethod() {
// Do private stuff, or build internal.
return "Message";
}
return {
someProperty: 'prop value',
publicMethod: function() {
return privateMethod() + " stuff";
}
};
})();
自从写了这篇文章以来,我的风格在这些年里有了微妙的变化,现在我发现自己是这样写闭包的:
var MYNS = MYNS || {};
MYNS.subns = (function() {
var internalState = "Message";
var privateMethod = function() {
// Do private stuff, or build internal.
return internalState;
};
var publicMethod = function() {
return privateMethod() + " stuff";
};
return {
someProperty: 'prop value',
publicMethod: publicMethod
};
})();
通过这种方式,我发现公共API和实现更容易理解。将return语句视为实现的公共接口。
我使用在企业jQuery网站上找到的方法:
下面是他们的例子,展示了如何声明私有和公共属性和函数。一切都是作为一个自动执行的匿名函数完成的。
(function( skillet, $, undefined ) {
//Private Property
var isHot = true;
//Public Property
skillet.ingredient = "Bacon Strips";
//Public Method
skillet.fry = function() {
var oliveOil;
addItem( "\t\n Butter \n\t" );
addItem( oliveOil );
console.log( "Frying " + skillet.ingredient );
};
//Private Method
function addItem( item ) {
if ( item !== undefined ) {
console.log( "Adding " + $.trim(item) );
}
}
}( window.skillet = window.skillet || {}, jQuery ));
如果你想访问某个公共成员你只需输入skillet。fry()或skillet。配料。
真正酷的是,现在可以使用完全相同的语法扩展名称空间。
//Adding new Functionality to the skillet
(function( skillet, $, undefined ) {
//Private Property
var amountOfGrease = "1 Cup";
//Public Method
skillet.toString = function() {
console.log( skillet.quantity + " " +
skillet.ingredient + " & " +
amountOfGrease + " of Grease" );
console.log( isHot ? "Hot" : "Cold" );
};
}( window.skillet = window.skillet || {}, jQuery ));
第三个未定义的参数
The third, undefined argument is the source of the variable of value undefined. I'm not sure if it's still relevant today, but while working with older browsers / JavaScript standards (ecmascript 5, javascript < 1.8.5 ~ firefox 4), the global-scope variable undefined is writable, so anyone could rewrite its value. The third argument (when not passed a value) creates a variable named undefined which is scoped to the namespace/function. Because no value was passed when you created the name space, it defaults to the value undefined.