如何在JavaScript中创建命名空间,使我的对象和函数不被其他同名对象和函数覆盖?我使用了以下方法:
if (Foo == null || typeof(Foo) != "object") { var Foo = new Object();}
有没有更优雅或更简洁的方式来做到这一点?
如何在JavaScript中创建命名空间,使我的对象和函数不被其他同名对象和函数覆盖?我使用了以下方法:
if (Foo == null || typeof(Foo) != "object") { var Foo = new Object();}
有没有更优雅或更简洁的方式来做到这一点?
当前回答
我创建的命名空间是受到Erlang模块的启发。这是一种非常实用的方法,但这就是我最近编写JavaScript代码的方式。
它为闭包提供全局名称空间,并在闭包中公开已定义的集合函数。
(function(){
namespace("images", previous, next);
// ^^ This creates or finds a root object, images, and binds the two functions to it.
// It works even though those functions are not yet defined.
function previous(){ ... }
function next(){ ... }
function find(){ ... } // A private function
})();
其他回答
另一种方式是,我认为它比对象文字形式限制少一点,是这样的:
var ns = new function() {
var internalFunction = function() {
};
this.publicFunction = function() {
};
};
上面的模式非常类似于模块模式,不管你喜欢与否,它允许你将所有函数公开为public,同时避免了对象字面量的刚性结构。
在将我的几个库移植到不同的项目中,并且不得不不断更改顶级(静态命名的)名称空间之后,我转而使用这个小的(开源的)帮助函数来定义名称空间。
global_namespace.Define('startpad.base', function(ns) {
var Other = ns.Import('startpad.other');
....
});
关于好处的描述在我的博客文章中。您可以在这里获取源代码。
我非常喜欢的一个好处是模块之间相对于加载顺序的隔离。你可以在加载外部模块之前引用它。当代码可用时,将填充您获得的对象引用。
我认为对于这样一个简单的问题,你们都使用了太多的代码。 没必要为它回购。 这是一个单线函数。
namespace => namespace.split(".").reduce((last, next) => (last[next] = (last[next] || {})), window);
试试吧:
//——定义—— Const namespace = name => name.split(".")。减少(下)(最后,= >(去年[下]=(去年[下一个 ] || {})), 窗口); //——使用---- Const c =命名空间("a.b.c"); c.MyClass = class MyClass {}; //—参见---- Console.log ("a: ", a);
我通常在闭包中构建它:
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语句视为实现的公共接口。
我写了另一个命名空间库,它的工作方式有点像其他语言中的包/单元。它允许你创建一个JavaScript代码包,并从其他代码中引用这个包:
文件hello.js
Package("hello", [], function() {
function greeting() {
alert("Hello World!");
}
// Expose function greeting to other packages
Export("greeting", greeting);
});
文件Example.js
Package("example", ["hello"], function(greeting) {
// Greeting is available here
greeting(); // Alerts: "Hello World!"
});
页面中只需要包含第二个文件。它的依赖项(本例中的文件hello.js)将自动加载,从这些依赖项导出的对象将用于填充回调函数的参数。
你可以在Packages JS中找到相关的项目。