কাইল সিম্পসনের ওলুও প্যাটার্ন বনাম প্রোটোটাইপ ডিজাইনের প্যাটার্ন


109

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

এখানে কাইলি এর প্যাটার্ন একটি উদাহরণ তার বই থেকে, "আপনি জানেন জাতীয় কি: এই & বস্তু অনুকৃতি":

var Foo = {
    init: function(who) {
        this.me = who;
    },
    identify: function() {
        return "I am " + this.me;
    }
};

var Bar = Object.create(Foo);

Bar.speak = function() {
    alert("Hello, " + this.identify() + ".");
};

var b1 = Object.create(Bar);
b1.init("b1");
var b2 = Object.create(Bar);
b2.init("b2");

b1.speak(); // alerts: "Hello, I am b1."
b2.speak(); // alerts: "Hello, I am b2."

2
আপনি যে প্যাটার্নটির বিষয়ে জিজ্ঞাসা করছেন তার বর্ণনার সাথে আপনি কি লিঙ্ক করতে পারেন? এমনকি আপনার প্রশ্নের মধ্যে একটি কোড উদাহরণ প্রদর্শন করা আরও ভাল।
jفر00

4
গ্যাটিফাই কখনও কখনও স্ট্যাকওভারফ্লোতে থাকে। আমি তাকে এই প্রশ্নটি টুইট করেছি :)
পয়েন্টি

উত্তর:


155

তার প্যাটার্নটি ঠিক কী পরিচয় করিয়ে দেয়?

লিওএজটি পেতে অন্য (আইএমও বিভ্রান্তিকর) শব্দার্থবিজ্ঞানের উপর কোনও স্তর তৈরি করার প্রয়োজন ছাড়াই ও ও এল ও ও প্রোটোটাইপ চেইনকে জড়িয়ে ধরে।

সুতরাং, এই দুটি স্নিপেটের হুবহু একই ফলাফল রয়েছে, তবে সেখানে আলাদাভাবে পান।

কনস্ট্রাক্টর ফর্ম:

function Foo() {}
Foo.prototype.y = 11;

function Bar() {}
Bar.prototype = Object.create(Foo.prototype);
Bar.prototype.z = 31;

var x = new Bar();
x.y + x.z;  // 42

ওলু ফর্ম:

var FooObj = { y: 11 };

var BarObj = Object.create(FooObj);
BarObj.z = 31;

var x = Object.create(BarObj);
x.y + x.z;  // 42

উভয় স্নিপেটে, কোনও xবস্তুর [[Prototype]]সাথে একটি বস্তুর ( Bar.prototypeবা BarObj) সংযুক্ত করা হয়, যা ঘুরেফিরে তৃতীয় বস্তু ( Foo.prototypeবা FooObj) এর সাথে সংযুক্ত থাকে ।

স্নিপেটগুলির মধ্যে সম্পর্ক এবং প্রতিনিধিদল অভিন্ন। স্মৃতি ব্যবহার স্নিপেটগুলির মধ্যে অভিন্ন। স্নিপেটের মধ্যে অনেকগুলি "শিশু" তৈরি করার ক্ষমতা (যেমন, অনেকগুলি বস্তুর x1মাধ্যমে x1000ইত্যাদি) সাদৃশ্য। প্রতিনিধিদলের ( x.yএবং x.z) পারফরম্যান্স স্নিপেটগুলির মধ্যে অভিন্ন। বস্তু সৃষ্টি কর্মক্ষমতা হয় OLOO সঙ্গে মন্থর, কিন্তু মানসিক সুস্থতা চেক যে জানায় যে ধীর কর্মক্ষমতা সত্যিই একটি সমস্যা হয় না।

ওএলইও অফারগুলির মধ্যে আমি যে যুক্তি দিচ্ছি তা হ'ল কেবল অবজেক্টগুলি প্রকাশ করা এবং সরাসরি সংযোগ স্থাপনের চেয়ে কন্ট্রাক্টর / newমেকানিজমের মাধ্যমে এগুলি সংযুক্ত করার চেয়ে অনেক সহজ । দ্বিতীয়টি ক্লাস সম্পর্কে ভান করে তবে সত্যই প্রতিনিধি ব্যক্ত করার জন্য এটি একটি ভয়ানক বাক্য গঠন ( পার্শ্ব নোট: এটিও এসএস classসিনট্যাক্স!)।

ওলু মধ্যবিত্তকে সরিয়ে দিচ্ছে।

এখানে ওএলইউ-র তুলনা আরও রয়েছে class


