簡體   English   中英

在JavaScript類中調用父方法,但stll可以訪問對象實例內部的原型方法嗎?

[英]Call parent method in JavaScript class but stll have access to prototype methods inside object instance?

是否可以在JavaScript類中調用父方法,但仍然可以從父子類訪問原型方法。 這是代碼示例:

var Base = function() {

  this.baseMethod = function(){
    return 'baseMethod';
  };

  this.baseInitMethod = function() {
    return 'baseInitMethod';
  }
}


Base.prototype.basePrototypeMethod = function() {
  return "basePrototypeMethod";
};


var Specific = function() {

  Base.call(this);

  this.baseInitMethod = function() {
    // call baseInitMethod from Base class
  }

  this.specificMethod = function(){
    return 'specificMethod';
  }

  this.specificInitMethod = function() {

    return this.basePrototypeMethod();
  }
}


Specific.prototype.specificPrototypeMethod = function() {
  return 'specificPrototypeMethod' + '-' + this.baseInitMethod();
}


for(var p in Base.prototype) {
   Specific.prototype[p] = Base.prototype[p]
}


var s = new Specific();


console.log(s.baseMethod());

console.log(s.baseInitMethod());

console.log(s.basePrototypeMethod());

console.log(s.specificMethod());

console.log(s.specificInitMethod());

console.log(s.specificPrototypeMethod());

我想從特定類中的baseInitMethod方法中調用Base類中的baseInitMethod,但是從上面進行的所有函數調用仍然有效。 那可能嗎?

這是您需要做的:

var Base = function () {
};
Base.prototype.baseMethod = function () {
    return 'baseMethod';
};
Base.prototype.baseInitMethod = function () {
    return 'baseInitMethod';
};
Base.prototype.basePrototypeMethod = function () {
    return "basePrototypeMethod";
};


var Specific = function () {
    Base.apply(this, arguments);
};
Specific.prototype.baseInitMethod = function () {
    Base.prototype.baseInitMethod.apply(this,arguments);
};

Specific.prototype.specificMethod = function () {
    return 'specificMethod';
};

Specific.prototype.specificInitMethod = function () {
    var basePrototypeMethodCallResult = Base.prototype.basePrototypeMethod.apply(this,arguments);

};

您的Specific.prototype對象應繼承Base.prototype對象。 當前,您正在使用以下代碼將其所有屬性復制到對象:

 for(var p in Base.prototype) { Specific.prototype[p] = Base.prototype[p] } 

但是您實際上應該使用Object.create建立一個真實的原型鏈

Specific.prototype = Object.create(Base.prototype);

Specific.prototype.specificPrototypeMethod = function() {
  return 'specificPrototypeMethod' + '-' + this.baseInitMethod();
}

我想從特定類內的baseInitMethod方法調用基類中的baseInitMethod

是。 在您的Specific構造函數中,在覆蓋實例的屬性之前,首先需要獲得BasebaseInitMethod實例方法:

function Specific() {
    Base.call(this);

    var parentInitMethod = this.baseInitMethod;
    this.baseInitMethod = function() {
        // call baseInitMethod from Base class:
        parentInitMethod.call(this /*, arguments…*/); 
    }

    …
}

因此從上面進行的所有函數調用仍然有效。

我不確定您的意思是什么。 specificPrototypeMethod將始終調用當前實例的baseInitMethod ,這將是Specific的覆蓋實例,而不是Base中定義的原始實例。

你覆蓋baseInitMethodBase里面Specific ,有Specific的定義,那么,為什么你會永遠想調用基版本? 如果僅刪除函數的覆蓋,則應調用基本定義:

var Base = function() {

  this.baseMethod = function(){
    return 'baseMethod';
  };

  this.baseInitMethod = function() {
    return 'baseInitMethod';
  }
}


Base.prototype.basePrototypeMethod = function() {
  return "basePrototypeMethod";
};


var Specific = function() {

  Base.call(this);

  this.baseInitMethod(); // calls the Base definition only

  this.specificMethod = function(){
    return 'specificMethod';
  }

  this.specificInitMethod = function() {

    return this.basePrototypeMethod();
  }
}

有人可能會爭辯說:“為什么總是嘗試通過callapply來模仿“經典”行為和大驚小怪,而不是擁抱原型委托模式?”

這是我要編寫的代碼:

var Base = {

    baseVariable1: "baseValue1",

    baseVariable2: "baseValue2",

    baseMethod: function () {
        return 'baseMethod';
    },

    baseInitMethod: function () {
        return 'baseInitMethod';
    }
}

var Specific = Object.create(Base);

Specific.variable1 = "value1";

Specific.variable2 = "value2";

Specific.specificInitMethod = function () {
    return 'specificInitMethod' + '-' + this.baseInitMethod();
}

Specific.specificMethod = function () {
    return 'specificMethod' + '-' + this.baseInitMethod();
}

var s = Object.create(Specific);

console.log(s.baseInitMethod());

console.log(s.baseVariable1);

console.log(s.baseVariable2);

console.log(s.variable1);

console.log(s.variable2);

console.log(s.baseMethod());

console.log(s.specificInitMethod());

console.log(s.specificMethod());
class Parentable {
  get parent() {
    return this.__proto__.__proto__;
  }
} 
class A extends Parentable { 
  say() { 
    console.log('Hello from A'); 
  } 
}
class B extends A {
  say() {
   console.log('Im not A, I am B! But A send you a message:');
   this.parent.say();
  }
}
(new B()).say();

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM