在构造函数上创建公共方法:为什么要使用prototype关键字?

时间:2011-03-04 20:22:13

标签: javascript oop inheritance prototype

如果我创建一个构造函数BlahWidget并给它2个公共方法:publicHello和secondHello。我使用'this'直接在widget中分配publicHello但是使用prototype对象来分配secondHello方法,这对widget上的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

3 个答案:

答案 0 :(得分:6)

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

这在实践中意味着您可以从构造函数创建一个对象的负载,并在原型上执行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

答案 1 :(得分:1)

“BlahWidget”的每个实例都有自己独特的“publicHello”功能副本。

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

答案 2 :(得分:0)

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

  1. 方法
  2. 构造
  3. 模块
  4. 下面的代码显示了创建类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中不是此函数的一部分。当我们使用new关键字创建MyClass的对象时,将返回此对象。由于词法范围(功能范围),这种概念在JavaScript中是可能的。

    当我们创建此类MyClass的对象时,调用get方法超过3次: enter image description here

    我想就新关键字写几点。

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

    我们可以实现JavaScript中私有变量的相同get和set功能,如下例所示:

    
    
    // 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;  
           };  
       } 
    
    
    

    enter image description here