2
আমি আপনার উত্তরটি এবং আপনার বইগুলিতে বর্ণিত ওলু ধারণাটি সত্যিই আকর্ষণীয় পেয়েছি, আমি এই প্রশ্নে আপনার প্রতিক্রিয়া জানাতে চাই: stackoverflow.com/questions/40395762/… বিশেষত যদি আপনি এই বাস্তবায়নটি সঠিকভাবে খুঁজে পেয়েছেন এবং কীভাবে অ্যাক্সেস সম্পর্কিত সমস্যা সমাধান করবেন? ব্যক্তিগত সদস্য আপনার আগাম সময়ের জন্য ধন্যবাদ এবং আপনার সর্বশেষ বইটির জন্য অভিনন্দন।
গিব্বোক

তবে এর Object.create(...)চেয়ে অনেকগুণ ধীর newjsperf.com/object-create-vs-cockockford-vs-jorge-vs-constructor/…
পিয়ার

3
@ পিয়ার পারফরম্যান্স আসলে তেমন সমস্যা হয় না। বিশুদ্ধতা সম্পর্কে ভাঙা ব্লগ পোস্ট লিঙ্কটি স্থির করে বস্তু তৈরির কার্যকারিতা যাচাইয়ের জন্য, যা এটি সম্পর্কে সঠিকভাবে কীভাবে ভাবতে হবে তা ব্যাখ্যা করে।
কাইল সিম্পসন

2
এবং jQuery ডম এপিআই এর চেয়ে ধীর, তাই না? তবে, এটি এখনকার বছর, মানুষ - আমি অনুকূলিতকরণের বিষয়ে চিন্তা করার চেয়ে বরং মার্জিত এবং সহজভাবে লিখতে চাই। যদি পরে আমার মাইক্রো-অপ্টিমাইজ করা দরকার হয়, সময় আসার পরে আমি এটি নিয়ে চিন্তিত হব।
এরিক বার্কল্যান্ড

6
আমি এখন এটি যুক্ত করতে চাই, ঠিক এক বছর পরে, অবজেক্ট.ক্রিয়েট () ক্রোমে প্রচুরভাবে অনুকূলিত হয়েছে, এবং যে জাসস্পারফ এটি দেখায় - এটি এখন দ্রুততম বিকল্পগুলির মধ্যে একটি। এটি ঠিক দেখায় যে আপনি কেন এইরকম মাইক্রো-অপটিমাইজেশনে নিজেকে উদ্বিগ্ন করবেন না এবং পরিবর্তে কেবল অ্যালগোরিদম সাউন্ড কোড লিখুন।
কাইল বেকার 18

25

আমি কাইলের বইটি পড়েছিলাম এবং আমি এটি সত্যই তথ্যবহুল, বিশেষত কীভাবে তার বিশদটি পেয়েছি this আবদ্ধ তা ।

পেশাদাররা:

আমার জন্য ওলু-র বেশ কয়েকটি বড় গুণ রয়েছে:

1. সরলতা

ওএলইউ Object.create()একটি নতুন অবজেক্ট তৈরি করতে নির্ভর করে যা [[prototype]]অন্য বস্তুর সাথে সংযুক্ত। আপনাকে বুঝতে হবে না যে ফাংশনগুলির একটি রয়েছেprototype সম্পত্তি আছে বা এর সংশোধন থেকে আসা সম্ভাব্য সম্পর্কিত যে কোনও সমস্যা সম্পর্কে উদ্বেগ রয়েছে।

2. ক্লিনার সিনট্যাক্স

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

কনস:

আমি মনে করি যে এখানে একটি প্রশ্নোত্তর নকশা রয়েছে (এটি একটি যা আসলে উপরে 2 পয়েন্টে অবদান রাখে), এবং তা ছায়াছবির সাথে করা:

আচরণের প্রতিনিধিদলে, আমরা যদি সম্ভাব্যভাবে সমস্ত [[Prototype]]শৃঙ্খলের বিভিন্ন স্তরে জিনিসটির নামকরণ করা হয় তবে এড়াতে পারি ।

এর পিছনে ধারণাটি হ'ল বস্তুগুলির নিজস্ব আরও সুনির্দিষ্ট ফাংশন থাকে যা পরে অভ্যন্তরীণভাবে শৃঙ্খলে নিচে ফাংশনগুলি অর্পণ করে। উদাহরণস্বরূপ, এতে resourceকোনও save()ফাংশন সহ আপনার কোনও বস্তু থাকতে পারে যা সার্ভারে অবজেক্টটির একটি JSON সংস্করণ প্রেরণ করে, তবে আপনার কাছে এমন কোনও clientResourceবস্তু থাকতে পারে যা একটিতে রয়েছেstripAndSave() ফাংশন যা প্রথমে সার্ভারে প্রেরণ করা হবে না এমন বৈশিষ্ট্যগুলি সরিয়ে দেয় which ।

