【问题标题】:creating a public method on a constructor function: Why use the prototype keyword?在构造函数上创建公共方法:为什么使用原型关键字?
【发布时间】:2011-03-04 20:22:13
【问题描述】:

如果我创建一个构造函数 BlahWidget 并为其提供 2 个公共方法:publicHello 和 secondHello。我使用'this'直接在小部件内部分配publicHello,但使用原型对象分配secondHello方法,这对小部件上2个方法的行为有什么影响?

var BlahWidget = function(){
  this.publicHello = function(){
    alert("Hello");
  }
};

BlahWidget.prototype.secondHello = function(){
  alert("Second Hello");
}

我的理解是使用 .prototype 允许它被继承的对象调用。但事实证明并非如此。这两种方法都可以被继承的函数对象调用,如下所示:

var MiniBlah = function(){

  this.callSupers = function(){
     this.publicHello();    
     this.secondHello();
  }
}


MiniBlah.prototype = new BlahWidget();
MiniBlah.prototype.constructor = MiniBlah;

var x = new MiniBlah();
x.callSupers();//calls both publicHello and secondHello

【问题讨论】:

    标签: javascript oop inheritance prototype


    【解决方案1】:

    不同之处在于,在原型对象上声明的函数在构造函数创建的对象实例之间共享,而在构造函数体内声明的函数则不是,它们属于从该函数构造的对象。

    这在实践中意味着你可以从一个构造函数中创建一个对象加载,其中原型上的一个函数执行 X,然后将原型上的该函数更改为执行 Y,所有对象实例都将获得新的功能函数。

    一个例子

    var BlahWidget = function(){
      this.publicHello = function(){
        console.log("Hello");
      }
    };
    
    BlahWidget.prototype.secondHello = function(){
      console.log("Second Hello");
    }
    
    var blah1 = new BlahWidget();
    
    var blah2 = new BlahWidget();
    blah2.publicHello = function() {
        console.log("Goodbye");
    }
    
    blah1.secondHello(); // logs SecondHello
    blah2.secondHello(); // logs SecondHello
    
    BlahWidget.prototype.secondHello = function(){
      console.log("Second Goodbye");
    }
    
    blah1.secondHello(); // logs Second Goodbye
    blah2.secondHello(); // logs Second Goodbye
    
    blah1.publicHello(); // logs Hello
    blah2.publicHello(); // logs Goodbye
    

    【讨论】:

    • 所以你的意思是你也可以使用原型来覆盖一个方法,对吧?
    • 我的意思是,如果你改变原型,你就会改变所有从函数构造的对象,包括那些已经构造的和尚未构造的。当我想到重写一个方法时,我会想到一个派生类重写从父类继承的方法,这里不是这种情况,所以我不会使用该术语来描述 JavaScript 的原型行为。
    【解决方案2】:

    “BlahWidget”的每个实例都会有自己独特的“publicHello”函数副本。

    另外,虽然这只是学术性的,但我不确定我会说“原型”是一个关键字;它更像是一个“特殊属性名称”。

    【讨论】:

      【解决方案3】:

      在 JavaScript 中,函数非常强大,可以构建 OOP 和模块化概念。以下概念仅在 JavaScript 中使用 Function 实现:

      1. 方法
      2. 构造函数
      3. 模块

      下面的代码显示了创建类 MyClass 并且它有私有成员的代码:

      function MyClass(a) {  
          var count = 3; // private member  
        
          // this check function is private function  
          function check() {  
              if (count > 0) {  
                  count--;  
                  return true;                  
              }  
              else {  
                  return false;  
              }  
          }  
          this._a = a;  
          this.get = function () {  
              if (check()) { // use of private function  
                  return this._a;  
              }  
              else {  
                  return "Thullu"; // after invoking get method 3 times in the object this else will be executed  
              }  
          }  
      }  

      在上面的代码变量中,count 是私有的,因为从 MyClass 创建的任何对象都不会有这个变量,类似地函数 check() 是私有函数,因为这个函数在 MyClass 中不是 this 的一部分。当我们使用 new 关键字创建 MyClass 的对象时,它会返回。由于词法作用域(功能作用域),这个概念在 JavaScript 中是可能的。

      当我们创建MyClass这个类的对象,并且调用get方法超过3次时:

      我想写几点关于新关键字的观点。

      当使用 new 运算符调用函数时,会使用原型成员创建一个新对象并将其分配给 this。 仅当函数中没有显式返回值时,上述语句才成立。如果类(函数)中存在显式返回,则将相同的返回分配给对象。 我想在这里再举一个例子,它具有非常基本的功能,就像我们拥有的所有 OOP 语言一样。我们声明私有字段,然后使用公共属性来公开私有字段,以更正式和 OOP 的方式,我们创建 Get 和 Set 方法来更新私有字段或检索类的私有成员。

      我们可以在 JavaScript 中为私有变量实现相同的获取和设置功能,如下例所示:

      // private class with get and set methods  
         function MyClass() {  
             var _privateField = 0; // It is private field as it is not part of "this"  
             this.GetPrivateField = function () {  
                 return _privateField;  
             };  
             this.SetPrivateField = function (value) {  
                 _privateField = value;  
             };  
         } 

      【讨论】:

        猜你喜欢
        • 2019-05-06
        • 2016-12-19
        • 1970-01-01
        • 2016-01-07
        • 1970-01-01
        • 2012-03-05
        • 2014-07-01
        相关资源
        最近更新 更多