জাভাস্ক্রিপ্ট ওভাররাইড পদ্ধতি


87

ধরা যাক আপনার নীচের কোডটি রয়েছে:

function A() {
    function modify() {
       x = 300;
       y = 400;
    }

    var c = new C();
}

function B() {
    function modify(){
       x = 3000;
       y = 4000;
    }

    var c = new C();
}

C = function () {
   var x = 10;
   var y = 20;

   function modify() {
      x = 30;
      y = 40;
   };

   modify();
   alert("The sum is: " + (x+y));
}

এখন প্রশ্নটি হল, যদি এমন কোনও উপায় থাকে যা আমি যে পদ্ধতিতে থাকি এবং সেগুলি modifyথেকে পদ্ধতিটি ওভাররাইড করতে পারি । জাভাতে আপনি- কীওয়ার্ডটি ব্যবহার করবেন তবে আপনি কীভাবে জাভাস্ক্রিপ্টে এইরকম কিছু অর্জন করতে পারেন?CABsuper


6
modifyকোনও পদ্ধতি নয় তবে একটি নেস্টেড ফাংশন - এই দুজনের মধ্যে একটি পার্থক্য রয়েছে ...
Šime বিদাস

4
জাভাতে আপনি বেসরকারী ক্ষেত্রগুলি এবং একটি সুপার-ক্লাসের পদ্ধতিগুলি অ্যাক্সেস করতে superকীওয়ার্ডটি ব্যবহার করেন । আপনি এগুলি ওভাররাইড করার জন্য এটি ব্যবহার করবেন না।
এফ কে 82

উত্তর:


138

সম্পাদনা: মূল উত্তরটি লেখা হয়েছিল এবং এখন অনেক পরিবর্তন হয়েছে এখন ছয় বছর পরে!

  • আপনি যদি জাভাস্ক্রিপ্টের একটি নতুন সংস্করণ ব্যবহার করছেন, সম্ভবত বাবেলের মতো একটি সরঞ্জাম দিয়ে সংকলিত হয়েছে , আপনি বাস্তব ক্লাস ব্যবহার করতে পারেন
  • আপনি যদি Angular বা দ্বারা সরবরাহিত শ্রেণীর মতো উপাদান তৈরির ব্যবহার করছেন or প্রতিক্রিয়া সেই কাঠামোর জন্য ডক্সে সন্ধান করতে চাইবেন।
  • আপনি যদি ইএস 5 ব্যবহার করে এবং প্রোটোটাইপগুলি ব্যবহার করে হাতে "জাল" ক্লাস তৈরি করেন তবে নীচের উত্তরটি এখনও আগের মতোই সঠিক।

শুভকামনা!


জাভাস্ক্রিপ্ট উত্তরাধিকার জাভা থেকে কিছুটা আলাদা দেখায়। নেটিভ জাভাস্ক্রিপ্ট অবজেক্ট সিস্টেমটি কেমন দেখাচ্ছে তা এখানে:

// Create a class
function Vehicle(color){
  this.color = color;
}

// Add an instance method
Vehicle.prototype.go = function(){
  return "Underway in " + this.color;
}

// Add a second class
function Car(color){
  this.color = color;
}

// And declare it is a subclass of the first
Car.prototype = new Vehicle();

// Override the instance method
Car.prototype.go = function(){
  return Vehicle.prototype.go.call(this) + " car"
}

// Create some instances and see the overridden behavior.
var v = new Vehicle("blue");
v.go() // "Underway in blue"

var c = new Car("red");
c.go() // "Underway in red car"

দুর্ভাগ্যক্রমে এটি কিছুটা কুৎসিত এবং এটি "সুপার" করার খুব সুন্দর উপায়টি অন্তর্ভুক্ত করে না: আপনি কোন পিতামাতার ক্লাসগুলির পদ্ধতিটি কল করতে চান তা আপনাকে ম্যানুয়ালি উল্লেখ করতে হবে। ফলস্বরূপ, ক্লাসগুলি আরও সুন্দর তৈরি করার জন্য বিভিন্ন ধরণের সরঞ্জাম রয়েছে। প্রোটোটাইপ.জেএস, ব্যাকবোন.জেএস বা অনুরূপ লাইব্রেরিতে জেএসে ওওপি করার জন্য একটি ভাল সিনট্যাক্স অন্তর্ভুক্ত করার চেষ্টা করুন।