সম্ভাব্য সমস্যাটি হ'ল: যদি অন্য কেউ উপস্থিত হয় এবং কোনও specialResourceবিষয় তৈরির সিদ্ধান্ত নেন , পুরো প্রোটোটাইপ চেইন সম্পর্কে পুরোপুরি অবগত না হন তবে তারা যুক্তিযুক্তভাবে * কোনও সম্পত্তি হিসাবে অন্তর্গত সংরক্ষণের জন্য একটি টাইমস্ট্যাম্প সংরক্ষণ করার সিদ্ধান্ত নিতে পারে save, যা ভিত্তিটির save()কার্যকারিতাটি ছায়া দেয় resourceবস্তুর প্রোটোটাইপ শৃঙ্খল নিচে দুই লিঙ্ক:

var resource = {
  save: function () { 
    console.log('Saving');
  }
};

var clientResource = Object.create(resource);

clientResource.stripAndSave = function () {
  // Do something else, then delegate
  console.log('Stripping unwanted properties');
  this.save();
};

var specialResource = Object.create( clientResource );

specialResource.timeStampedSave = function () {
  // Set the timestamp of the last save
  this.save = Date.now();
  this.stripAndSave();
};

a = Object.create(clientResource);
b = Object.create(specialResource);

a.stripAndSave();    // "Stripping unwanted properties" & "Saving".
b.timeStampedSave(); // Error!

এটি একটি বিশেষভাবে স্বীকৃত উদাহরণ, তবে মূল বিষয়টি এটি বিশেষভাবে নয় অন্যান্য সম্পত্তি ছায়া করা কিছু বিশ্রী পরিস্থিতি এবং থিসেরসের ভারী ব্যবহারের কারণ হতে পারে!

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

* আসলে এটি বিশেষভাবে যুক্তিসঙ্গত নয় ( lastSavedএটি আরও ভাল হবে তবে এটি কেবল একটি উদাহরণ।)


23
আমি সম্মত হই যে নামের সংঘর্ষের সম্ভাবনাটি একটি অসুবিধা ... তবে আসলে এটি [[Prototype]]সিস্টেমেরই একটি অপূর্ণতা , বিশেষত ওলুও নয়।
কাইল সিম্পসন

সম্ভবত বইতেও এটি উল্লেখ করা উচিত ছিল?
ভাড়া

আমি নই সত্যিই নিশ্চিত এই সত্যিই সমস্যার একটি সমাধান @Ed Hinchliffe বর্ণনা যেহেতু এটি শুধু এটা সংরক্ষণ (প্যাচসমূহ) নিজের নামস্থান হয় কিন্তু এটি কাজ করে codepen.io/tforward/pen/govEPr?editors=1010
ট্রিস্টান ফরোয়ার্ড

আমার মনে হয় কোড স্নিপেটের শেষ লাইনের b.timeStampedSave();পরিবর্তে @ এডি-হিঙ্কলিফ মানে a.timeStampedSave();
amangpt777

1
@ ট্রিস্টান-ফরোয়ার্ড রিক এবং মর্তিকে এতে আনার জন্য আপনাকে ধন্যবাদ!
এরিক বিশার্ড

13

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

1

যখন "শ্রেণি" "ক্লাসিকাল প্যাটার্নে" অন্য "শ্রেণি" উত্তরাধিকার সূত্রে প্রাপ্ত হয়, তখন দুটি ফাংশনকে অনুরূপ সিনট্যাক্স হিসাবে ঘোষণা করা যেতে পারে ( "ফাংশন ঘোষণা" বা "ফাংশন বিবৃতি" ):

function Point(x,y) {
    this.x = x;
    this.y = y;
};

function Point3D(x,y,z) {
    Point.call(this, x,y);
    this.z = z;
};

Point3D.prototype = Object.create(Point.prototype);

বিপরীতে, ওলু প্যাটার্নে, বেস এবং উত্পন্ন বস্তুর সংজ্ঞা দেওয়ার জন্য বিভিন্ন সিনট্যাক্টিকাল ফর্মগুলি ব্যবহার করা হয়:

var Point = {
    init  : function(x,y) {
        this.x = x;
        this.y = y;
    }
};


var Point3D = Object.create(Point);
Point3D.init = function(x,y,z) {
    Point.init.call(this, x, y);
    this.z = z;
};

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

2

