假设我在JavaScript
中有一个构造函数,我用它来创建我的对象。如何通过此函数的方法调用来更改此函数创建的所有对象的“内容”。我想知道的是,天气可以调用原型上的方法调用,就像我们修改原型添加我们自己的方法/属性一样。
例如:
function MyConstructor()
{
var privateVariable = "This is an ORIGINAL private variable";
this.publicVariable = "This is public";
this.modificationMethod = function(){
// I want to call this methode on the prototype
privateVariable = "I am now changed";
};
this.alertMe = function(){
alert(privateVariable);
};
}
var a = new MyConstructor();
a.alertMe(); // alerts This is an ORIGINAL private variable
a.modificationMethod();
a.alertMe(); // alerts I am now changed
当我想要更改单个对象时,我会调用该方法,它会更改该单个对象。但是,我想更改构造函数创建的所有对象。
我知道我可以像这样添加新方法:
MyConstructor.prototype.foo = function(){
alert("foo");
}
a = new MyConstructor();
a.foo();
但它不允许我运行现有方法来更改属性,并抛出错误:
MyConstructor.prototype.modificationMethod();
“modificationMethod不是函数”
答案 0 :(得分:1)
编辑:更新答案以反映评论中讨论的所有内容。我最初误解了OP的问题。
每个对象都链接到一个原型对象。当尝试访问不存在的属性时,JavaScript将查找该属性的对象的原型对象,如果存在则返回它。
函数构造函数的prototype属性引用使用new时使用该函数创建的所有实例的原型对象。
这意味着当对象本身没有所需的属性时,原型对象是一种回退机制。
私有变量的概念实际上是closures。
原型函数在构造函数范围之外定义,这意味着它们无法访问“私有属性”。
但是,可以为prototype属性本身分配一个闭包,有效地创建一个私有共享(静态)变量。
function MyConstructor() {};
MyConstructor.prototype = (function() {
var extensions = {
foo: null,
test: function() {
alert("Test was extended");
}
};
return {
registerExtension: function(name, callback) {
extensions[name] = callback;
},
// in order to use the extensions object, you need a generic function such as invoke
invoke: function(name) {
if (typeof extensions[name] === 'function')
extensions[name].call(this);
}
};
}());
var a = new MyConstructor();
a.invoke('test'); //will alert
a.invoke('foo'); //will not alert (not a function)
a.registerExtension('foo', function() {
alert("foo is now extended as well");
});
a.invoke('test'); //will alert
a.invoke('foo'); //will alert
如果您不介意扩展函数可见(公共),那么更简单的方法是直接扩展prototype
。
function MyConstructor() {};
MyConstructor.prototype = {
foo: null,
test: function() {
alert("Test was extended");
}
};
var a = new MyConstructor();
a.test(); //will alert
//a.foo(); //will not alert (not a function)
MyConstructor.prototype.foo = function() {
alert("foo is now extended as well");
};
a = new MyConstructor();
a.test(); //will alert
a.foo(); //will alert
您可以轻松地为原型扩展创建界面。
Object.prototype.registerExtension = function( name, func ){
this.prototype[ name ] = func;
};
// ...
MyConstructor.registerExtension( 'foo', function() {
alert("foo is now extended as well");
} );