4
বিকল্প হিসাবে "ক্লাসগুলি আরও সুন্দর তৈরি করতে" কোনও সরঞ্জাম ব্যবহার করার পরে আপনি মোটেও ক্লাস করতে পারবেন না। জেএসে ক্লাসিকাল ওও অনুকরণ সর্বদা অগোছালো হয়ে যায়।
রায়নস

4
(গঠনমূলক মন্তব্য নয়) ব্রাউজার বিশ্বে "নিম্ন স্তরের" ভাষা হওয়ার কারণে অকারণে খুব কুৎসিত। এখনও এটি শিখছি, ধন্যবাদ!
dnuske

9
আমি বিশ্বাস করি Car.prototype = new Vehicle () এর পরিবর্তে; এটি Car.prototype = Object.create (Vehicle.prototype) হওয়া উচিত; না?
জর্দান


কার.প্রোটোটাইপ = নতুন যানবাহন () এর একটি কারণ; কোনও রঙ পাওয়ার সময় যানবাহন () এ যাওয়ার কিছু নেই বলে এটি ভুল।
তুষার অরোরা

63

যেহেতু এটি গুগল শীর্ষস্থানীয়, তাই আমি একটি আপডেট উত্তর দিতে চাই।

ES6 ক্লাস ব্যবহার করা উত্তরাধিকার এবং পদ্ধতিটিকে অনেক সহজ করে তোলে:

'use strict';

class A {
    speak() {
        console.log("I'm A");
    }
}

class B extends A {
    speak() {
        super.speak();

        console.log("I'm B");
    }
}

var a = new A();
a.speak();
// Output:
// I'm A

var b = new B();
b.speak();
// Output:
// I'm A
// I'm B

superশব্দ যখন inheriting ক্লাসে ব্যবহৃত পিতা বা মাতা বর্গ বোঝায়। এছাড়াও, পিতামাতার ক্লাসে সমস্ত পদ্ধতি সন্তানের দৃষ্টান্তের সাথে আবদ্ধ, সুতরাং আপনাকে লিখতে হবে নাsuper.method.apply(this);

সামঞ্জস্যতা হিসাবে: ES6 সামঞ্জস্যতা টেবিল প্রধান খেলোয়াড় সমর্থন ক্লাসের সবচেয়ে সাম্প্রতিক সংস্করণগুলি (বেশিরভাগই) দেখায়। ভি 8 ব্রাউজারগুলি এ বছরের জানুয়ারীর পর থেকে (ক্রোম এবং অপেরা) রয়েছে এবং ফায়ারফক্স স্পাইডারমোনকি জেএস ইঞ্জিন ব্যবহার করে আগামী মাসে তাদের অফিসিয়াল ফায়ারফক্স 45 রিলিজের সাথে ক্লাস দেখতে পাবে। মোবাইলের দিক থেকে, অ্যান্ড্রয়েড এখনও এই বৈশিষ্ট্যটি সমর্থন করে না, যদিও আইওএস 9, পাঁচ মাস আগে প্রকাশিত হয়েছে, আংশিক সমর্থন রয়েছে।

ভাগ্যক্রমে, বাবেল রয়েছে , জেএস গ্রন্থাগারটি ES5 কোডে হারমনি কোডটি পুনরায় সংকলনের জন্য। ES6 এর ক্লাসগুলি এবং অন্যান্য দুর্দান্ত বৈশিষ্ট্যগুলি আপনার জাভাস্ক্রিপ্ট কোডটিকে অনেক বেশি পঠনযোগ্য এবং রক্ষণাবেক্ষণযোগ্য করে তুলতে পারে।


10
এই উত্তরটি আরও creditণের দাবিদার এবং বর্তমানে সঠিক উত্তর।
ক্লোম্পেনরুনার

6

একবারে ক্লাসিকাল ওও অনুকরণ করা এড়ানো উচিত এবং পরিবর্তে প্রোটোটাইপিকাল ওও ব্যবহার করা উচিত। প্রোটোটাইপিকাল ওওর জন্য একটি দুর্দান্ত ইউটিলিটি লাইব্রেরি হ'ল বৈশিষ্ট্য

