প্রোটোটাইপগুলি কখন ব্যবহার করবেন তা জাভাস্ক্রিপ্ট


94

জেএসে প্রোটোটাইপ পদ্ধতি ব্যবহার করা কখন উপযুক্ত তা আমি বুঝতে চাই। সেগুলি কি সর্বদা ব্যবহার করা উচিত? বা এমন কিছু ক্ষেত্রে রয়েছে যেগুলি ব্যবহার করা পছন্দসই নয় এবং / অথবা কোনও পারফরম্যান্স জরিমানা আদায় করে?

জেএসে নামস্পেসিংয়ের সাধারণ পদ্ধতিতে এই সাইটের আশেপাশে অনুসন্ধান করার পরে, মনে হয় বেশিরভাগই একটি অ-প্রোটোটাইপ ভিত্তিক বাস্তবায়ন ব্যবহার করে: কেবল কোনও স্থান বা স্থান ব্যবহারের জন্য কোনও অবজেক্ট বা কোনও ফাংশন অবজেক্ট ব্যবহার করে।

শ্রেণিভিত্তিক ভাষা থেকে আসা, সমান্তরালগুলি আঁকতে চেষ্টা করা এবং এটি মনে করা শক্ত নয় যে প্রোটোটাইপগুলি "ক্লাস" এর মতো এবং আমি যে নেমস্পেসের প্রয়োগগুলি উল্লেখ করেছি তা স্থির পদ্ধতির মতো।

উত্তর:


135

প্রোটোটাইপগুলি একটি অপ্টিমাইজেশন

এগুলিকে ভালভাবে ব্যবহার করার একটি দুর্দান্ত উদাহরণ হ'ল jQuery লাইব্রেরি। যতবারই আপনি ব্যবহার করে কোনও jQuery অবজেক্ট পান $('.someClass'), সেই বস্তুর কয়েক ডজন "পদ্ধতি" রয়েছে। গ্রন্থাগারটি কোনও বস্তু ফিরিয়ে দিয়ে তা অর্জন করতে পারে:

return {
   show: function() { ... },
   hide: function() { ... },
   css: function() { ... },
   animate: function() { ... },
   // etc...
};

তবে এর অর্থ হ'ল মেমোরিতে প্রতিটি jQuery অবজেক্টের কয়েক ডজন নামযুক্ত স্লট একই পদ্ধতিতে থাকবে এবং এটি বারবার থাকবে।

পরিবর্তে, সেই পদ্ধতিগুলি একটি প্রোটোটাইপ এবং সমস্ত jQuery অবজেক্টগুলিতে "উত্তরাধিকারসূত্রে" সংজ্ঞায়িত হয় যাতে প্রোটোটাইপ যাতে খুব অল্প রানটাইম ব্যয়ে এই সমস্ত পদ্ধতি অর্জন করতে পারে।

JQuery এটি ঠিক কীভাবে পায় তার একটি অতি গুরুত্বপূর্ণ অংশ হ'ল এটি প্রোগ্রামার থেকে লুকানো। এটি নিখুঁতভাবে একটি অপ্টিমাইজেশন হিসাবে বিবেচনা করা হয়, লাইব্রেরিটি ব্যবহার করার সময় আপনার যে উদ্বেগের দরকার তা নয়।

জাভাস্ক্রিপ্টের সমস্যাটি হ'ল নগ্ন কন্সট্রাক্টর ফাংশনগুলির জন্য কলারটিকে তাদের উপসর্গের সাথে স্মরণ করা প্রয়োজন newবা অন্যথায় তারা সাধারণত কাজ করে না। এর কোনও ভাল কারণ নেই। jQuery ঠিক কোনও সাধারণ ক্রিয়াকলাপের পিছনে সেই আজেবাজে কথাটি লুকিয়ে রাখে $, সুতরাং আপনাকে কীভাবে অবজেক্টগুলি বাস্তবায়ন করা হয় তা যত্ন নেওয়ার দরকার নেই।

যাতে আপনি কোনও নির্দিষ্ট প্রোটোটাইপ দিয়ে সুবিধার্থে কোনও অবজেক্ট তৈরি করতে পারেন, ইসমাএসক্রিপ 5 এ একটি মানক ফাংশন অন্তর্ভুক্ত রয়েছে Object.create। এর একটি বিস্তৃত সরলীকৃত সংস্করণ এর মতো দেখতে পাবেন:

Object.create = function(prototype) {
    var Type = function () {};
    Type.prototype = prototype;
    return new Type();
};

এটি কেবল কোনও কনস্ট্রাক্টর ফাংশন লেখার এবং তারপরে কল করার ব্যথার যত্ন নেয় new

আপনি কখন প্রোটোটাইপগুলি এড়াবেন?

