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

如何将原型模式引入javascript名称空间,javascript,prototype,Javascript,Prototype,在我开始之前,我想承认我是一个JavaScript新手,对JavaScript模式和术语了解很少,所以请随意向我解释基本概念,就像我5岁一样 我以前在工作中使用过JavaScript原型模式,效果非常好 这是我以前使用原型模式的工作的一个示例 var SomeNameSpace = SomeNameSpace || {}; SomeNameSpace.SomeClass = function(oSomeParameter){ this.SomeProperty = oSomeParam

在我开始之前,我想承认我是一个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
,但如果在其他地方定义了名称空间,则确保不覆盖该名称空间。对于大多数用例来说,它已经足够了,并且它的优点是对于大多数阅读您的代码的人来说非常简洁和清晰

第二个示例与第一个示例类似,但有两个区别:

  • 特别检查
    a
    在定义之前是否未定义(ex1仅检查是否存在错误,这通常就足够了)
  • 将_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;
    

    首先尝试验证语法,它看起来不正确。
    SomeClass=function…
    。检查这里您在第一个示例中忘记了
    new
    。谢谢!我会记住的!最后,我应该像示例1或示例2中那样声明我的名称空间吗?很难在注释中解释,因此我将很快更新我的答案。非常感谢您花时间向我如此详细地解释这一点!要回答您的问题,不,没有理由使用| u名称空间(我强烈怀疑编写它的人不知道为什么要包含它,因为代码中有许多不一致之处)只是最后一个问题,因此最好使用a=a |{};VarA语句不是在局部范围内声明变量,而是在全局范围内声明变量。如果您希望名称空间仅在特定范围内定义(-在特定函数内),则需要使用var a。通常情况并非如此,只有一个例外:iLife(谷歌it)。由于您已经将所有内容包装在名称空间中,因此不会污染范围,因此不需要IIFE。PS:您可能在全局范围内定义了名称空间,所以有/没有var都是一样的。再次感谢您,但是如何在名称空间内声明属性呢?是否编写SomeNamespace.SomeProperty=“Some Value”;