提问人:Scott McKenzie 提问时间:5/19/2009 最后编辑:George StockerScott McKenzie 更新时间:1/12/2022 访问量:633022
如何在 JavaScript 中声明命名空间?
How do I declare a namespace in JavaScript?
问:
如何在 JavaScript 中创建命名空间,以便我的对象和函数不会被其他同名对象和函数覆盖?我使用了以下内容:
if (Foo == null || typeof(Foo) != "object") { var Foo = new Object();}
有没有更优雅或更简洁的方法?
答:
我喜欢这个:
var yourNamespace = {
foo: function() {
},
bar: function() {
}
};
...
yourNamespace.foo();
评论
MyApp
MyApp.Views.Profile = {}
MyApp.users = {}
MyViews.Profile = {}
我使用这种方法:
var myNamespace = {}
myNamespace._construct = function()
{
var staticVariable = "This is available to all functions created here"
function MyClass()
{
// Depending on the class, we may build all the classes here
this.publicMethod = function()
{
//Do stuff
}
}
// Alternatively, we may use a prototype.
MyClass.prototype.altPublicMethod = function()
{
//Do stuff
}
function privateStuff()
{
}
function publicStuff()
{
// Code that may call other public and private functions
}
// List of things to place publically
this.publicStuff = publicStuff
this.MyClass = MyClass
}
myNamespace._construct()
// The following may or may not be in another file
myNamespace.subName = {}
myNamespace.subName._construct = function()
{
// Build namespace
}
myNamespace.subName._construct()
然后,外部代码可以是:
var myClass = new myNamespace.MyClass();
var myOtherClass = new myNamepace.subName.SomeOtherClass();
myNamespace.subName.publicOtherStuff(someParameter);
评论
ns = ns || {}
另一种方法,我认为它比对象文字形式限制少一点,是这样的:
var ns = new function() {
var internalFunction = function() {
};
this.publicFunction = function() {
};
};
上面的内容与模块模式非常相似,无论您喜欢与否,它都允许您将所有函数公开为公共函数,同时避免对象文字的僵化结构。
评论
ns().publicFunction()
ns.publicFunction()
new
function
new
ns
在将我的几个库移植到不同的项目,并且必须不断更改顶级(静态命名)命名空间之后,我已切换到使用这个小型(开源)帮助程序函数来定义命名空间。
global_namespace.Define('startpad.base', function(ns) {
var Other = ns.Import('startpad.other');
....
});
我非常喜欢的一个好处是模块之间在负载顺序方面的隔离。您可以在加载外部模块之前对其进行引用。当代码可用时,您获得的对象引用将被填充。
评论
有没有更优雅或更简洁的方法?
是的。例如:
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 your_namespace = your_namespace = your_namespace || {}
我创建了受 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
})();
这是 user106826 链接到 Namespace.js 的后续。该项目似乎转移到了 GitHub。现在是 smith/namespacedotjs。
我一直在为我的小项目使用这个简单的 JavaScript 助手,到目前为止,它似乎很轻巧但用途广泛,足以处理命名空间和加载模块/类。如果它允许我将包导入我选择的命名空间,而不仅仅是全局命名空间,那就太好了......唉,但这不是重点。
它允许您声明命名空间,然后在该命名空间中定义对象/模块:
Namespace('my.awesome.package');
my.awesome.package.WildClass = {};
另一种选择是立即声明命名空间及其内容:
Namespace('my.awesome.package', {
SuperDuperClass: {
saveTheDay: function() {
alert('You are welcome.');
}
}
});
有关更多用法示例,请查看源代码中的 example.js 文件。
评论
因为你可能会编写不同的 JavaScript 文件,然后将它们合并或不合并到一个应用程序中,所以每个文件都需要能够在不损害其他文件工作的情况下恢复或构造命名空间对象......
一个文件可能打算使用命名空间:namespace.namespace1
namespace = window.namespace || {};
namespace.namespace1 = namespace.namespace1 || {};
namespace.namespace1.doSomeThing = function(){}
另一个文件可能想要使用命名空间:namespace.namespace2
namespace = window.namespace || {};
namespace.namespace2 = namespace.namespace2 || {};
namespace.namespace2.doSomeThing = function(){}
这两个文件可以共存或分开而不会发生冲突。
评论
我写了另一个命名空间库,它的工作方式更像其他语言中的包/单元。它允许您创建 JavaScript 代码包以及从其他代码包中引用该代码包:
文件你好 .js
Package("hello", [], function() {
function greeting() {
alert("Hello World!");
}
// Expose function greeting to other packages
Export("greeting", greeting);
});
文件示例:.js
Package("example", ["hello"], function(greeting) {
// Greeting is available here
greeting(); // Alerts: "Hello World!"
});
页面中只需要包含第二个文件。它的依赖项(本例中的文件hello.js)将被自动加载,从这些依赖项导出的对象将用于填充回调函数的参数。
您可以在 Packages JS 中找到相关项目。
评论
如果使用 Makefile,您可以执行此操作。
// prelude.hjs
billy = new (
function moduleWrapper () {
const exports = this;
// postlude.hjs
return exports;
})();
// someinternalfile.js
function bob () { console.log('hi'); }
exports.bob = bob;
// clientfile.js
billy.bob();
一旦我达到大约 1000 行,我更喜欢使用 Makefile,因为我可以通过删除 makefile 中的一行来有效地注释掉大量代码。它使摆弄东西变得容易。此外,使用这种技术,命名空间在前奏中只出现一次,因此很容易更改,您不必在库代码中不断重复它。
使用 makefile 时用于在浏览器中进行实时开发的 shell 脚本:
while (true); do make; sleep 1; done
将其添加为 make 任务 'go',你可以 'make go' 以在编码时保持构建更新。
我使用在Enterprise 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.ingredients
真正酷的是,您现在可以使用完全相同的语法扩展命名空间。
//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 ));
第三个论点undefined
第三,参数是变量 value 的来源。我不确定它今天是否仍然相关,但是在使用较旧的浏览器/JavaScript 标准(ecmascript 5、javascript < 1.8.5 ~ firefox 4)时,global-scope 变量是可写的,因此任何人都可以重写它的值。第三个参数(当未传递值时)创建一个名为的变量,该变量的作用域为命名空间/函数。由于创建命名空间时未传递任何值,因此它默认为值 。
undefined
undefined
undefined
undefined
undefined
评论
undefined
undefined
undefined
undefined
undefined
window.skillet = window.skillet || {}
我通常在闭包中构建它:
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 语句视为实现的公共接口。
评论
MYNS.subns = MYNS.subns || {}
var foo = function
function foo
var foo
function foo
jmp
pushq
popq
function foo
以下是 Stoyan Stefanov 在他的 JavaScript Patterns 一书中是如何做到的,我发现这本书非常好(它还展示了他如何进行允许自动生成的 API 文档的注释,以及如何将方法添加到自定义对象的原型中):
/**
* My JavaScript application
*
* @module myapp
*/
/** @namespace Namespace for MYAPP classes and functions. */
var MYAPP = MYAPP || {};
/**
* A maths utility
* @namespace MYAPP
* @class math_stuff
*/
MYAPP.math_stuff = {
/**
* Sums two numbers
*
* @method sum
* @param {Number} a First number
* @param {Number} b Second number
* @return {Number} Sum of the inputs
*/
sum: function (a, b) {
return a + b;
},
/**
* Multiplies two numbers
*
* @method multi
* @param {Number} a First number
* @param {Number} b Second number
* @return {Number} The inputs multiplied
*/
multi: function (a, b) {
return a * b;
}
};
/**
* Constructs Person objects
* @class Person
* @constructor
* @namespace MYAPP
* @param {String} First name
* @param {String} Last name
*/
MYAPP.Person = function (first, last) {
/**
* First name of the Person
* @property first_name
* @type String
*/
this.first_name = first;
/**
* Last name of the Person
* @property last_name
* @type String
*/
this.last_name = last;
};
/**
* Return Person's full name
*
* @method getName
* @return {String} First name + last name
*/
MYAPP.Person.prototype.getName = function () {
return this.first_name + ' ' + this.last_name;
};
您可以声明一个简单的函数来提供命名空间。
function namespace(namespace) {
var object = this, tokens = namespace.split("."), token;
while (tokens.length > 0) {
token = tokens.shift();
if (typeof object[token] === "undefined") {
object[token] = {};
}
object = object[token];
}
return object;
}
// Usage example
namespace("foo.bar").baz = "I'm a value!";
样本:
var namespace = {};
namespace.module1 = (function(){
var self = {};
self.initialized = false;
self.init = function(){
setTimeout(self.onTimeout, 1000)
};
self.onTimeout = function(){
alert('onTimeout')
self.initialized = true;
};
self.init(); /* If it needs to auto-initialize, */
/* You can also call 'namespace.module1.init();' from outside the module. */
return self;
})()
您可以选择声明变量、 、 like 和 assign (如果希望它是私有的)。local
same
self
local.onTimeout
我喜欢 Jaco Pretorius 的解决方案,但我想通过将“this”关键字指向模块/命名空间对象来使其更有用。 我的煎锅版本:
(function ($, undefined) {
console.log(this);
}).call(window.myNamespace = window.myNamespace || {}, jQuery);
我对命名空间使用以下语法。
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/
我的习惯是使用函数 myName() 作为属性存储,然后使用 var myName 作为“方法”持有者......
不管这是否合法,打败我!我一直依赖我的PHP逻辑,而且事情很简单。:D
function myObj() {
this.prop1 = 1;
this.prop2 = 2;
this.prop3 = 'string';
}
var myObj = (
(myObj instanceof Function !== false)
? Object.create({
$props: new myObj(),
fName1: function() { /* code.. */ },
fName2: function() { /* code ...*/ }
})
: console.log('Object creation failed!')
);
if (this !== that) myObj.fName1(); else myObj.fName2();
您也可以以“反之亦然”的方式进行检查,以便在创建对象之前进行检查,这要好得多:
function myObj() {
this.prop1 = 1;
this.prop2 = 2;
this.prop3 = 'string';
}
var myObj = (
(typeof(myObj) !== "function" || myObj instanceof Function === false)
? new Boolean()
: Object.create({
$props: new myObj(),
init: function () { return; },
fName1: function() { /* code.. */ },
fName2: function() { /* code ...*/ }
})
);
if (myObj instanceof Boolean) {
Object.freeze(myObj);
console.log('myObj failed!');
debugger;
}
else
myObj.init();
参考:JavaScript:使用 Object.create() 创建对象
这是 Ionuț G. Stan 回答的后续,但通过使用 展示了整洁代码的好处,它利用了 JavaScript 的闭包范围,以减少同一命名空间中类的命名空间混乱。var ClassFirst = this.ClassFirst = function() {...}
var Namespace = new function() {
var ClassFirst = this.ClassFirst = function() {
this.abc = 123;
}
var ClassSecond = this.ClassSecond = function() {
console.log("Cluttered way to access another class in namespace: ", new Namespace.ClassFirst().abc);
console.log("Nicer way to access a class in same namespace: ", new ClassFirst().abc);
}
}
var Namespace2 = new function() {
var ClassFirst = this.ClassFirst = function() {
this.abc = 666;
}
var ClassSecond = this.ClassSecond = function() {
console.log("Cluttered way to access another class in namespace: ", new Namespace2.ClassFirst().abc);
console.log("Nicer way to access a class in same namespace: ", new ClassFirst().abc);
}
}
new Namespace.ClassSecond()
new Namespace2.ClassSecond()
输出:
Cluttered way to access another class in namespace: 123
Nicer way to access a class in same namespace: 123
Cluttered way to access another class in namespace: 666
Nicer way to access a class in same namespace: 666
我们可以通过这种方式独立使用它:
var A = A|| {};
A.B = {};
A.B = {
itemOne: null,
itemTwo: null,
};
A.B.itemOne = function () {
//..
}
A.B.itemTwo = function () {
//..
}
最近我最喜欢的模式变成了:
var namespace = (function() {
// expose to public
return {
a: internalA,
c: internalC
}
// all private
/**
* Full JSDoc
*/
function internalA() {
// ...
}
/**
* Full JSDoc
*/
function internalB() {
// ...
}
/**
* Full JSDoc
*/
function internalC() {
// ...
}
/**
* Full JSDoc
*/
function internalD() {
// ...
}
})();
当然,return 可以在末尾,但如果只有函数声明跟在它后面,那么就更容易看到命名空间的全部内容,以及公开了什么 API。
在这种情况下使用函数表达式的模式导致在不遍历整个代码的情况下无法知道公开了哪些方法。
评论
namespace.a();
()
在 JavaScript 中,没有预定义的方法来使用命名空间。在 JavaScript 中,我们必须创建自己的方法来定义 NameSpaces。这是我们在 Oodles 技术中遵循的程序。
注册命名空间 以下是注册命名空间的函数
//Register NameSpaces Function
function registerNS(args){
var nameSpaceParts = args.split(".");
var root = window;
for(var i=0; i < nameSpaceParts.length; i++)
{
if(typeof root[nameSpaceParts[i]] == "undefined")
root[nameSpaceParts[i]] = new Object();
root = root[nameSpaceParts[i]];
}
}
要注册命名空间,只需调用上述函数,参数为名称空间,用 (dot) 分隔。
例如
让您的应用程序名称为 oodles。您可以通过以下方法创建命名空间'.'
registerNS("oodles.HomeUtilities");
registerNS("oodles.GlobalUtilities");
var $OHU = oodles.HomeUtilities;
var $OGU = oodles.GlobalUtilities;
基本上,它将在后端创建您的命名空间结构,如下所示:
var oodles = {
"HomeUtilities": {},
"GlobalUtilities": {}
};
在上面的函数中,您注册了一个名为 和 的命名空间。为了调用这些命名空间,我们制作了一个变量,即 var 和 var 。"oodles.HomeUtilities"
"oodles.GlobalUtilities"
$OHU
$OGU
这些变量只不过是初始化命名空间的别名。
现在,每当你声明一个属于你的函数时,都会像下面这样声明它:HomeUtilities
$OHU.initialization = function(){
//Your Code Here
};
上面是函数名初始化,它被放入一个命名空间中。并在脚本文件中的任意位置调用此函数。只需使用以下代码即可。$OHU
$OHU.initialization();
同样,使用另一个命名空间。
希望对你有所帮助。
我迟到了 7 年,但在 8 年前做了相当多的工作:
- http://blogger.ziesemer.com/2008/05/javascript-namespace-function.html
- http://blogger.ziesemer.com/2007/10/respecting-javascript-global-namespace.html
能够轻松高效地创建多个嵌套命名空间以保持复杂的 Web 应用程序井井有条且易于管理,同时尊重 JavaScript 全局命名空间(防止命名空间污染),并且在此过程中不会破坏命名空间路径中的任何现有对象,这一点很重要。
综上所述,这是我大约 2008 年的解决方案:
var namespace = function(name, separator, container){
var ns = name.split(separator || '.'),
o = container || window,
i,
len;
for(i = 0, len = ns.length; i < len; i++){
o = o[ns[i]] = o[ns[i]] || {};
}
return o;
};
这不是创建命名空间,而是提供用于创建命名空间的函数。
这可以浓缩为缩小的单行:
var namespace=function(c,f,b){var e=c.split(f||"."),g=b||window,d,a;for(d=0,a=e.length;d<a;d++){g=g[e[d]]=g[e[d]]||{}}return g};
使用示例:
namespace("com.example.namespace");
com.example.namespace.test = function(){
alert("In namespaced function.");
};
或者,作为一个声明:
namespace("com.example.namespace").test = function(){
alert("In namespaced function.");
};
然后,任一操作都按以下方式执行:
com.example.namespace.test();
如果您不需要对旧版浏览器的支持,请更新版本:
const namespace = function(name, separator, container){
var o = container || window;
name.split(separator || '.').forEach(function(x){
o = o[x] = o[x] || {};
});
return o;
};
现在,我不敢公开全局命名空间本身。(太糟糕了,基本语言没有为我们提供这个!因此,我通常会在闭包中使用它,例如:namespace
(function(){
const namespace = function(name, separator, container){
var o = container || window;
name.split(separator || '.').forEach(function(x){
o = o[x] = o[x] || {};
});
return o;
};
const ns = namespace("com.ziesemer.myApp");
// Optional:
ns.namespace = ns;
// Further extend, work with ns from here...
}());
console.log("\"com\":", com);
在较大的应用程序中,只需在页面加载开始时定义一次(对于基于客户端的 Web 应用)。如果保留其他文件,则可以重用命名空间函数(在上面作为“可选”包含在内)。在最坏的情况下,如果这个函数被重新声明几次 - 它只是几行代码,如果缩小,则更少。
评论
let
const
namespace("com.ziesemer.myApp")
const
let
com.ziesemer.myApp.logger
const
模块模式最初被定义为一种为传统软件工程中的类提供私有和公共封装的方法。
在使用 Module 模式时,我们可能会发现定义一个简单的模板来开始使用它很有用。下面是一个涵盖名称间距、公共和私有变量的变量。
在 JavaScript 中,Module 模式用于进一步模拟类的概念,以便我们能够在单个对象中同时包含公共/私有方法和变量,从而将特定部分屏蔽在全局范围之外。这样可以降低函数名称与页面上其他脚本中定义的其他函数冲突的可能性。
var myNamespace = (function () {
var myPrivateVar, myPrivateMethod;
// A private counter variable
myPrivateVar = 0;
// A private function which logs any arguments
myPrivateMethod = function( foo ) {
console.log( foo );
};
return {
// A public variable
myPublicVar: "foo",
// A public function utilizing privates
myPublicFunction: function( bar ) {
// Increment our private counter
myPrivateVar++;
// Call our private method using bar
myPrivateMethod( bar );
}
};
})();
优势
为什么模块模式是一个不错的选择?对于初学者来说,对于来自面向对象背景的开发人员来说,它比真正的封装要干净得多,至少从 JavaScript 的角度来看是这样。
其次,它支持私有数据——因此,在模块模式中,我们代码的公共部分能够触及私有部分,但外界无法触及类的私有部分。
弊
模块模式的缺点是,由于我们以不同的方式访问公共成员和私有成员,因此当我们希望更改可见性时,我们实际上必须对使用成员的每个位置进行更改。
我们也无法访问稍后添加到对象的方法中的私有成员。也就是说,在许多情况下,模块模式仍然非常有用,如果使用得当,肯定有可能改进我们应用程序的结构。
揭示模块模式
现在我们对模块模式有了更深入的了解,让我们来看看一个稍微改进的版本——Christian Heilmann 的 Revealing Module 模式。
Revealing Module 模式的出现是因为 Heilmann 对这样一个事实感到沮丧,即当我们想从另一个公共方法调用一个公共方法或访问公共变量时,他必须重复主对象的名称。他也不喜欢 Module 模式要求他必须切换到对象文字表示法来表示他希望公开的内容。
他努力的结果是一个更新的模式,在这个模式中,我们只需在私有范围内定义所有函数和变量,并返回一个匿名对象,其中包含指向我们希望公开的私有功能的指针。
有关如何使用“显示模块”模式的示例,请参见下文
var myRevealingModule = (function () {
var privateVar = "Ben Cherry",
publicVar = "Hey there!";
function privateFunction() {
console.log( "Name:" + privateVar );
}
function publicSetName( strName ) {
privateVar = strName;
}
function publicGetName() {
privateFunction();
}
// Reveal public pointers to
// private functions and properties
return {
setName: publicSetName,
greeting: publicVar,
getName: publicGetName
};
})();
myRevealingModule.setName( "Paul Kinlan" );
优势
此模式允许脚本的语法更加一致。它还在模块末尾更清楚地说明了哪些函数和变量可以公开访问,从而简化了可读性。
弊
这种模式的缺点是,如果私有函数引用公共函数,则在需要修补程序时无法覆盖该公共函数。这是因为私有函数将继续引用私有实现,并且该模式不适用于公共成员,仅适用于函数。
引用私有变量的公共对象成员也受上述无补丁规则说明的约束。
如果需要专用范围:If you need the private scope:
var yourNamespace = (function() {
//Private property
var publicScope = {};
//Private property
var privateProperty = "aaa";
//Public property
publicScope.publicProperty = "bbb";
//Public method
publicScope.publicMethod = function() {
this.privateMethod();
};
//Private method
function privateMethod() {
console.log(this.privateProperty);
}
//Return only the public parts
return publicScope;
}());
yourNamespace.publicMethod();
否则,如果您永远不会使用专用范围:
var yourNamespace = {};
yourNamespace.publicMethod = function() {
// Do something...
};
yourNamespace.publicMethod2 = function() {
// Do something...
};
yourNamespace.publicMethod();
我认为你们都为这么简单的问题使用了太多的代码。 无需为此制作回购。 这是一个单行函数。
namespace => namespace.split(".").reduce((last, next) => (last[next] = (last[next] || {})), window);
尝试一下:
// --- definition ---
const namespace = name => name.split(".").reduce((last, next) => (last[next] = (last[next] || {})), window);
// --- Use ----
const c = namespace("a.b.c");
c.MyClass = class MyClass {};
// --- see ----
console.log("a : ", a);
默认情况下,JavaScript 不支持命名空间。因此,如果您创建任何元素(函数、方法、对象、变量),那么它就会变成全局并污染全局命名空间。让我们举一个定义两个没有任何命名空间的函数的例子,
function func1() {
console.log("This is a first definition");
}
function func1() {
console.log("This is a second definition");
}
func1(); // This is a second definition
它始终调用第二个函数定义。在这种情况下,namespace 将解决名称冲突问题。
// circle.js
export { name, draw, reportArea, reportPerimeter };
// main.js
import * as Circle from './modules/circle.js';
// draw a circle
let circle1 = Circle.draw(myCanvas.ctx, 75, 200, 100, 'green');
Circle.reportArea(circle1.radius, reportList);
Circle.reportPerimeter(circle1.radius, reportList);
这将获取 circle.js 中所有可用的导出,并使它们可作为对象的成员使用,有效地为其提供自己的命名空间。Circle
JavaScript 还没有命名空间的本机表示形式,但 TypeScript 有。
例如,可以使用以下 TS 代码 (playground)
namespace Stack {
export const hello = () => console.log('hi')
}
Stack.hello()
如果无法将代码更新为 TS,则在生成命名空间的 JS 输出时,至少可以使用 TS 采用的模式,如下所示:
var Stack;
(function (Stack) {
Stack.hello = () => console.log('hi');
})(Stack || (Stack = {}));
Stack.hello();
评论