ওলু পদ্ধতিতে, কোনও বস্তু তৈরি করা দুটি ধাপ:

  1. কল Object.create
  2. অবজেক্টটি আরম্ভ করার জন্য কিছু কাস্টম, অ-মানক পদ্ধতিতে কল করুন (যা আপনাকে মনে রাখতে হবে যেহেতু এটি এক বস্তুর থেকে পরেরটিতে পরিবর্তিত হতে পারে):

     var p2a = Object.create(Point);
    
     p2a.init(1,1);

বিপরীতে, প্রোটোটাইপ প্যাটার্নে আপনি স্ট্যান্ডার্ড অপারেটরটি ব্যবহার করেন new:

var p2a = new Point(1,1);

3

শাস্ত্রীয় প্যাটার্নে আমি "স্থিতিশীল" ইউটিলিটি ফাংশন তৈরি করতে পারি যা সরাসরি "ক্লাস" ফাংশনে (তার বিপরীতে .prototype) সরাসরি অর্পণ করে কোনও "তাত্ক্ষণিক" -এ প্রয়োগ হয় না । যেমন squareনীচের কোডে ফাংশনের মতো :

Point.square = function(x) {return x*x;};

Point.prototype.length = function() {
    return Math.sqrt(Point.square(this.x)+Point.square(this.y));
};

বিপরীতে, ওলু প্যাটার্নে কোনও "স্ট্যাটিক" ফাংশন ([[প্রোটোটাইপ]] চেইনের মাধ্যমে) অবজেক্টের উদাহরণগুলিতেও উপলব্ধ:

var Point = {
    init  : function(x,y) {
        this.x = x;
        this.y = y;
    },
    square: function(x) {return x*x;},
    length: function() {return Math.sqrt(Point.square(this.x)+Point.square(this.y));}
};

2
আপনার প্রথম কোড উদাহরণে কোনও আক্ষরিক নেই। আপনি সম্ভবত "আক্ষরিক" শব্দটির অপব্যবহার করছেন এটির অন্য অর্থ প্রদান করে। শুধু বলছি ...
ইভান ক্লেশিনিন

2
২ য় বিষয় সম্পর্কে লেখক যুক্তি দেখিয়েছেন যে সৃষ্টি ও সূচনা পৃথক করা উদ্বেগের একটি "আরও ভাল" বিভাজন এবং উল্লেখ করা হয়েছে যে এটি বিরল ব্যবহারের ক্ষেত্রে ঘটতে পারে যেখানে এটি জ্বলতে পারে (উদাহরণস্বরূপ কোনও বস্তু পুল)। যুক্তিটি আমি ভীষণ দুর্বল বলে মনে করি।
ভাড়া

2
আবার ওএলইউ-র সাথে দ্বিতীয় দফার বিষয়ে আপনি একবারে আপনার বস্তু তৈরি করতে পারেন এবং আরম্ভ করার জন্য অপেক্ষা করতে পারেন, যেখানে কনস্ট্রাক্টরের সাথে আপনাকে তৈরির সূচনা করতে হবে, তাই কাইল এটিকে একটি সুবিধা হিসাবে বিবেচনা করে।
টাকো

5

"আমি ভেবে দেখেছি এটি প্রতিটি আপত্তিটিকে অন্যের উপর নির্ভরশীল করে তোলে"

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

var foo= {},
    bar= Object.create(foo),
    baz= Object.create(bar);


console.log(Object.getPrototypeOf(foo)) //Object.prototype

console.log(Object.getPrototypeOf(bar)) //foo

console.log(Object.getPrototypeOf(baz)) //bar

এখন আপনি একটি সেকেন্ডের জন্য চিন্তা করুন foo barএবংbaz একে অপরের উপর নির্ভরশীল হিসাবে ?

এবার এই constructorস্টাইলের কোডটি একই করুন-

function Foo() {}

function Bar() {}

function Baz() {}

Bar.prototype= Object.create(Foo);
Baz.prototype= Object.create(Bar);

var foo= new Foo(),
    bar= new Bar().
    baz= new Baz();

console.log(Object.getPrototypeOf(foo)) //Foo.prototype
console.log(Object.getPrototypeOf(Foo.prototype)) //Object.prototype

console.log(Object.getPrototypeOf(bar)) //Bar.prototype
console.log(Object.getPrototypeOf(Bar.prototype)) //Foo.prototype

console.log(Object.getPrototypeOf(baz)) //Baz.prototype
console.log(Object.getPrototypeOf(Baz.prototype)) //Bar.prototype

