简体   繁体   English

在javascript中,对象和命名空间之间有什么区别?

[英]In javascript, what is the difference between an object and a namespace?

While reading " Object-Oriented JavaScript " on Mozilla's website, I stumbled upon this note: 在Mozilla网站上阅读“ 面向对象的JavaScript ”时,我偶然发现了这个问题:

It's important to note that in JavaScript there's no language-level difference between regular objects and namespaces. 值得注意的是,在JavaScript中,常规对象和命名空间之间没有语言级差异

However, the note is not clear about what is meant by "language-level difference". 但是,该说明并未明确“语言级差异”的含义。

Does it mean there are two ways of writing the same thing? 这是否意味着有两种方法可以写同样的东西? Or that there are two terms that refer to the same thing? 或者说有两个术语指的是同一个东西?

You've taken the quote out of context. 你已经脱离了背景。 The answer is in the paragraph above the quote : 答案在报价上方的段落中

A namespace is a container which allows developers to bundle up functionality under a unique, application-specific name. 命名空间是一个容器,允许开发人员在一个独特的,特定于应用程序的名称下捆绑功能。 In JavaScript a namespace is just another object containing methods, properties, and objects . 在JavaScript中,命名空间只是包含方法,属性和对象的另一个对象

(Emphasis mine) (强调我的)

The quote: 报价单:

It's important to note that in JavaScript there's no language-level difference between regular objects and namespaces . 值得注意的是,在JavaScript中,常规对象和命名空间之间没有语言级差异

Is just saying that this means a "namespace" is just a object used as a "namespace". 只是说这意味着“命名空间”只是一个用作“命名空间”的对象。
There are no "real" namespaces in JS. JS中没有“真正的”命名空间。

Some languages have an actual namespace which is not the same thing as an object. 有些语言的实际名称空间与对象不同。 JavaScript is not one of those languages, so objects are used for this purpose. JavaScript不是这些语言之一,因此对象用于此目的。

For example, the Math functions like Math.round and Math.abs , are all namespaced in the Math object. 例如, Math.roundMath.absMath函数都在Math对象中命名空间。 They aren't really contextual methods like toString is (at least not in any implementation I've found), just collected under an object to keep it organized. 它们不是真正的上下文方法,比如toString (至少在我发现的任何实现中都没有),只是在一个对象下收集以保持它有条理。 * *


* They are technically methods, because they are accessible by a property on an object (a definition that technically makes all global functions methods because they are available through the global object (ie. window.Function() )), but unlike methods like toString , or the methods of most console implementations like console.log they do not depend on the object they are called on and the this value is irrelevant. *它们在技术上是方法,因为它们可以通过对象上的属性访问(技术上制定所有全局函数方法的定义,因为它们可以通过全局对象(即window.Function() )获得),但不像toString这样的toString ,或大多数console实现的方法,如console.log它们不依赖于它们被调用的对象,并且this值是无关紧要的。 The Math object is used purely for namespacing, not because of the context it gives. Math对象仅用于命名空间,而不是因为它提供的上下文。

First, are you sure you know what a namespace is? 首先,您确定知道命名空间是什么吗? Real Quick: 真正快速:

Let's use an analogy. 让我们用一个类比。 On your computer you have files. 在您的计算机上,您有文件。 But you don't just have files you have folders. 但是你不只是拥有文件夹的文件。 Why? 为什么?

Because if there were no folder every file name would have to be unique and it would be hard to keep things organized. 因为如果没有文件夹,每个文件名都必须是唯一的,并且很难保持组织有序。

Same for variables names if you only had global variables. 如果您只有全局变量,则变量名称也相同。 If you could only have global variables every variable name would have to be completely unique. 如果您只能拥有全局变量,则每个变量名称都必须完全唯一。

This would be very difficult to keep track of. 这很难跟踪。 Chances are you would probably end up using the same variable name by accident. 您可能会偶然使用相同的变量名称。 Your code would act funny and it would be very difficult to track down the problem. 你的代码会很有趣,很难找到问题所在。

So what's the solution? 那么解决方案是什么?

That's right put your variables into folders, ahem, sorry, I meant namespaces, put them into namespaces. 这是正确的把你的变量放到文件夹,嗯,对不起,我的意思是命名空间,把它们放入命名空间。 I gotta figure out how to use the backspace key. 我得弄清楚如何使用退格键。

Anyway, languages like C# and Java let you do exactly this: 无论如何,像C#和Java这样的语言可以让你做到这一点:

// C# - example of a language with built in support for namespaces

namespace MySpace {
    class MyClass {
    }
}

namespace Facebook {
    class MyClass {
    }
}

There no conflict because the classes are in different namespaces. 没有冲突,因为类在不同的名称空间中。 Then in your code if you wanted to instantiate them you would write something like this: 然后在你的代码中,如果你想实例化它们,你会写这样的东西:

// C# again (JavaScript code coming up soon - keep scrolling)
var myObject = new Facebook.MyClass();

That's great but JavaScript doesn't have a namespace keyword. 这很好,但JavaScript没有namespace关键字。 Technically it doesn't have namespaces, what it does have is some really clever programmers. 从技术上讲,它没有名称空间,它拥有的是一些非常聪明的程序员。

Their solution? 他们的解答? Use objects. 使用对象。

// JavaScript
var MySpace = {};
MySpace.MyFunction = function() {
    // insert brilliant code here
};

var Facebook = {};
Facebook.MyFunction = function() {
    // insert more brilliant code here
};

Now you have 2 functions with the "same" name that don't get in the way of each other. 现在,您有两个具有“相同”名称的功能,这些功能不会妨碍彼此。 If you want to call the Facebook version of MyFunction you would write code like this: 如果你想调用Facebook版本的MyFunction你会写这样的代码:

// JavaScript
Facebook.MyFunction();

As you can see in these examples MySpace and Facebook are really objects, but they are objects that we are using only to separate functions and variables, which means we're using them for nothing more than to serve as namespaces. 正如您在这些示例中看到的那样, MySpaceFacebook实际上是对象,但它们是我们仅用于分离函数和变量的对象,这意味着我们只使用它们作为命名空间。

One Extra Note 一个额外的说明

A lot of times you will see "namespace" objects declared like this: 很多时候你会看到像这样声明的“namespace”对象:

var MySpace = MySpace || {};

This means MySpace = MySpace if the MySpace object already exists. 这意味着如果MySpace对象已经存在, MySpace = MySpace Otherwise it's assigned a new empty object. 否则,它会被分配一个新的空对象。 This is a way of reusing the MySpace object/namespace in multiple files. 这是在多个文件中重用MySpace对象/命名空间的一种方法。

Each file adds it's own functions and variables to the same "namespace" object. 每个文件都将自己的函数和变量添加到同一个“命名空间”对象中。 For example: 例如:

var MySpace = MySpace || {};
MySpace.a = 10;

var MySpace = MySpace || {};
MySpace.b = 20;

You end up with one MySpace object with the variables a and b . 最终得到一个带有变量ab MySpace对象。 This is true even if the code were in different files and even if you reverse the order. 即使代码位于不同的文件中,即使您颠倒了顺序,也是如此。

It's important to note that in JavaScript there's no language-level difference between regular objects and namespaces. 值得注意的是,在JavaScript中,常规对象和命名空间之间没有语言级差异。

It's saying that a "namespace" is not an actual type of component in JavaScript, but rather just another use of a plain old JavaScript object. 它说“命名空间”不是JavaScript中的实际类型的组件,而只是普通旧JavaScript对象的另一种用法。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM