A 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.
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
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
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
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
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)!

Hot AI Tools

Undresser.AI Undress
AI-powered app for creating realistic nude photos

AI Clothes Remover
Online AI tool for removing clothes from photos.

Undress AI Tool
Undress images for free

Clothoff.io
AI clothes remover

AI Hentai Generator
Generate AI Hentai for free.

Hot Article

Hot Tools

Notepad++7.3.1
Easy-to-use and free code editor

SublimeText3 Chinese version
Chinese version, very easy to use

Zend Studio 13.0.1
Powerful PHP integrated development environment

Dreamweaver CS6
Visual web development tools

SublimeText3 Mac version
God-level code editing software (SublimeText3)

Hot Topics



How to use WebSocket and JavaScript to implement an online speech recognition system Introduction: With the continuous development of technology, speech recognition technology has become an important part of the field of artificial intelligence. The online speech recognition system based on WebSocket and JavaScript has the characteristics of low latency, real-time and cross-platform, and has become a widely used solution. This article will introduce how to use WebSocket and JavaScript to implement an online speech recognition system.

WebSocket and JavaScript: Key technologies for realizing real-time monitoring systems Introduction: With the rapid development of Internet technology, real-time monitoring systems have been widely used in various fields. One of the key technologies to achieve real-time monitoring is the combination of WebSocket and JavaScript. This article will introduce the application of WebSocket and JavaScript in real-time monitoring systems, give code examples, and explain their implementation principles in detail. 1. WebSocket technology

Introduction to how to use JavaScript and WebSocket to implement a real-time online ordering system: With the popularity of the Internet and the advancement of technology, more and more restaurants have begun to provide online ordering services. In order to implement a real-time online ordering system, we can use JavaScript and WebSocket technology. WebSocket is a full-duplex communication protocol based on the TCP protocol, which can realize real-time two-way communication between the client and the server. In the real-time online ordering system, when the user selects dishes and places an order

How to use WebSocket and JavaScript to implement an online reservation system. In today's digital era, more and more businesses and services need to provide online reservation functions. It is crucial to implement an efficient and real-time online reservation system. This article will introduce how to use WebSocket and JavaScript to implement an online reservation system, and provide specific code examples. 1. What is WebSocket? WebSocket is a full-duplex method on a single TCP connection.

JavaScript and WebSocket: Building an efficient real-time weather forecast system Introduction: Today, the accuracy of weather forecasts is of great significance to daily life and decision-making. As technology develops, we can provide more accurate and reliable weather forecasts by obtaining weather data in real time. In this article, we will learn how to use JavaScript and WebSocket technology to build an efficient real-time weather forecast system. This article will demonstrate the implementation process through specific code examples. We

JavaScript tutorial: How to get HTTP status code, specific code examples are required. Preface: In web development, data interaction with the server is often involved. When communicating with the server, we often need to obtain the returned HTTP status code to determine whether the operation is successful, and perform corresponding processing based on different status codes. This article will teach you how to use JavaScript to obtain HTTP status codes and provide some practical code examples. Using XMLHttpRequest

Introduction to the method of obtaining HTTP status code in JavaScript: In front-end development, we often need to deal with the interaction with the back-end interface, and HTTP status code is a very important part of it. Understanding and obtaining HTTP status codes helps us better handle the data returned by the interface. This article will introduce how to use JavaScript to obtain HTTP status codes and provide specific code examples. 1. What is HTTP status code? HTTP status code means that when the browser initiates a request to the server, the service

JavaScript is a programming language widely used in web development, while WebSocket is a network protocol used for real-time communication. Combining the powerful functions of the two, we can create an efficient real-time image processing system. This article will introduce how to implement this system using JavaScript and WebSocket, and provide specific code examples. First, we need to clarify the requirements and goals of the real-time image processing system. Suppose we have a camera device that can collect real-time image data
