search
HomeWeb Front-endJS TutorialA detailed introduction to namespaces in JavaScript

Global variables should be reserved for objects with system-wide dependencies, and their names should avoid ambiguity and minimize the risk of naming conflicts. In practice, this means that you should avoid creating global objects unless they are absolutely necessary.

But, well, you already knew this...

So what did you do about it? Traditional approaches tell us that the best strategy for eliminating globals is to create a small number of global objects that serve as actual namespaces for underlying modules and subsystems. I'll explore several approaches to namespaces and end with an elegant, safe, and flexible solution I came up with based on a recent article by James Edwards.

static namespace

I use static namespace as an umbrella term for those solutions where the namespace label is actually hard-coded. Yes, you can reassign one namespace to another, but the new namespace will reference the same objects as the old one.

1. Through direct allocation

The most basic method. This is very verbose, and if you want to rename these namespaces, you have work to do. But it's safe and clear.

var myApp = {}
myApp.id = 0;
myApp.next = function() {
    return myApp.id++;  
}
myApp.reset = function() {
    myApp.id = 0;   
}
window.console && console.log(
    myApp.next(),
    myApp.next(),
    myApp.reset(),
    myApp.next()
); //0, 1, undefined, 0

You can also make future maintenance easier by using this to reference sibling properties, but this is a bit risky because there is nothing stopping your namespace methods from being redistribute.

var myApp = {}
myApp.id = 0;
myApp.next = function() {
    return this.id++;   
}
myApp.reset = function() {
    this.id = 0;    
}
myApp.next(); //0
myApp.next(); //1
var getNextId = myApp.next;
getNextId(); //NaN whoops!

2. Use object literals