শুধু পার্থক্য B / W আধুনিক ও সাবেক কোডটি আধুনিক একটিতে আছে foo, bar, bazbbjects প্রতিটি-অপরকে তাদের স্বেচ্ছাচারী বস্তু মাধ্যমে সংযুক্ত থাকে constructorফাংশন ( Foo.prototype, Bar.prototype, Baz.prototype) কিন্তু সাবেক এক (মধ্যে OLOOশৈলী) তারা সরাসরি লিঙ্ক করা হয়। উভয় উপায় আপনি শুধু লিঙ্ক করছি foo, bar, bazএকে অপরের সাথে সরাসরি সাবেক এক এবং পরোক্ষভাবে আধুনিক এক। তবে, উভয় ক্ষেত্রেই বস্তুগুলি একে অপরের থেকে স্বাধীন কারণ এটি সত্যই কোনও শ্রেণীর উদাহরণের মতো নয় যা একবার তাত্ক্ষণিকভাবে চালিত হয়েছিল, অন্য কোনও শ্রেণীর কাছ থেকে উত্তরাধিকারী হতে পারে না। আপনি সর্বদা পরিবর্তন করতে পারেন কোন বস্তুর কোন প্রতিনিধিত্ব করা উচিত।

var anotherObj= {};
Object.setPrototypeOf(foo, anotherObj);

সুতরাং তারা সবাই একে অপরের থেকে স্বতন্ত্র।

"আমি আশা করছিলাম OLOOযে এই সমস্যাটি সমাধান করা হবে যেখানে প্রতিটি বস্তু অপরটি সম্পর্কে কিছুই জানে না।"

হ্যাঁ এটা সত্যিই সম্ভব-

Techইউটিলিটি অবজেক্ট হিসাবে ব্যবহার করা যাক-

 var Tech= {
     tag: "technology",
     setName= function(name) {
              this.name= name;
}
}

আপনি যতগুলি সংযুক্তি করতে চান তত বেশি বস্তু তৈরি করুন Tech-

var html= Object.create(Tech),
     css= Object.create(Tech),
     js= Object.create(Tech);

Some checking (avoiding console.log)- 

    html.isPrototypeOf(css); //false
    html.isPrototypeOf(js); //false

    css.isPrototypeOf(html); //false
    css.isPrototypeOf(js); //false

    js.isPrototypeOf(html); //false
    js.isPrototypwOf(css); //false

    Tech.isPrototypeOf(html); //true
    Tech.isPrototypeOf(css); //true
    Tech.isPrototypeOf(js); //true

আপনি কি মনে করেন html, css, jsবস্তু একে-অপরের সাথে সংযুক্ত করা হয়? না, তারা না। এখন আসুন আমরা constructorফাংশন- এর মাধ্যমে এটি কীভাবে করতে পারি তা দেখুন-

function Tech() { }

Tech.prototype.tag= "technology";

Tech.prototype.setName=  function(name) {
              this.name= name;
}

আপনি যতগুলি সংযুক্তি করতে চান তত বেশি বস্তু তৈরি করুন Tech.proptotype-

var html= new Tech(),
     css= new Tech(),
      js= new Tech();

কিছু পরীক্ষা করা হচ্ছে (কনসোল.লগ এড়ানো) -

html.isPrototypeOf(css); //false
html.isPrototypeOf(js); //false

css.isPrototypeOf(html); //false
css.isPrototypeOf(js); //false

js.isPrototypeOf(html); //false
js.isPrototypeOf(css); //false

Tech.prototype.isPrototypeOf(html); //true
Tech.prototype.isPrototypeOf(css); //true
Tech.prototype.isPrototypeOf(js); //true

এইসব মনে কেমন করে থাকে constructor-style অবজেক্টস ( html, css, js) অবজেক্টস থেকে পৃথক OLOO-style কোড? আসলে তারা একই উদ্দেশ্য পরিবেশন। ইন OLOO-style এক প্রতিনিধি বস্তু Tech(প্রতিনিধিদল স্পষ্টভাবে নির্ধারণ করা হয়েছে) যখন constructor-style এক প্রতিনিধি বস্তু Tech.prototype(প্রতিনিধিদল পরোক্ষভাবে হয়)। অবশেষে আপনি তিনটি অবজেক্টের সাথে একে অপরের সাথে কোনও সংযোগ না রেখে, একটি বস্তুর সাথে সরাসরি- OLOOস্টাইল ব্যবহার করে , অপ্রত্যক্ষভাবে constructorস্টাইল ব্যবহার করে লিঙ্কটি শেষ করবেন।

"যেমনটি, ওজেজেবি তৈরি করতে হবে ওবজা থেকে .. অবজেক্ট.ক্রিয়েট (ওবিজেবি) ইত্যাদি"

