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

时间:2013-09-25 06:04:11

标签: javascript prototype

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

1 个答案:

答案 0 :(得分:7)

定义方法

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

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
  3. 关于undefined的检查,我怀疑你需要它。如果你的代码与使用'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;