Now we only need to reference the namespace name once, so changing the name later is simpler (assuming you haven't referenced the namespace repeatedly). There is still a danger that the value of this may throw up a "surprise" - but it is safer to assume that the object defined in an object literal structure will not be reallocated.

var myApp = {
    id: 0,
    next: function() {
        return this.id++;   
    },
    reset: function() {
        this.id = 0;    
    }
}
window.console && console.log(
    myApp.next(),
    myApp.next(),
    myApp.reset(),
    myApp.next()
) //0, 1, undefined, 0

3. Module Pattern

I find myself using Module Pattern more lately. The logic is isolated from the global scope by a method wrapper (usually self-invoking), which returns an object representing the module's public interface. By immediately calling this method and assigning the result to a namespace variable, we lock the API of the module in this named variable. Additionally, any variables not included in the return value will always remain private, visible only to the public methods that reference them.

var myApp = (function() {
    var id= 0;
    return {
        next: function() {
            return id++;    
        },
        reset: function() {
            id = 0;     
        }
    };  
})();   
window.console && console.log(
    myApp.next(),
    myApp.next(),
    myApp.reset(),
    myApp.next()
) //0, 1, undefined, 0

As with the object literal example above, the namespace name can be easily changed, but there is an added advantage: object literals are class 4 - it's all about attribute assignment, no room for supporting logic. Furthermore, all properties must be initialized, and property values ​​cannot be easily referenced across objects (so, for example, internal closures are not possible to use). Module pattern does not have any of the above constraints and gives us additional privacy benefits.

Dynamic Namespace

We can also call this section Namespace Injection. The namespace is represented by a proxy that directly references the method wrapper inside of it - this means we no longer need to wrap the return value assigned to the namespace. This makes namespace definitions more flexible and allows having multiple independent instances of the module that exist in independent namespaces (or even in the global context). Dynamic namespaces support all the features of the module pattern with the added advantage of being intuitive and readable.

4. Provide namespace parameters

Here we just pass the namespace as a parameter to the self-calling method. The variable

id is private because it is not assigned to context.

var myApp = {};
(function(context) { 
    var id = 0;
    context.next = function() {
        return id++;    
    };
    context.reset = function() {
        id = 0;     
    }
})(myApp);  
window.console && console.log(
    myApp.next(),
    myApp.next(),
    myApp.reset(),
    myApp.next()
) //0, 1, undefined, 0

We can even set

context to the global object (with a single word change!). This is a huge asset for library owners - they can wrap their features in a self-calling function and let the user decide whether they are global or not (John Resig was an early adopter of this theory when he was writing JQuery) .

var myApp = {};
(function(context) { 
    var id = 0;
    context.next = function() {
        return id++;    
    };
    context.reset = function() {
        id = 0;     
    }
})(this);   
window.console && console.log(
    next(),
    next(),
    reset(),
    next()
) //0, 1, undefined, 0

5. Use

this as a namespace proxy

A recent article by James Edwads piqued my interest. "My Favorite JavaScript Design Patter" has obviously been misunderstood by many commentators, who think that it may also rely on the module pattern. This article promotes a variety of techniques (probably confusing the reader), but at its core is a bit of genius that I've modified and presented as a namespace tool.

The beauty of this pattern is that it is used simply the way the language was designed - no more, no less, no opportunism, no tricks. Additionally because the namespace is injected via the

this keyword (which is immutable within a given execution context), it cannot be accidentally modified.

var myApp = {};
(function() {
    var id = 0;

    this.next = function() {
        return id++;    
    };

    this.reset = function() {
        id = 0;     
    }
}).apply(myApp);    

window.console && console.log(
    myApp.next(),
    myApp.next(),
    myApp.reset(),
    myApp.next()
); //0, 1, undefined, 0

Even better, the

apply (and call) API provides natural isolation from context and parameters – so passing additional parameters to the module creator is very clean . The following example illustrates this and shows how to run modules independently of multiple namespaces.

var subsys1 = {}, subsys2 = {};
var nextIdMod = function(startId) {
    var id = startId || 0;
    this.next = function() {
        return id++;    
    };
    this.reset = function() {
        id = 0;     
    }
};
nextIdMod.call(subsys1);    
nextIdMod.call(subsys2,1000);   
window.console && console.log(
    subsys1.next(),
    subsys1.next(),
    subsys2.next(),
    subsys1.reset(),
    subsys2.next(),
    subsys1.next()
) //0, 1, 1000, undefined, 1001, 0

Of course if we need a global id generator, it’s very simple...

nextIdMod();    
window.console && console.log(
    next(),
    next(),
    reset(),
    next()
) //0, 1, undefined, 0

这个我们作为例子使用的 id 生成器工具并没有表现出这个模式的全部潜力。通过包裹一整个库和使用this关键字作为命名空间的替身,我们使得用户在任何他们选择的上下文中运行这个库很轻松(包括全局上下文)。

//library code
var protoQueryMooJo = function() {  
    //everything
}
//user code
var thirdParty = {};
protoQueryMooJo.apply(thirdParty);

其他的考虑

我希望避免命名空间嵌套。它们很难追踪(对人和电脑都是)并且它们会让你的代码因为一些乱七八糟的东西变得很多。如 Peter Michaux 指出的,深度嵌套的命名空间可能是那些视图重新创建他们熟悉和热爱的长包链的老派 Java 开发者的遗产。

通过 .js 文件来固定一个单独的命名空间也是可以的(虽然只能通过命名空间注入或者直接分配每一个变量),不过你应该对依赖谨慎些。此外将命名空间绑定到文件上可以帮助读者更轻易弄清整个代码。

因为 JavaScript 并没有正式的命名空间结构,所以有很多自然形成的方法。这个调查只详细说明了其中的一部分,可能有更好的技术我没有发现。我很乐意知道它们。

 以上就是JavaScript 中的命名空间详细介绍的内容,更多相关内容请关注PHP中文网(www.php.cn)!

Statement
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn
JavaScript Comments: A Guide to Using // and /* */JavaScript Comments: A Guide to Using // and /* */May 13, 2025 pm 03:49 PM

JavaScriptusestwotypesofcomments:single-line(//)andmulti-line(//).1)Use//forquicknotesorsingle-lineexplanations.2)Use//forlongerexplanationsorcommentingoutblocksofcode.Commentsshouldexplainthe'why',notthe'what',andbeplacedabovetherelevantcodeforclari

Python vs. JavaScript: A Comparative Analysis for DevelopersPython vs. JavaScript: A Comparative Analysis for DevelopersMay 09, 2025 am 12:22 AM

The main difference between Python and JavaScript is the type system and application scenarios. 1. Python uses dynamic types, suitable for scientific computing and data analysis. 2. JavaScript adopts weak types and is widely used in front-end and full-stack development. The two have their own advantages in asynchronous programming and performance optimization, and should be decided according to project requirements when choosing.

Python vs. JavaScript: Choosing the Right Tool for the JobPython vs. JavaScript: Choosing the Right Tool for the JobMay 08, 2025 am 12:10 AM

Whether to choose Python or JavaScript depends on the project type: 1) Choose Python for data science and automation tasks; 2) Choose JavaScript for front-end and full-stack development. Python is favored for its powerful library in data processing and automation, while JavaScript is indispensable for its advantages in web interaction and full-stack development.

