以下是我想要的一个简单示例:
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
有没有办法让一个函数作为另一个的实例?所以这个函数可能会隐含地“继承”其构造函数原型中定义的所有方法。
或者如果您有其他建议,我的目标是构建可模糊的构造函数 - 就像原型的实例一样。
答案 0 :(得分:4)
请确保您已理解.prototype
属性与内部继承原型之间的区别。
代码将失败,因为A不是ConstBuilder的实例。有没有办法将函数作为另一个函数的实例?
A
,正如每个构造函数所需,是Function
。因此,如果您只是在add
上定义remove
和Function.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