原型和命名空间之间的差异

时间:2014-01-28 08:21:23

标签: javascript

在命名空间中,我们可以使用以下内容:

var namespace = {};
namespace.something.nested.namespacing();

而且在原型中我们可以使用相同名称命名空间:

something.prototype.method();

在这两种类型中,我们都使用. notation。那么,我们如何确定代码是使用命名空间还是原型?

3 个答案:

答案 0 :(得分:7)

JavaScript没有名称空间。你所谓的名称空间只是一个对象。使用对象代替命名空间是相当普遍的。

您的代码:

var namespace = {};
namespace.something.nested.namespacing();

...创建一个对象和一个引用该对象的变量namespace。然后你向该对象添加属性(看起来你已经添加了一个属性something,它也是一个对象,它有一个属性nested,它也是 一个对象,它有一个名为namespacing的属性,它引用一个函数。)

您的代码:

something.prototype.method();

...也在使用一个对象。上面实际上是一个非常不寻常的事情,你通过直接引用我假设的函数method属性来调用函数(prototype)(something) 。那通常不是你要做的。通常你会通过函数创建一个对象:

var s = new something();

...然后使用隐式分配给s的原型:

s.method();

函数的prototype属性可能会让刚接触JavaScript的人感到困惑。它只是一个普通的属性,就像在函数实例上的任何其他属性一样。唯一让它变得特别的是new运算符:当您通过new调用函数时:

var s = new something();

... JavaScript引擎创建一个新的空白对象,然后使用__proto__设置其基础原型(有时称为something.prototype,但不在规范中),如下所示:

// pseudo-code for `var s = new something()`
var tmp = {};                        // New, blank object
tmp.__proto__ = something.prototype; // Assign a prototype to the new object
something.call(tmp);                 // Call `something` with `this` referring to `tmp`
s = tmp;                             // Assign the result to `s`

(我在上面省略了一个细节,以避免混淆事项,与something中有一个显式return语句的特殊情况有关,返回一个对象引用。 )

答案 1 :(得分:4)

好吧,命名空间只是对象而原型对象是对象,所以从语法的角度来看,访问它们的方式没有区别(foo.bar称为点符号(

然而,它们有两个根本不同的目的:

  • 命名空间用于构建代码并避免全局命名空间污染。
  • 原型用于在同一构造函数的多个实例之间共享方法。

所以你通常不直接在原型上调用方法,因为它很可能不起作用。此方法的目的是在相应构造函数的实例上调用。例如:

function Something() {}
Something.prototype.foo = function() {};

var s = new Something();
s.foo();

答案 2 :(得分:3)

.表示法是javascript中用于访问任何对象的任何属性的非常通用的工具。

var x = {};
x.val = 2;

您对命名空间的引用只是javascript中的通用对象,因为javascript中没有实际的命名空间类型。换句话说,普通对象用于在javascript中创建类似命名空间的东西。因此,对象属性用于跟踪命名空间中的名称。


.符号与原型一起使用是访问特定类型对象(原型)上的属性的一个特定实例。原型用于函数对象,在创建该函数的新实例时具有非常特殊的用途。

function foo() {
}

foo.prototype.talk = function() {
    alert("hello");
}

var y = new foo();
y.talk();