Python and JavaScript: Understanding the Strengths of EachPython and JavaScript: Understanding the Strengths of EachMay 06, 2025 am 12:15 AM

Python and JavaScript each have their own advantages, and the choice depends on project needs and personal preferences. 1. Python is easy to learn, with concise syntax, suitable for data science and back-end development, but has a slow execution speed. 2. JavaScript is everywhere in front-end development and has strong asynchronous programming capabilities. Node.js makes it suitable for full-stack development, but the syntax may be complex and error-prone.

JavaScript's Core: Is It Built on C or C  ?JavaScript's Core: Is It Built on C or C ?May 05, 2025 am 12:07 AM

JavaScriptisnotbuiltonCorC ;it'saninterpretedlanguagethatrunsonenginesoftenwritteninC .1)JavaScriptwasdesignedasalightweight,interpretedlanguageforwebbrowsers.2)EnginesevolvedfromsimpleinterpreterstoJITcompilers,typicallyinC ,improvingperformance.

JavaScript Applications: From Front-End to Back-EndJavaScript Applications: From Front-End to Back-EndMay 04, 2025 am 12:12 AM

JavaScript can be used for front-end and back-end development. The front-end enhances the user experience through DOM operations, and the back-end handles server tasks through Node.js. 1. Front-end example: Change the content of the web page text. 2. Backend example: Create a Node.js server.

Python vs. JavaScript: Which Language Should You Learn?Python vs. JavaScript: Which Language Should You Learn?May 03, 2025 am 12:10 AM

Choosing Python or JavaScript should be based on career development, learning curve and ecosystem: 1) Career development: Python is suitable for data science and back-end development, while JavaScript is suitable for front-end and full-stack development. 2) Learning curve: Python syntax is concise and suitable for beginners; JavaScript syntax is flexible. 3) Ecosystem: Python has rich scientific computing libraries, and JavaScript has a powerful front-end framework.

JavaScript Frameworks: Powering Modern Web DevelopmentJavaScript Frameworks: Powering Modern Web DevelopmentMay 02, 2025 am 12:04 AM

The power of the JavaScript framework lies in simplifying development, improving user experience and application performance. When choosing a framework, consider: 1. Project size and complexity, 2. Team experience, 3. Ecosystem and community support.

See all articles

Hot AI Tools

Undresser.AI Undress

Undresser.AI Undress

AI-powered app for creating realistic nude photos

AI Clothes Remover

AI Clothes Remover

Online AI tool for removing clothes from photos.

Undress AI Tool

Undress AI Tool

Undress images for free

Clothoff.io

Clothoff.io

AI clothes remover

Video Face Swap

Video Face Swap

Swap faces in any video effortlessly with our completely free AI face swap tool!

Hot Article

Hot Tools

PhpStorm Mac version

PhpStorm Mac version

The latest (2018.2.1) professional PHP integrated development tool

DVWA

DVWA

Damn Vulnerable Web App (DVWA) is a PHP/MySQL web application that is very vulnerable. Its main goals are to be an aid for security professionals to test their skills and tools in a legal environment, to help web developers better understand the process of securing web applications, and to help teachers/students teach/learn in a classroom environment Web application security. The goal of DVWA is to practice some of the most common web vulnerabilities through a simple and straightforward interface, with varying degrees of difficulty. Please note that this software

SublimeText3 Chinese version

SublimeText3 Chinese version

Chinese version, very easy to use

SecLists

SecLists

SecLists is the ultimate security tester's companion. It is a collection of various types of lists that are frequently used during security assessments, all in one place. SecLists helps make security testing more efficient and productive by conveniently providing all the lists a security tester might need. List types include usernames, passwords, URLs, fuzzing payloads, sensitive data patterns, web shells, and more. The tester can simply pull this repository onto a new test machine and he will have access to every type of list he needs.

Dreamweaver Mac version

Dreamweaver Mac version

Visual web development tools