是否可以从对象定义构造函数中调用方法

时间:2016-06-02 09:35:05

标签: javascript prototype

假设我在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不是函数”

1 个答案:

答案 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");
} );