একটি দরকারী তুলনা হ'ল জাভা এবং সি # এর মতো জনপ্রিয় ওও ভাষার সাথে। এগুলি দুই ধরণের উত্তরাধিকারকে সমর্থন করে:

  • ইন্টারফেস উত্তরাধিকার, যেখানে আপনি implementএকটি interfaceযেমন বর্গ ইন্টারফেসের যে সদস্যের নিজস্ব অনন্য বাস্তবায়ন উপলব্ধ পারে।
  • বাস্তবায়ন উত্তরাধিকার, যেখানে আপনি extendএকটি classযে কিছু পদ্ধতি ডিফল্ট বাস্তবায়নের প্রদান করে।

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

তবে আপনি যদি এমন কোনও পরিস্থিতিতে থাকেন যেখানে আপনি সি # বা জাভাতে ইন্টারফেস ব্যবহার করেছেন তবে জাভাস্ক্রিপ্টে আপনার কোনও বিশেষ ভাষা বৈশিষ্ট্যের প্রয়োজন নেই। ইন্টারফেসের প্রতিনিধিত্ব করে এমন কোনও কিছু স্পষ্টভাবে ঘোষণা করার দরকার নেই এবং বস্তুগুলিকে সেই ইন্টারফেসটিকে "বাস্তবায়ন" হিসাবে চিহ্নিত করার দরকার নেই:

var duck = {
    quack: function() { ... }
};

duck.quack(); // we're satisfied it's a duck!

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

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


4
ভাল ব্যাখ্যা। তারপরে আপনি কি সম্মত হবেন, যেহেতু আপনি প্রোটোটাইপগুলিকে একটি অপ্টিমাইজেশন হিসাবে বিবেচনা করেন, তবে সেগুলি সর্বদা আপনার কোড উন্নত করতে ব্যবহার করা যেতে পারে? আমি ভাবছি এমন কোনও ঘটনা আছে যেখানে প্রোটোটাইপ ব্যবহার করা কোনও অর্থবোধ করে না বা আসলে পারফরম্যান্সের জন্য শাস্তি দেয় inc
ওপল

আপনার ফলোআপে, আপনি উল্লেখ করেছেন যে "এটি প্রতিটি প্রকারের জন্য আপনি কত বার বরাদ্দ করেন তার উপর নির্ভর করে"। তবে আপনি যে উদাহরণটি উল্লেখ করেছেন সেটি হ'ল প্রোটোটাইপ ব্যবহার করা নয়। উদাহরণ বরাদ্দ করার ধারণাটি কোথায় (আপনি কি এখানে "নতুন" ব্যবহার করবেন)? এছাড়াও: বলুন কোয়াকের পদ্ধতিটির একটি প্যারামিটার ছিল - ডাকসের একটি অনুরোধ (প্যারাম) মেমরিতে কোনও নতুন অবজেক্ট তৈরি করতে পারে (এটির প্যারামিটার থাকলে এটি অপ্রাসঙ্গিক হতে পারে)?
ওপল

4
১. আমি বোঝাতে চাইছিলাম যে যদি এক ধরণের হাঁসের প্রচুর সংখ্যক দৃষ্টান্ত থাকে তবে উদাহরণটি সংশোধন করা বোধগম্য হবে যাতে quackফাংশনটি প্রোটোটাইপে থাকে, যার সাথে অনেকগুলি হাঁসের উদাহরণ সংযুক্ত থাকে। ২. বস্তুর আক্ষরিক বাক্য গঠন { ... }একটি উদাহরণ তৈরি করে ( newএটির সাথে ব্যবহারের দরকার নেই )। ৩. যে কোনও ফাংশনকে জেএস কল করার ফলে মেমরিতে কমপক্ষে একটি অবজেক্ট তৈরি হওয়ার কারণ হয় - এটিকে argumentsঅবজেক্ট বলা হয় এবং কলটিতে পাস হওয়া আর্গুমেন্টগুলি সংরক্ষণ করে: ডেভেলপার.মোজিলা.আর
জাভা স্ক্রিপ্ট / রেফারেন্স /

ধন্যবাদ আমি আপনার উত্তর গ্রহণ করেছি। তবে আপনার বক্তব্যটি (1) নিয়ে আমার এখনও কিছুটা বিভ্রান্তি রয়েছে: "আপনি এক ধরণের হাঁসের বড় সংখ্যক উদাহরণ" দিয়ে আপনি কী বোঝাতে চাইছেন তা আমি বুঝতে পারছি না। যেমন আপনি বলেছেন (3) আপনি যখনই জেএস ফাংশনটি কল করেন, তখন একটি জিনিস স্মৃতিতে তৈরি হয় - সুতরাং আপনার যদি কেবল এক ধরণের হাঁস থাকে, আপনি প্রতিবার হাঁসের ফাংশনটি কল করার সময় কি মেমরি বরাদ্দ করবেন না (মধ্যে কোন প্রোটোটাইপটি ব্যবহার করা সর্বদা বোধগম্য হবে)?
ওপল