না, ObjBএখানে কোনও শ্রেণীর উদাহরণ (শাস্ত্রীয় ভিত্তিক ভাষাগুলির) মতো নয় ObjAএটি objBএমনভাবে বলা যেতে পারে যেমন ObjAতার তৈরির সময় অবজেক্টটিকে প্রতিনিধি হিসাবে তৈরি করা হয় " । আপনি যদি কনস্ট্রাক্টর ব্যবহার করেন তবে আপনি একই 'কাপলিং' করতেন, যদিও পরোক্ষভাবে .prototypeগুলি ব্যবহার করে of


3

@ মারকাস @ ভোলবেন

সম্ভবত আমরা এই জাতীয় কিছু করতে পারি।

    const Point = {

        statics(m) { if (this !== Point) { throw Error(m); }},

        create (x, y) {
            this.statics();
            var P = Object.create(Point);
            P.init(x, y);
            return P;
        },

        init(x=0, y=0) {
            this.x = x;
            this.y = y;
        }
    };


    const Point3D = {

        __proto__: Point,

        statics(m) { if (this !== Point3D) { throw Error(m); }},

        create (x, y, z) {
            this.statics();
            var P = Object.create(Point3D);
            P.init(x, y, z);
            return P;
        },

        init (x=0, y=0, z=0) {
            super.init(x, y);
            this.z = z;
        }
    }; 

