如何封装一个构造函数?

9

我有这段JavaScript代码:

var Type = function(name) {
    this.name = name;
};

var t = new Type();

现在我想添加这个:
var wrap = function(cls) {
    // ... wrap constructor of Type ...
    this.extraField = 1;
};

因此我可以做:

wrap(Type);
var t = new Type();

assertEquals(1, t.extraField);

[编辑] 我需要一个实例属性,而不是一个类(静态/共享)属性。

在包装函数中执行的代码应该像我将其粘贴到真正的构造函数中一样工作。

Type 的类型不应更改。


1
据我理解,您想要向构造函数添加一个额外的属性,以便进一步创建新实例具有该属性? - Joseph
也许你只需要改变 wrap() 函数中 Type 的原型。例如:var wrap = function(cls) { cls.prototype.extraField=1; };?或者最好创建一个新的 Type2 继承自 Type 并附加额外的 extraField 成员? - Andrew D.
你能更详细地描述一下你的问题吗? - seteh
我想要一个实例属性,而不是类(静态/共享)属性。在包装函数中执行的代码应该像我将其粘贴到真正的构造函数中一样工作。 - Aaron Digulla
1个回答

8

更新:这里有更新版本

你实际上想要的是将Type扩展到另一个类中。在JavaScript中有很多方法可以做到这一点。我并不是很喜欢使用newprototype构建“类”的方式(我更喜欢寄生继承风格),但是这就是我得到的:

//your original class
var Type = function(name) {
    this.name = name;
};

//our extend function
var extend = function(cls) {

    //which returns a constructor
    function foo() {

        //that calls the parent constructor with itself as scope
        cls.apply(this, arguments)

        //the additional field
        this.extraField = 1;
    }

    //make the prototype an instance of the old class
    foo.prototype = Object.create(cls.prototype);

    return foo;
};

//so lets extend Type into newType
var newType = extend(Type);

//create an instance of newType and old Type
var t = new Type('bar');
var n = new newType('foo');


console.log(t);
console.log(t instanceof Type);
console.log(n);
console.log(n instanceof newType);
console.log(n instanceof Type);

从您的控制台输出中,我想扩展存储在“constructor”中的函数。新字段应该显示在“name”旁边,而不是“constructor”旁边。 - Aaron Digulla
所以你真正想做的是创建另一个构造函数?还是只是添加到现有的构造函数中? - Joseph
我想扩展现有的构造函数。 - Aaron Digulla
1
不用 cls.prototype.constructor.call(this, name),我会用 cls.call(this, name)。这两个函数是一样的,而且不需要担心 .constructor 属性是否存在的问题。foo.prototype = new cls() 的危险在于 cls 可能是一个需要参数的函数。这就是为什么 foo.prototype = Object.create(cls.prototype) 更受欢迎的原因。 - user1106925
@amnotiam 很有趣。现在我学到了新东西。但是Object.create是ECMA5的,你如何在旧浏览器中实现它呢? - Joseph
1
此示例展示了经典的修复方法。它仅模拟Object.create中的“使用原型创建对象”部分,但在这里这就足够了。 - user1106925

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接