11
+1 jQuery এর সাথে তুলনা করা ছিল আমি কখন এবং কেন পড়েছিলাম যে প্রোটোটাইপগুলি ব্যবহার করব সে সম্পর্কে তার প্রথম স্পষ্ট এবং সংক্ষিপ্ত ব্যাখ্যা। আপনাকে অনেক ধন্যবাদ.
জিফোলে 83

46

আপনি যদি বস্তুর "অ-স্থিতিশীল" পদ্ধতিটি ঘোষণা করতে চান তবে আপনার প্রোটোটাইপগুলি ব্যবহার করা উচিত।

var myObject = function () {

};

myObject.prototype.getA = function (){
  alert("A");
};

myObject.getB = function (){
  alert("B");
};

myObject.getB();  // This works fine

myObject.getA();  // Error!

var myPrototypeCopy = new myObject();
myPrototypeCopy.getA();  // This works, too.

@keatsKelleher কিন্তু আমরা thisউদাহরণস্বরূপ this.getA = function(){alert("A")}সঠিকভাবে কনস্ট্রাক্টর ফাংশনটির ভিতরে পদ্ধতিটি সংজ্ঞায়িত করে অবজেক্টের জন্য একটি অ স্থির পদ্ধতি তৈরি করতে পারি ?
আমর লবিব

17

অন্তর্নির্মিত prototypeঅবজেক্টটি ব্যবহার করার একটি কারণ হ'ল যদি আপনি এমন কোনও জিনিসকে একাধিকবার নকল করে থাকেন যা সাধারণ কার্যকারিতা ভাগ করে নেবে। প্রোটোটাইপ পদ্ধতি সংযুক্ত করে, আপনি প্রতি newউদাহরণ প্রতি তৈরি হচ্ছে সদৃশ পদ্ধতিতে সংরক্ষণ করতে পারেন । তবে আপনি যখন কোনও পদ্ধতি সংযুক্ত করেন prototype, সমস্ত দৃষ্টান্তগুলিতে সেই পদ্ধতিগুলির অ্যাক্সেস থাকবে।

বলুন আপনার একটি বেস Car()ক্লাস / অবজেক্ট রয়েছে।

function Car() {
    // do some car stuff
}

তারপরে আপনি একাধিক Car()উদাহরণ তৈরি করেন ।

var volvo = new Car(),
    saab = new Car();

এখন, আপনি জানেন যে প্রতিটি গাড়ি চালাতে হবে, চালু করতে হবে ইত্যাদি। সরাসরি Car()ক্লাসের সাথে কোনও পদ্ধতি সংযুক্ত করার পরিবর্তে (যা প্রতিটি প্রতিটির তৈরি মেমরি গ্রহণ করে) পরিবর্তে আপনি পদ্ধতিগুলি প্রোটোটাইপের সাথে সংযুক্ত করতে পারেন (কেবল পদ্ধতিগুলি তৈরি করে) একবার), সুতরাং নতুন volvoএবং উভয় ক্ষেত্রেই এই পদ্ধতিগুলিতে অ্যাক্সেস দেওয়া saab

// just mapping for less typing
Car.fn = Car.prototype;

Car.fn.drive = function () {
    console.log("they see me rollin'");
};
Car.fn.honk = function () {
    console.log("HONK!!!");
}

volvo.honk();
// => HONK!!!
saab.drive();
// => they see me rollin'

4
আসলে এটি ভুল। volvo.honk () আপনি পুরোপুরি প্রোটোটাইপ অবজেক্টটি প্রতিস্থাপন করেছেন, এটি প্রসারিত করেননি বলে কাজ করবে না। আপনি যদি এমন কিছু করতে থাকেন তবে এটি আপনার প্রত্যাশার মতো কাজ করবে: Car.prototype.honk = ফাংশন () so কনসোল.লগ ('হংক');} ভলভো.হোনক (); // 'ভেঁপু'
29er

4
@ 29er - আমি এই উদাহরণটি যেভাবে লিখেছি তা আপনি সঠিক। আদেশ ব্যাপার না। আমি যদি এই উদাহরণটি যেমন রাখি তবে এই jsfiddle এর মধ্যে সচিত্র রূপে Car.prototype = { ... }কল করার আগে অবশ্যই আসতে হবে new Car(): jsfiddle.net/mxacA । আপনার যুক্তি হিসাবে, এটি করার সঠিক উপায় এটি হবে: jsfiddle.net/Embnp । মজার বিষয় হ'ল, আমি এই প্রশ্নের
উত্তরটি