পরিবর্তে পদ্ধতিগুলি ওভাররাইটিং এবং উত্তরাধিকার শৃঙ্খলা স্থাপন (বস্তুর উত্তরাধিকারের উপরে সর্বদা অবজেক্ট রচনার পক্ষে হওয়া উচিত) আপনার পুনরায় ব্যবহারযোগ্য ফাংশনগুলিকে বৈশিষ্ট্যগুলিতে বান্ডিল করা উচিত এবং সেগুলির সাথে বস্তু তৈরি করা উচিত।

সরাসরি উদাহরণ

var modifyA = {
    modify: function() {
        this.x = 300;
        this.y = 400;
    }
};

var modifyB = {
    modify: function() {
        this.x = 3000;
        this.y = 4000;
    }
};

C = function(trait) {
    var o = Object.create(Object.prototype, Trait(trait));

    o.modify();
    console.log("sum : " + (o.x + o.y));

    return o;
}

//C(modifyA);
C(modifyB);

10
আপনি প্রশ্নের উত্তর দিচ্ছেন না। এটি কিছু হলে একটি মন্তব্য করা উচিত।
এফ কে 82

@ এফ কে ৮৮ আসুন আমরা এই আলোচনাটি
থাকি

3

আপনার উদাহরণে () পরিবর্তন করুন এটি একটি ব্যক্তিগত ফাংশন, এটি আপনার এ, বি বা সি সংজ্ঞার মধ্যে কোথাও থেকে অ্যাক্সেসযোগ্য হবে না। আপনি এটি হিসাবে ঘোষণা করতে হবে

this.modify = function(){}

সি এর পিতামাতাদের কাছে কোনও রেফারেন্স নেই, যদি না আপনি সি এ উত্তীর্ণ হন তবে সি যদি এ বা বি থেকে উত্তরাধিকার সূত্রে সেট করা থাকে তবে এটি এর সর্বজনীন পদ্ধতিগুলির উত্তরাধিকারী হবে (এটি আপনার ব্যক্তিগত ফাংশন যেমন আপনি সংশোধন করেছেন () সংজ্ঞায়িত করেছেন)। সি একবার তার পিতামাতার কাছ থেকে পদ্ধতি উত্তরাধিকার সূত্রে প্রাপ্ত হয়ে গেলে আপনি উত্তরাধিকার সূত্রে প্রাপ্ত পদ্ধতিগুলিকে ওভাররাইড করতে পারেন।


সংশোধন করা একটি স্থানীয় ফাংশন। জাভাস্ক্রিপ্টে কোনও ব্যক্তিগত নেই
রায়নস

স্থানীয় / ব্যক্তিগত, এটি কি একই জিনিস নয়, কেবল একটি পৃথক শব্দ?
অ্যালেক্স হাইড

2

modify()আপনি সর্বশেষে যে পদ্ধতিটি ডাকলেন সেটি বৈশ্বিক প্রসঙ্গে বলা হয় যদি আপনি ওভাররাইড modify()করতে চান তবে আপনাকে প্রথমে উত্তরাধিকারী হতে হবে AবাB

হতে পারে আপনি এটি করার চেষ্টা করছেন:

এই ক্ষেত্রে Cউত্তরাধিকারীA

function A() {
    this.modify = function() {
        alert("in A");
    }
}

function B() {
    this.modify = function() {
        alert("in B");
    }
}

C = function() {
    this.modify = function() {
        alert("in C");
    };

    C.prototype.modify(); // you can call this method where you need to call modify of the parent class
}

C.prototype = new A();

4
C.prototype.modify()ভুল thisমান হবে। যথা C.prototypeগ এর উদাহরণের পরিবর্তে। দয়া করে ব্যবহার করুন .call(this)তবে আপনার উত্তরটি কেবল একটি সদৃশ :)
রায়নস

1

আপনি যদি সমস্ত ভেরিয়েবলগুলি "পাবলিক" না করেন, তা Functionনা হলে সরাসরি বা prototypeসম্পত্তির মাধ্যমে এগুলিকে সদস্য করুন ।

var C = function( ) {
    this.x = 10 , this.y = 20 ;
    this.modify = function( ) {
        this.x = 30 , this.y = 40 ;
        console.log("(!) C >> " + (this.x + this.y) ) ;
    } ;
} ;

var A = function( ) {
    this.modify = function( ) {
       this.x = 300 , this.y = 400 ;
       console.log("(!) A >> " + (this.x + this.y) ) ;
    } ;
} ;
    A.prototype = new C ;

