4

在开始之前,我想承认我是一名 JavaScript 新手,我对 JavaScript 模式和术语知之甚少,所以请随时向我解释基本概念,就像我 5 岁一样!

我以前在我的工作中使用过 JavaScript 原型模式,效果很好。

这是我以前使用原型模式工作的示例

var SomeNameSpace = SomeNameSpace || {};
SomeNameSpace.SomeClass = function(oSomeParameter){
     this.SomeProperty = oSomeParameter
     ...
}

SomeNameSpace.SomeClass.prototype = {
     SomeClassMethod: function (oSomeOtherParameter) {//code here}
}

var someClassInstance = new SomeNameSpace.SomeClass("some string");
var result = someClassInstance.SomeClassMethod("some other string");

该片段是我一直使用 javascript 的一个示例

我负责支持一些新的 javascript 代码。我想在这个新库中引入相同类型的原型模式。但是,命名空间的编写方式对我来说是陌生的,我不知道如何修改它以满足我的需要。

一个例子

if (typeof SomeNamespace == "undefined") {
    SomeNamespace = { __namespace: true };
}



 SomeNamespace.SomeOtherNamespace = {
     SomeClass: function(oSomeParameter){
          this.SomeProperty = oSomeParameter
          ...
     }
 }

我不知道如何在这段代码中添加原型函数......

(抱歉,如果我对细节含糊不清,我什至不确定为什么在我的第二个示例中如此声明命名空间,所以如果有人可以向我解释,那就太好了!)

*编辑* 更正了第二个示例中的语法

*编辑* 在我的示例中省略了“new”关键字

4

1 回答 1

8

定义方法

这段代码在语法上不正确:

SomeNamespace.SomeOtherNamespace = {
     SomeClass = function(oSomeParameter){  // you probably have : instead of =
          this.SomeProperty = oSomeParameter
          ...
     }
 }

要在第二个示例中添加实例方法,您可以在 SomeClass 的定义之后简单地做:

SomeNamespace.SomeotherNamespace.SomeClass.prototype.SomeClassMethod = function() {
};

在您提到的第一种和第二种方式中,您的代码都希望显示这些函数(第一个示例中的实例方法,第二个示例中的类)都属于同一个对象(第一个示例中的原型,第二个示例中的命名空间)。对于一些属性来说,这一切都很好,但我发现当您处理具有许多方法的类时,或者更糟糕的是,具有许多类的命名空间时,这会变得更加麻烦。

我建议您使用不同的文件将代码分开并将它们一起缩小。一个文件夹代表一个命名空间,一个文件代表一个类。遵循第一个示例中的模式,但不要说“这是具有这些方法的原型对象”,而是使用上面的示例行一次添加一个。

声明命名空间

首先,我们需要在同一页面上。在 JavaScript 中,命名空间只是一个对象(包含您感兴趣的任何属性、构造函数、静态函数 - 出厂方法、其他命名空间等)。

第一个示例a = a || {}确保a定义了名称空间,但如果它在其他地方定义,请确保不要覆盖它。对于大多数用例来说,这已经足够了,而且它的优点是对于大多数阅读您的代码的人来说非常简洁明了。

第二个示例与第一个示例类似,但有两个不同之处:

  1. 在定义之前专门检查a未定义的内容(ex1 只检查虚假性,这通常就足够了)
  2. 将 _namespace 属性添加到a

关于未定义的检查,我怀疑你需要它。如果您的代码与使用“a”而不是对象的东西发生冲突,那么无论使用哪种方法,都很有可能会发生故障。

_namespace 属性对于我认为的代码来说纯粹是常规的。它可能对各种工具有所帮助(可能在调试期间或用于自动文档生成),但这就是我能想到的全部。显然,您可以更好地查看它是否实际用于某事,因此如果您遇到有趣的用法,也许您可​​以发表评论。

总而言之,我更喜欢第一个变体,因为它更简洁,甚至更频繁(阅读代码的人更容易识别)。

完整示例:

// class definition
a = a || {}; // global namespace, all good
a.b = a.b || {}; // both lines are needed

a.b.Class = function() {
  this.myProp = 'hello';
};

a.b.Class.prototype.myMethod = function() {
};


// usage
var myInstance = new a.b.Class();
instance.myMethod();
var x = instance.myProp;
于 2013-09-25T06:19:35.587 回答