Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/variables/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
带有函数原型的Javascript命名空间声明_Javascript_Class_Namespaces_Function Prototypes - Fatal编程技术网

带有函数原型的Javascript命名空间声明

带有函数原型的Javascript命名空间声明,javascript,class,namespaces,function-prototypes,Javascript,Class,Namespaces,Function Prototypes,我知道,这经常被讨论。但在像19世纪的人一样四处寻找之后,我需要一些建议。声明一个“名称空间”并没有问题,但当涉及prototype.foo函数时,我就卡住了。我找到了一种方法,但我不喜欢: Namespace = {} Namespace.obj = function() { this.foo="bar"; } Namespace.obj.prototype.start = function() { this.foo="fubar"; } blah = new Namespa

我知道,这经常被讨论。但在像19世纪的人一样四处寻找之后,我需要一些建议。声明一个“名称空间”并没有问题,但当涉及prototype.foo函数时,我就卡住了。我找到了一种方法,但我不喜欢:

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

blah = new Namespace.obj();
blah.start();
现在,由于我对脚本编写有点神经质,我希望有这样的东西:

Namespace = {
    obj: function() {
        this.foo="bar";
    },
    obj.prototype.start: function(tabinst) {
        this.foo="fubar";
    }
}
...
但随后它抛出了一个错误: “未捕获的语法错误:意外标记。”


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

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

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

Namespace = {};

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

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

console.log( Namespace.obj.prototype );
(看这把小提琴)

编辑:哇,我刚刚注意到我说的已经在问题范围之内了。我很抱歉没有早点注意到。。。你描述自己的方式是实现这一目标的正确方法

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

编辑2:看到这把小提琴了吗

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


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

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

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”类方法和构造函数,我们可以执行以下操作:

/** Class obj **/
var obj = (function () {
    /** class Constructor **/
    var obj = function () {
        this.foo = 'bar';
    };
    /** class methods **/
    obj.prototype = {
        start: function () {
            this.foo = 'fubar';
        }
    };
    return obj;
})();
/** 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

还有一个重要的特征是免费使用这个模式,它是“私有变量”,考虑以下内容:

/** Class obj **/
var obj = (function () {
    /** class Constructor **/
    var obj = function () {
        this.foo = 'bar';
    };
    /** class methods **/
    obj.prototype = {
        start: function () {
            this.foo = 'fubar';
        }
    };
    return obj;
})();
/** 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

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

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()

编辑中的第一个代码段将不会像您所想的那样工作
obj.main
obj.prototype
是两个不同的独立功能。是的,
如果您在不使用
new
的情况下调用它们,
将引用同一对象,但这只是因为它引用了
窗口
。因此,您将使
foo
成为全局的。您的第二个示例将
名称空间
限制为仅包含一个“类”,这在某种程度上违背了名称空间的用途。您对第一个示例的回答是正确的,我觉得没有尽早注意到这一点很愚蠢,但我不同意第二个示例。为什么它只限于一个“类”?如果您使用更多的对象,它将遍历这些对象并为它们指定正确的原型值。啊,没错,您有
obj
内部
prototype
。。。。我错过了。对不起。我仍然认为这不是一个简单的方法。Thans Amjad,这很好。但现在我又绊倒了。我看得对吗:使用这种方法,不可能生成从obj分离的Namespace.blah()函数?@Johnny如果我没有弄错你的问题,只需在返回对象中添加一个
blah
函数:
。返回{obj:obj,obj2:obj2,blah:function(){/*dosomething*/}阿姆贾德,非常感谢。这正是我想要的!现在我明白了。