在命名空间中,我们可以使用以下内容:
var namespace = {};
namespace.something.nested.namespacing();
而且在原型中我们可以使用相同名称命名空间:
something.prototype.method();
在这两种类型中,我们都使用. notation
。那么,我们如何确定代码是使用命名空间还是原型?
答案 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();