var B = function( ) {
    this.modify = function( ) {
       this.x = 3000 , this.y = 4000 ;
       console.log("(!) B >> " + (this.x + this.y) ) ;
    } ;
} ;


new C( ).modify( ) ;
new A( ).modify( ) ;
new B( ).modify( ) ; 

আপনি কয়েকটি পরিবর্তন লক্ষ্য করবেন।

সর্বাধিক গুরুত্বপূর্ণভাবে অনুমিত "সুপার-ক্লাস" কনস্ট্রাক্টরের কলটি এখন এই লাইনের মধ্যে অন্তর্ভুক্ত:

<name>.prototype = new C ;

উভয়ই Aএবং Bএখন পৃথকভাবে সংশোধনযোগ্য সদস্য থাকবে xএবং yএটি ... = Cপরিবর্তে আমরা লিখতে চাইলে কেস হবে না ।

এর পরে, x, yএবং modifyসব "সর্বজনীন" সদস্যদের তাই একটি ভিন্ন বরাদ্দ করছেন যে Functionতাদের

 <name>.prototype.modify = function( ) { /* ... */ }

আসলটি "ওভাররাইড" করবে Functionসেই নামটি ।

শেষ অবধি, ঘোষণাপত্রে কলটি করা modifyযাবে না Functionকারণ "সুপার-ক্লাস" এর অন্তর্নিহিত কলটি তখনই কার্যকর করা হবে যখন আমরা অনুমিত "সুপার-ক্লাস" সেট করিprototype অনুমিত "উপ-শ্রেণীর" সম্পত্তিতে ।

তবে ভাল, আপনি জাভাস্ক্রিপ্টে এই জাতীয় জিনিসটি কীভাবে করবেন তা কমবেশি।

এইচটিএইচ,

এফকে


কোনো লাভ নেই <name>.prototype = new C;প্রোটোটাইপ আপনার ছায়া সকল সদস্যদের যাহাই হউক না কেন
Raynos

@ রায়নোস: হ্যাঁ আছে। বুদ্ধিমানভাবে, উত্তরাধিকার সূত্রে সমস্ত Objectsসদস্য একই সদস্যকে ভাগ করে নেবে Cযদি আপনি কোনও Cঅবজেক্ট ইনস্ট্যান্ট না করেন । সুতরাং, পরিবর্তন xমধ্যে Aপরিবর্তন হবে xমধ্যে Cএবং এইভাবে পরিবর্তন xমধ্যে B। যা স্পষ্টতই অনাকাঙ্ক্ষিত।
এফ কে 82

আপনি বিন্দু মিস করেছেন। আপনি লাইনটি সরাতে পারেন এবং কোডটি এখনও কাজ করবে
রায়নস

@ রায়নোস: আপনি নিজের বক্তব্যটি মিস করছেন আমি ভীত। ;-) আমরা চাই Aএবং এর Bউত্তরাধিকারী হই C। যদি সেই লাইনটি অনুপস্থিত থাকে, তবে এটি হবে না। আসলে একমাত্র প্রোটোটাইপ Aপাশাপাশি B"ছায়া" উভয় ক্ষেত্রেই এর অ্যাক্সেস থাকবে Object.prototype
এফ কে 82

কোড তাকান। এ এবং বি সি এর সদস্যদের কোনও প্রোটোটাইপ ব্যবহার করবেন না। সুতরাং সি থেকে "উত্তরাধিকারসূত্রে পাওয়া" অকেজো। এর কারণ A এবং B পুনরায় সংজ্ঞায়িত x, yএবং modifyএবং এইভাবে সব ছায়া C'র সদস্যরা। প্রোটোটাইপ সি ব্যবহার না করে লাভ কী? এটি ডেড কোড।
রায়নস

0

function A() {
    var c = new C();
	c.modify = function(){
		c.x = 123;
		c.y = 333;
	}
	c.sum();
}

function B() {
    var c = new C();
	c.modify = function(){
		c.x = 999;
		c.y = 333;
	}
	c.sum();
}


C = function () {
   this.x = 10;
   this.y = 20;

   this.modify = function() {
      this.x = 30;
      this.y = 40;
   };
   
   this.sum = function(){
	this.modify();
	console.log("The sum is: " + (this.x+this.y));
   }
}

A();
B();

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.