برنامهنویسی شیءگرا - چگونه متد والد را از کلاس فرزند در جاوااسکریپت فراخوانی کنیم؟
من چند ساعت گذشته را صرف تلاش برای پیدا کردن راهحلی برای مشکل خود کردهام اما به نظر میرسد که ناامیدکننده است.
در اصل من نیاز دارم بدانم چگونه میتوانم یک متد والد را از یک کلاس فرزند فراخوانی کنم. تمام چیزهایی که تاکنون امتحان کردهام یا کار نمیکنند یا متد والد را بازنویسی میکنند.
من از کد زیر برای راهاندازی برنامهنویسی شیءگرا در جاوااسکریپت استفاده میکنم:
// SET UP OOP
// surrogate constructor (empty function)
function surrogateCtor() {}
function extend(base, sub) {
// copy the prototype from the base to setup inheritance
surrogateCtor.prototype = base.prototype;
sub.prototype = new surrogateCtor();
sub.prototype.constructor = sub;
}
// parent class
function ParentObject(name) {
this.name = name;
}
// parent's methods
ParentObject.prototype = {
myMethod: function(arg) {
this.name = arg;
}
}
// child
function ChildObject(name) {
// call the parent's constructor
ParentObject.call(this, name);
this.myMethod = function(arg) {
// HOW DO I CALL THE PARENT METHOD HERE?
// do stuff
}
}
// setup the prototype chain
extend(ParentObject, ChildObject);
من باید ابتدا متد والد را فراخوانی کنم و سپس در کلاس فرزند موارد بیشتری به آن اضافه کنم.
در بیشتر زبانهای برنامهنویسی شیءگرا این به سادگی فراخوانی parent.myMethod() خواهد بود. اما من واقعاً نمیتوانم درک کنم که این کار در جاوااسکریپت چگونه انجام میشود.
هر کمکی بسیار قدردانی میشود، متشکرم!
پاسخ شماره ۱
سبک ES6 به شما امکان میدهد از ویژگیهای جدید استفاده کنید، مانند کلمه کلیدی super. کلمه کلیدی super همه چیز دربارهی زمینه کلاس والد است، زمانی که شما از نحو کلاسهای ES6 استفاده میکنید. به عنوان یک مثال بسیار ساده، بررسی کنید:
به یاد داشته باشید: ما نمیتوانیم متدهای استاتیک والد را از طریق کلیدواژه
superداخل یک متد نمونه فراخوانی کنیم. متد فراخوانیکننده نیز باید استاتیک باشد.
فراخوانی متد ایستا از طریق متد نمونه - TypeError !
class Foo {
static classMethod() {
return 'hello';
}
}
class Bar extends Foo {
classMethod() {
return super.classMethod() + ', too';
}
}
console.log(Bar.classMethod()); // 'hello' - Invokes inherited static method
console.log((new Bar()).classMethod()); // 'Uncaught TypeError' - Invokes on instance methodفراخوانی متد ایستا از طریق super - این کار میکند!
class Foo {
static classMethod() {
return 'hello';
}
}
class Bar extends Foo {
static classMethod() {
return super.classMethod() + ', too';
}
}
console.log(Bar.classMethod()); // 'hello, too'حالا زمینه super بسته به فراخوانی تغییر میکند - Voilà!
class Foo {
static classMethod() {
return 'hello i am static only';
}
classMethod() {
return 'hello there i am an instance ';
}
}
class Bar extends Foo {
classMethod() {
return super.classMethod() + ', too';
}
}
console.log((new Bar()).classMethod()); // "hello there i am an instance , too"
console.log(Bar.classMethod()); // "hello i am static only"همچنین، شما میتوانید از super برای فراخوانی سازنده والد استفاده کنید:
class Foo {}
class Bar extends Foo {
constructor(num) {
let tmp = num * 2; // OK
this.num = num; // ReferenceError
super();
this.num = num; // OK
}
}
و البته میتوانید از آن برای دسترسی به ویژگیهای کلاس والد استفاده کنید super.prop. بنابراین، از ES6 استفاده کنید و خوشحال باشید.
پاسخ شماره ۲
اینگونه انجام میشود: ParentClass.prototype.myMethod();
یا اگر بخواهید آن را در زمینه نمونه فعلی فراخوانی کنید، میتوانید این کار را انجام دهید: ParentClass.prototype.myMethod.call(this)
همین مورد برای فراخوانی یک متد والد از کلاس فرزند با آرگومانها صادق است: ParentClass.prototype.myMethod.call(this, arg1, arg2, ..) * راهنما: به جای call() از apply() برای ارسال آرگومانها به صورت آرایه استفاده کنید.
