首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >使用function-prototype声明Javascript命名空间

使用function-prototype声明Javascript命名空间
EN

Stack Overflow用户
提问于 2011-08-21 19:00:46
回答 3查看 12.8K关注 0票数 18

我知道,这是经常讨论的。但在像19世纪的人一样四处寻找之后,我需要一些建议。我可以声明一个“名称空间”,但是当涉及到prototype.foo函数时,我就坚持了下来。我找到了一种方法,但我不喜欢:

代码语言:javascript
复制
Namespace = {}
Namespace.obj = function() {
    this.foo="bar";
}
Namespace.obj.prototype.start = function() {
    this.foo="fubar";
}

blah = new Namespace.obj();
blah.start();

现在,由于我在脚本编写方面有点神经质,我希望有这样的东西:

代码语言:javascript
复制
Namespace = {
    obj: function() {
        this.foo="bar";
    },
    obj.prototype.start: function(tabinst) {
        this.foo="fubar";
    }
}
...

但随后它抛出一个错误:“未捕获SyntaxError:意想不到的标记。”

我知道,这是表面上的,但我认为必须有更好的方法来声明包含类和原型函数的“命名空间”。

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2011-08-21 19:48:02

我要做的就是使用"Module pattern"

你基本上将所有的“模块”逻辑封装在一个自动执行的函数中,该函数将返回一个包含你的类、函数、变量等的对象……将返回值视为公开模块API。

代码语言:javascript
复制
Namespace = (function () {
    /** Class obj **/
    var obj = function () {
        this.foo = 'bar';
    };
    obj.prototype = {
        start: function () {
            this.foo = 'fubar';
        }
    };

    /** Class obj2 **/  
    var obj2 = function () {
        this.bar = 'foo'
    };
    obj2.prototype = {
        start: function () {
            this.bar = 'barfoo';
        },
        end: function () {
            this.bar = '';
        }
    };
    return {
        obj : obj,
        obj2: obj2
    };
})();

var o = new Namespace.obj()
o.start()

为了进一步封装"obj“类方法和构造函数,我们可以执行以下操作:

代码语言:javascript
复制
/** Class obj **/
var obj = (function () {
    /** class Constructor **/
    var obj = function () {
        this.foo = 'bar';
    };
    /** class methods **/
    obj.prototype = {
        start: function () {
            this.foo = 'fubar';
        }
    };
    return obj;
})();

使用此模式还有一个免费的重要特性,即“私有变量”,请考虑以下几点:

代码语言:javascript
复制
/** Class Foo **/
var Foo = (function () {
    // Private variables
    var private_number = 200
    /** class Constructor **/
    var Foo = function () {
        this.bar = 0;
    };
    /** class methods **/
    Foo.prototype = {
        add: function () {
            this.bar += private_number;
        }
    };
    return Foo;
})();

foo = new Foo();
alert(foo.bar); // 0
foo.add(); 
alert(foo.bar);// 200
alert(foo.private_number) //undefined
票数 34
EN

Stack Overflow用户

发布于 2011-08-21 19:13:52

是,因为您不能在对象声明中使用此类型的链接

这里是obj.prototype或obj.something,因为该语言将obj视为非对象的值。你可以像这样伪造这样的效果

代码语言:javascript
复制
Namespace = {};

Namespace.obj =function() {
        this.foo="bar";
};

Namespace.obj.prototype.start = function(tabinst) {
        this.foo="fubar";
};

console.log( Namespace.obj.prototype );

(请参阅此fiddle http://jsfiddle.net/WewnF/ )

编辑:哇,我刚刚注意到我说的话已经在问题中了。我很抱歉没有注意到更早……好吧,你描述自己的方式是实现这一目标的正确方法。

否则,你可以像这样重写你的代码--但这并不是你想要的,也不会以同样的方式工作(因为obj本身不是一个函数,你必须像这样调用它的主函数obj.main();)

代码语言:javascript
复制
Namespace = {
    obj: {
          main : function() {
               this.foo="bar";
          },
          prototype : {
             start: function(tabinst) {
             this.foo="fubar";
             }
          }
    }
}

编辑2:查看此小提琴http://jsfiddle.net/NmA3v/1/

代码语言:javascript
复制
Namespace = {
    obj: function() {
        this.foo="bar";
    },
    prototype: {
        obj : {
            start : function( hi ) {
                 alert( hi ); 
            }  
        }

    },

    initProto : function(){
        for( var key in Namespace )
        {
            if( key !== "prototype" )
            {
                for( var jey in Namespace.prototype[ key ] )
                    Namespace[ key ].prototype[ jey ] =  Namespace.prototype[ key ][ jey ];  
            }
        }
    }
}

Namespace.initProto();

console.log( Namespace.obj);

var test  = new Namespace.obj();

test.start( "Hello World" );

这将具有完全相同的效果。解释:我们将我们的对象声明为普通的属性-函数,然后使用一个主原型对象,该对象包含与上面相同的名称的对象,例如,对于每个Namespace.obj,还有一个包含我们想要添加到原型链中的函数的Namespace.prototype.obj。

然后使用namespace.protoInit()遍历所有属性-并从Namespace.prototype键提取函数并将它们添加到Namespace键.prototype -成功地扩展了原型对象!有点不正统,但很管用!

票数 3
EN

Stack Overflow用户

发布于 2015-09-04 06:58:03

只是为了好玩,并在上面的答案上进行扩展。基于嵌套命名空间的更多面向对象的表示法

代码语言:javascript
复制
var NS = {};

// Class List
NS.Classes = {
  Shape: (function(){
    // Private
    var whateveryouwishboss = false;

    // Public
    var Shape = function(x,y,w,h){
      this.x = x;
      this.y = y;
      this.w = w;
      this.h = h;
    };
    Shape.prototype = {
      draw: function(){
        //... Im on prototype Shape 
      }
    }
    return Shape;
  })(),
  Person: (function(){
    //....
  })()
}

/////// Let the games begin

var rect = new NS.Class.Shape(0,0,10,10);
rect.draw()
票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/7137860

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档