如何将原型模式引入 javascript 命名空间

How to introduce the prototype pattern to javascript namespace

本文关键字:javascript 命名空间 模式 原型      更新时间:2023-09-26

在我开始之前,我想承认我是一个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"关键字

定义方法

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

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;