JavaScript构建构造函数的构造函数

时间:2014-02-12 22:05:36

标签: javascript constructor prototype

以下是我想要的一个简单示例:

var ConstBuilder = function() {
    var constructor = function() {} ;
    constructor.prototype = {} ;
    return constructor ;
} ;

ConstBuilder.prototype = {
    add : function(name, value) {
        this.prototype[name] = value ;
    }
} ;

var A = new ConstBuilder() ;
A.add('test', function() {
    console.log('test') ;
}) ;

var a = new A() ;
a.test() ;

此代码将失败,因为A不是ConstBuilder的实例(因为A来自返回的var constructor = function() {},并且不会在其原型中定义方法(add)。

但是这对于修改超级构造函数的原型来说会很有用,例如:

ConstBuilder.prototype.remove = function(name) {
    delete this.prototype[name] ;
} ;

A.remove('test') ;

a.test ; // undefined

有没有办法让一个函数作为另一个的实例?所以这个函数可能会隐含地“继承”其构造函数原型中定义的所有方法。

或者如果您有其他建议,我的目标是构建可模糊的构造函数 - 就像原型的实例一样。

3 个答案:

答案 0 :(得分:4)

请确保您已理解.prototype属性与内部继承原型之间的区别。


  

代码将失败,因为A不是ConstBuilder的实例。有没有办法将函数作为另一个函数的实例?

A,正如每个构造函数所需,是Function。因此,如果您只是在add上定义removeFunction.prototype方法,它就会起作用:

Function.prototype.add = function(name, value) {
    this.prototype[name] = value;
};
Function.prototype.remove = function(name) {
    delete this.prototype[name];
};

function A() {}
A.add('test', function(){console.log('test');});
var a = new A();
a.test(); // test

A.remove('test');
a.test; // undefined

然而,除了Function.prototype之外,不可能让函数继承其他内容 - 请参阅Can a JavaScript object have a prototype chain, but also be a function?。如果您不想修改原生Function.prototype对象,您仍然可以使用mixin pattern

var Constr = (function() {
    function add(name, value) {
        this.prototype[name] = value;
    }
    function remove(name) {
        delete this.prototype[name];
    }
    return function mixin(c) {
        c.add = add;
        c.remove = remove;
        return c;
    };
})();

var A = Constr(function() {…});
A.add("test", …);
var a = new A();
a.test(); // test
  

我的目标是构建可模糊的构造函数

您可以使用builder pattern,因为您似乎已经尝试过了。

function ConstBuilder() {
    this.prototype = {};
};

ConstBuilder.prototype = {
    add: function(name, value) {
        this.prototype[name] = value;
    },
    remove: function(name) {
        delete this.prototype[name];
    },
    getConstructor: function() {
        var constructor = function() {};
        constructor.prototype = this.prototype;
        this.prototype.constructor = constructor;
        return constructor;
    }
};

var A = new ConstBuilder().add('test', function() {
    console.log('test');
}).getConstructor();
var a = new A();
a.test(); // test

要在以后删除功能,您需要保存对builder

的引用

答案 1 :(得分:0)

function a (x,y,construct)
    {
    if (!construct) return;
    this.x=x;
    this.y=y;
    }

a.prototype.methoda=function ()
    {
    return x+y;
    }

function b (x,y,d,e)
    {
    a.call (this,x,y,true) //--- this would inherit all own Objects and Properties of a and become own properties of b
    this.d=d;
    this.e=e;
    }

  b.prototype=new a ();  //--- this would only inherit the prototype, construct becomes false and isnt worked through, which if not would result in adding propertiy x and y to prototype instead of directly to instance of b,
  b.prototype.constructor=b;

  var test=new b (1,2,3,4);
  b.methoda ();

第二种方式

function a (x,y)
    {
    if (arguments.callee.doNotConstruct) return;
    this.x=x;
    this.y=y;
    }

a.prototype.methoda=function ()
    {
    return x+y;
    }


function b (x,y,d,e)
    {
    a.call (this,x,y) //--- this would inherit all own Objects and Properties of a and become own properties of b
    this.d=d;
    this.e=e;
    }
  a.doNotConstruct=true;
  b.prototype=new a ();  //--- this would only inherit the prototype, construct becomes false and isnt worked through, which if not would result in adding propertiy x and y to prototype instead of directly to instance of b,
  a.doNotConstruct=false;

  b.prototype.constructor=b;

  var test=new b (1,2,3,4);
  b.methoda ();

把它放在一个函数

 function prototypeInheritance (inheritor,parent)
 {
 parent.doNotConstruct=true;
 inheritor=new parent ();
 inheritor.prototype.constructor=inheritor;
 inheritor.parent=parent;
 parent.doNotConstruct=false;
 }

您可以在继承者构造函数中使用(arguments.callee.parent)调用父属性,并且可以在父构造函数中使用arguments.callee.doNotConstruct检查doNotConstruct

答案 2 :(得分:0)

我认为您正在寻找一个如何进行JavaScript“原型继承”的示例。当JavaScript在对象上查找属性时,它首先检查对象本身。接下来它检查原型。但是,因为JavaScript中的所有内容都是对象,而原型是一个对象

function Root(){}
Root.prototype.fromRoot = function() { console.log("I'm on Root's prototype."); };
function Child(){}
Child.prototype = new Root();
Child.prototype.fromChild = function() { console.log("I'm on Child's prototype."); };

var r = new Root();
var c = new Child();

r.fromRoot();  // works
c.fromRoot();  // works
c.fromChild(); // works
r.fromChild(); // fails