অবশ্যই, একটি পয়েন্ট 3 ডি অবজেক্ট তৈরি করা যা পয়েন্ট 2 ডি অবজেক্টের প্রোটোটাইপের সাথে লিঙ্ক করা এক ধরণের নির্বোধ, তবে এটি বিন্দুর পাশে রয়েছে (আমি আপনার উদাহরণের সাথে সামঞ্জস্য রাখতে চেয়েছিলাম)। যাইহোক, অভিযোগ যতদূর যায়:

  1. অসম্পূর্ণতা ES6 এর অবজেক্ট.সেটপ্রোটোটাইপএফ বা __proto__ = ...আমি যেটি ব্যবহার করি তার উপর আরও ভ্রূণিত করা যায় । আমরা এখন নিয়মিত বস্তুগুলিতেও সুপার ব্যবহার করতে পারি , যেমনটি দেখা গেছে Point3D.init()। আরেকটি উপায় হতে পারে এর মতো কিছু করা

    const Point3D = Object.assign(Object.create(Point), {  
        ...  
    }   

    যদিও আমি বিশেষভাবে বাক্য গঠন পছন্দ করি না।


  1. আমরা সবসময় কেবল মোড়তে পারি p = Object.create(Point)এবং তারপরে p.init()একটি কনস্ট্রাক্টরের মধ্যে। যেমন Point.create(x,y)। উপরের কোডটি ব্যবহার করে আমরা Point3Dনিম্নলিখিত পদ্ধতিতে একটি "উদাহরণ" তৈরি করতে পারি ।

    var b = Point3D.create(1,2,3);
    console.log(b);                         // { x:1, y:2, z:3 }
    console.log(Point.isPrototypeOf(b));    // true
    console.log(Point3D.isPrototypeOf(b))   // true

  1. আমি ওএলইও-তে স্থির পদ্ধতিগুলি অনুকরণ করতে এই হ্যাকটি নিয়ে এসেছি। আমি এটি পছন্দ করি বা না জানি তা নিশ্চিত নই। এটি কোনও "স্থিতিশীল" পদ্ধতির শীর্ষে একটি বিশেষ সম্পত্তি কল করার প্রয়োজন। উদাহরণস্বরূপ, আমি Point.create()পদ্ধতিটি স্থির করেছি ।

        var p = Point.create(1,2);
        var q = p.create(4,1);          // Error!  

অন্যথা, ES6 সঙ্গে প্রতীকসমূহ আপনি নিরাপদে জাভাস্ক্রিপ্ট বেস ক্লাস প্রসারিত করতে পারেন। সুতরাং আপনি নিজেকে কিছু কোড সংরক্ষণ করতে পারেন এবং অবজেক্ট.প্রোটোটাইপে বিশেষ সম্পত্তিটি নির্ধারণ করতে পারেন। উদাহরণ স্বরূপ,

    const extendedJS = {};  

    ( function(extension) {

        const statics = Symbol('static');

        Object.defineProperty(Object.prototype, statics, {
            writable: true,
            enumerable: false,
            configurable: true,
            value(obj, message) {
                if (this !== obj)
                    throw Error(message);
            }
        });

        Object.assign(extension, {statics});

    })(extendedJS);


    const Point = {
        create (x, y) {
            this[extendedJS.statics](Point);
            ...


2

@ জেমস ইমানন - সুতরাং, আপনি একাধিক উত্তরাধিকারের কথা উল্লেখ করছেন ("আপনি জেএস জানেন না: এই & অবজেক্ট প্রোটোটাইপস" বইয়ের 75 পৃষ্ঠায় আলোচিত)। এবং সেই প্রক্রিয়াটি আমরা উদাহরণস্বরূপ আন্ডারস্কোরের "প্রসারিত" ফাংশনটিতে খুঁজে পেতে পারি। আপনার উদাহরণে আপনি যে অবজেক্টের নাম বলেছেন সেটি হল আপেল, কমলা এবং ক্যান্ডিসের সাথে কিছুটা মিশ্রণ তবে আমি পিছনের বিষয়টিটি বুঝতে পারি। আমার অভিজ্ঞতা থেকে এটি OOLO সংস্করণ হবে:

var ObjA = {
  setA: function(a) {
    this.a = a;
  },
  outputA: function() {
    console.log("Invoking outputA - A: ", this.a);
  }
};

// 'ObjB' links/delegates to 'ObjA'
var ObjB = Object.create( ObjA );

ObjB.setB = function(b) {
   this.b = b;
}

ObjB.setA_B = function(a, b) {
    this.setA( a ); // This is obvious. 'setA' is not found in 'ObjB' so by prototype chain it's found in 'ObjA'
    this.setB( b );
    console.log("Invoking setA_B - A: ", this.a, " B: ", this.b);
};

// 'ObjC' links/delegates to 'ObjB'
var ObjC = Object.create( ObjB );

ObjC.setC = function(c) {
    this.c = c;  
};

ObjC.setA_C = function(a, c) {
    this.setA( a ); // Invoking 'setA' that is clearly not in ObjC shows that prototype chaining goes through ObjB all the way to the ObjA
    this.setC( c );
    console.log("Invoking setA_C - A: ", this.a, " C: ", this.c);
};

ObjC.setA_B_C = function(a, b, c){
    this.setA( a ); // Invoking 'setA' that is clearly not in ObjC nor ObjB shows that prototype chaining got all the way to the ObjA
    this.setB( b );
    this.setC( c );
    console.log("Invoking setA_B_C - A: ", this.a, " B: ", this.b, " C: ", this.c);
};

ObjA.setA("A1");
ObjA.outputA(); // Invoking outputA - A:  A1

ObjB.setA_B("A2", "B1"); // Invoking setA_B - A:  A2  B:  B1

ObjC.setA_C("A3", "C1"); // Invoking setA_C - A:  A3  C:  C1
ObjC.setA_B_C("A4", "B2", "C1"); // Invoking setA_B_C - A:  A4  B:  B2  C:  C1

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

অন্য কথায়, প্রকৃত যান্ত্রিকতা, জাভাস্ক্রিপ্টে আমরা যে কার্যকারিতাটি লাভ করতে পারি তার জন্য কী গুরুত্বপূর্ণ, এর অর্থ হ'ল সমস্ত বস্তুর সাথে অন্য বস্তুর সাথে সংযুক্ত হওয়া

আমি বুঝতে পেরেছি যে আপনার জন্য আরও প্রাকৃতিক উপায় হ'ল সমস্ত "প্যারেন্ট" (সাবধান :)) অবজেক্টগুলিকে এক জায়গায় / ফাংশন কলের পরিবর্তে পুরো চেইনের মডেলিং করতে হবে।

এর জন্য যা প্রয়োজন তা হ'ল আমাদের অ্যাপ্লিকেশনগুলিতে সেই অনুযায়ী চিন্তাভাবনা এবং মডেলিংয়ের সমস্যাগুলি পরিবর্তন করা। আমিও এর অভ্যস্ত হয়ে যাচ্ছি। আশা করি এটি সাহায্য করে এবং কাইলের কাছ থেকে চূড়ান্ত রায়টি দুর্দান্ত হবে। :)


হ্যাঁ - ধন্যবাদ - তবে আমি এই পদ্ধতিটি থেকে সরে আসার প্রত্যাশা করছিলাম কারণ আপনার কাছে যে পদ্ধতিটি রয়েছে এবং যেভাবে আমি এটি করতে পেরেছি তা প্রতিটি বিষয়টিকে অন্যটির উপর নির্ভরশীল করে তুলেছে .. আমি আশা করছিলাম যে ওলুও এই সমস্যার সমাধান করবে would প্রতিটি বস্তু অপরের সম্পর্কে কিছুই জানে না। যেমন, ObjA তৈরি করতে হবে ObjA .. Object.create (ObjB) ইত্যাদি .. এটি খুব মিলিত। কোন ধারনা?
জেমস ইমানন

-1

@ মার্কাস, ঠিক আপনার মতোই, আমিও ওলু-র প্রতি আগ্রহী এবং আপনার প্রথম পয়েন্টে বর্ণিত অসম্পূর্ণতাও অপছন্দ করি। প্রতিসাম্যতা ফিরিয়ে আনতে আমি একটি বিমূর্ততা নিয়ে খেলছি। আপনি ব্যবহার করতে পারেন link()যে একটি ফাংশন তৈরি করতে পারে Object.create()। যখন ব্যবহার করা হয়, তখন আপনার কোডটি এ জাতীয় কিছু দেখতে পারে ...

var Point = {
    init  : function(x,y) {
        this.x = x;
        this.y = y;
    }
};


var Point3D = link(Point, {
    init: function(x,y,z) {
        Point.init.call(this, x, y);
        this.z = z;
    }
});

মনে রাখবেন Object.create()এর একটি দ্বিতীয় প্যারামিটার রয়েছে যা পাস হতে পারে Here এখানে লিঙ্ক ফাংশনটি রয়েছে যা দ্বিতীয় প্যারামিটারটি উপকৃত করে। এটি কিছুটা কাস্টম কনফিগারেশনকেও অনুমতি দেয় ...

function link(delegate, props, propsConfig) {
  props = props || {};
  propsConfig = propsConfig || {};

  var obj = {};
  Object.keys(props).forEach(function (key) {
    obj[key] = {
      value: props[key],
      enumerable: propsConfig.isEnumerable || true,
      writable: propsConfig.isWritable || true,
      configurable: propsConfig.isConfigurable || true
    };
  });

  return Object.create(delegate, obj);
}

অবশ্যই, আমার কাছে মনে হয় @ init()কাইল পয়েন্ট 3 ডি অবজেক্টে ফাংশনটি ছায়া দিয়ে দেখবেন না । ;-)


এর মাধ্যমে ফিরে তাকানোর ক্ষেত্রে, আমি এখন মনে করি যে এর Object.assign()সাথে একত্রিত হয়ে Object.create()আমরা link()উপরের ফাংশনটি ব্যাপকভাবে সহজ করতে পারি । তার জায়গা, আমরা এই ব্যবহার করতে পারে: function create(delegate, props) { return Object.assign(Object.create(delegate), props); }। বা আরো ভালো এখনো, আমরা এটা সত্যিই সংক্ষিপ্ত করতে আন্ডারস্কোর বা Lodash ব্যবহার করতে পারেন: _.create(delegate, props)
ভোলবেন

-1

"দুটি" অবজেক্টের চেয়ে বেশি ওলু-র কোনও উপায় আছে .. আমি যে উদাহরণগুলিকে ভিত্তি করে তৈরি করি (ওপি-র উদাহরণ দেখুন)। আসুন আমরা বলি যে নিম্নলিখিত বিষয়গুলি ছিল, আমরা কীভাবে একটি "চতুর্থ" অবজেক্ট তৈরি করতে পারি যেখানে 'অন্যান্য' তিনটির বৈশিষ্ট্য রয়েছে? Ala ...

var Button = {
     init: function(name, cost) {
       this.buttonName = name;
       this.buttonCost = cost;
     }
}

var Shoe = {
     speed: 100
}

var Bike = {
     range: '4 miles'
}

এই অবজেক্টগুলি নির্বিচারে, এবং সমস্ত ধরণের আচরণকে ঘিরে রাখতে পারে। তবে সংক্ষিপ্তসারটি হ'ল, আমাদের কাছে 'এন' সংখ্যা রয়েছে এবং আমাদের নতুন অবজেক্টের তিনটি থেকেই কিছু প্রয়োজন।

আলা পরিবর্তিত উদাহরণগুলির পরিবর্তে:

var newObj = Object.create(oneSingularObject);
    newObj.whatever..

তবে আমাদের নতুন অবজেক্ট = (বাটন, বাইক, জুতো) ......

ওলুওতে এটি পেতে প্যাটার্নটি কী?


1
এটি "উত্তরাধিকারের চেয়ে বেশি রচনাটির পক্ষপাতিত্ব" - এর মতো দুর্দান্ত কৌশল sounds ES6- এ আপনি ব্যবহার করতে পারেন Object.assign()- developer.mozilla.org/en-US/docs/Web/JavaScript/References/… । যদি ES5 তে লেখা হয় তবে আপনি _.extend()অ্যান্ডস্কোর বা লোডাশ ব্যবহার করতে পারেন _.assign()। এখানে ব্যাখ্যা করার জন্য একটি দুর্দান্ত ভিডিও ... youtu.be/wfMtDGfHWpA । আপনার যদি কোনও সংঘর্ষ সম্পর্কিত সম্পত্তি থাকে তবে শেষটি জয়ী হয় - সুতরাং অর্ডারগুলি গুরুত্বপূর্ণ।
ভোলবেন
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.