@ হেলাতান আপনি কনস্ট্রাক্টর সেট করে এটি ঠিক করতে পারেন: কার থেকে আপনি কোনও বস্তুর আক্ষরিক সাথে প্রোটোটাইপ সম্পত্তি ওভাররোট করে।
জোশ বেদো 8'14

@ জোশ তা উল্লেখ করার জন্য ধন্যবাদ। আমি আমার উত্তরটি আপডেট করেছি যাতে আমি কোনও বস্তুর আক্ষরিক সাথে প্রোটোটাইপটি ওভাররাইট না করি, যেমন এটি শুরু থেকেই হওয়া উচিত ছিল।
হেল্লাতান

12

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

প্রোটোটাইপ অবজেক্টে পদ্ধতি পরিবর্তন করা বা পদ্ধতি যুক্ত করা, তাত্ক্ষণিকভাবে সম্পর্কিত ধরণের সমস্ত দৃষ্টান্তের প্রকৃতির পরিবর্তন করে।

এখন আপনি কেন এই সমস্ত জিনিসটি করতেন তা হ'ল বেশিরভাগ ক্ষেত্রে আপনার নিজের অ্যাপ্লিকেশন ডিজাইনের একটি ফাংশন এবং ক্লায়েন্ট-সাইড কোডে আপনাকে কী ধরণের জিনিসগুলি করতে হবে। (পুরো আলাদা গল্পটি কোনও সার্ভারের অভ্যন্তরে কোড হতে পারে; সেখানে আরও বৃহত্তর স্কেল "ওও" কোড করার কথাটি কল্পনা করা আরও সহজ))


সুতরাং যখন আমি প্রোটোটাইপ পদ্ধতিগুলি (নতুন কীওয়ার্ডের মাধ্যমে) দিয়ে কোনও নতুন অবজেক্ট ইনস্ট্যান্ট করি, তখন সেই বস্তুটি প্রতিটি ফাংশনের একটি নতুন অনুলিপি পায় না (কেবলমাত্র পয়েন্টারটির মতো)? যদি এটি হয় তবে আপনি প্রোটোটাইপটি ব্যবহার করতে চান না কেন?
ওপল

@ আপি হ্যাঁ, আপনি ঠিক বলেছেন - এখানে কোনও অনুলিপি তৈরি হয়নি। পরিবর্তে, প্রোটোটাইপ অবজেক্টের চিহ্ন (সম্পত্তি নাম) প্রতিটি উদাহরণ বস্তুর ভার্চুয়াল অংশ হিসাবে স্বাভাবিকভাবে "সেখানে" সাজানো থাকে। লোকেরা এটির জন্য উদ্বিগ্ন না হওয়ার একমাত্র কারণ হ'ল ঘটনাগুলি হ'ল বস্তুগুলি স্বল্পস্থায়ী এবং স্বতন্ত্র, বা যেখানে ভাগ করার মতো খুব বেশি "আচরণ" নেই be
পয়েন্টি

3

আমি যদি ক্লাস ভিত্তিক শব্দটিতে ব্যাখ্যা করি তবে ব্যক্তি শ্রেণি, ওয়াক () হ'ল প্রোটোটাইপ পদ্ধতি। সুতরাং আপনি এটির মাধ্যমে নতুন অবজেক্টটি ইনস্ট্যান্ট করলেই ওয়াক () এর অস্তিত্ব থাকবে।

সুতরাং আপনি যদি ব্যক্তির মতো অবজেক্টের অনুলিপি তৈরি করতে চান তবে আপনি অনেক ব্যবহারকারী তৈরি করতে পারেন প্রোটোটাইপ হ'ল সমাধান ভাল কারণ এটি মেমরির প্রতিটি অবজেক্টের জন্য একই কপির ফাংশনটির ভাগ করে / উত্তরাধিকারসূত্রে স্মৃতি সাশ্রয় করে memory

স্থির এই ধরণের দৃশ্যে এত বড় সাহায্য না।

function Person(){
this.name = "anonymous";
}

// its instance method and can access objects data data 
Person.prototype.walk = function(){
alert("person has started walking.");
}
// its like static method
Person.ProcessPerson = function(Person p){
alert("Persons name is = " + p.name);
}

var userOne = new Person();
var userTwo = new Person();

//Call instance methods
userOne.walk();

//Call static methods
Person.ProcessPerson(userTwo);

সুতরাং এটির সাথে এর আরও উদাহরণের পদ্ধতিটি। অবজেক্টের অ্যাপ্রোচ স্ট্যাটিক পদ্ধতির মতো।

https://developer.mozilla.org/en/ ভূমিকা_to_Object- ওরিয়েন্টেড_ জাভা স্ক্রিপ্ট

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