কীভাবে জাভাস্ক্রিপ্টে একটি কাস্টম অবজেক্ট "সঠিকভাবে" তৈরি করবেন?


471

আমি জাভাস্ক্রিপ্ট অবজেক্ট তৈরি করা যা এর বৈশিষ্ট্য এবং পদ্ধতি রয়েছে তার সেরা উপায়টি সম্পর্কে আমি অবাক হয়েছি।

সুযোগটি সর্বদা সঠিক কিনা তা নিশ্চিত করার জন্য আমি ব্যক্তি উদাহরণগুলি দেখেছি যেখানে ব্যক্তি ব্যবহার করেছে var self = thisএবং তারপরে self.সমস্ত ফাংশনে ব্যবহার করে।

তারপরে আমি .prototypeবৈশিষ্ট্য যুক্ত করতে ব্যবহার করার উদাহরণগুলি দেখেছি , অন্যরা এটি ইনলাইন করে।

কেউ আমাকে কিছু বৈশিষ্ট্য এবং পদ্ধতি সহ জাভাস্ক্রিপ্ট অবজেক্টের উপযুক্ত উদাহরণ দিতে পারেন?


13
কোনও "সেরা" উপায় নেই।
ট্রিপটিচ

নয় selfএকটি সংরক্ষিত শব্দ? যদি না হয়, এটি হওয়া উচিত; যেহেতু selfবর্তমান উইন্ডোটি উল্লেখ করে একটি পূর্বনির্ধারিত পরিবর্তনশীল। self === window
শাজ

2
@ শ্যাজ: এটি windowব্রাউজার অবজেক্ট মডেলের মতো documentবা অন্য বৈশিষ্ট্যের চেয়ে কোনও সংরক্ষিত শব্দ নয় frames; আপনি অবশ্যই ভেরিয়েবলের নাম হিসাবে শনাক্তকারীটিকে পুনরায় ব্যবহার করতে পারেন। যদিও, হ্যাঁ, স্টাইলিস্টিকভাবে আমি var that= thisকোনও সম্ভাব্য বিভ্রান্তি এড়াতে পছন্দ করি । যদিও window.selfচূড়ান্তভাবে অর্থহীন তাই এটিকে স্পর্শ করার খুব কমই কারণ রয়েছে।
ববিনস

7
যখন জেএসকে সংক্ষিপ্ত করা হয়, thisস্থানীয় ভেরিয়েবলকে নির্ধারণ করা (যেমন self) ফাইলের আকার হ্রাস করে।
প্যাট্রিক ফিশার

Classjs নতুন লিঙ্ক: github.com/divio/classjs
নিকোলা

উত্তর:


889

জাভাস্ক্রিপ্টে ক্লাস এবং ইনস্ট্যান্স বাস্তবায়নের জন্য দুটি মডেল রয়েছে: প্রোটোটাইপিং উপায় এবং ক্লোজার ওয়ে। উভয়েরই সুবিধাগুলি এবং ত্রুটি রয়েছে এবং প্রচুর পরিমাণে বর্ধিত বৈচিত্র রয়েছে। অনেক প্রোগ্রামার এবং গ্রন্থাগারগুলির ভাষার কিছু কুরুচিপূর্ণ অংশের উপর কাগজপত্রের জন্য বিভিন্ন পদ্ধতি এবং শ্রেণি-পরিচালনার ইউটিলিটি ফাংশন রয়েছে।

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

প্রোটোটাইপ উপায় দিয়ে শুরু করা যাক । এটি আপনি পেতে পারেন এমন সর্বাধিক জাভাস্ক্রিপ্ট-নেটিভ: এখানে সর্বনিম্ন ওভারহেড কোড রয়েছে এবং উদাহরণস্বরূপ এই ধরণের অবজেক্টের উদাহরণ দিয়ে কাজ করবে।

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

এই কন্সট্রাক্টর ফাংশনটির অনুসন্ধানে new Shapeতাদের লিখে লিখে তৈরি করা مثالগুলিতে আমরা পদ্ধতিগুলি যুক্ত করতে পারি prototype:

Shape.prototype.toString= function() {
    return 'Shape at '+this.x+', '+this.y;
};

এখন এটি সাবক্লাস করার জন্য, যতটা আপনি জাভাস্ক্রিপ্ট সাবক্লাসিং করে কল করতে পারেন। আমরা সেই অদ্ভুত যাদু prototypeসম্পত্তিটি পুরোপুরি প্রতিস্থাপন করে তা করি :

function Circle(x, y, r) {
    Shape.call(this, x, y); // invoke the base class's constructor function to take co-ords
    this.r= r;
}
Circle.prototype= new Shape();

এটিতে পদ্ধতি যুক্ত করার আগে:

Circle.prototype.toString= function() {
    return 'Circular '+Shape.prototype.toString.call(this)+' with radius '+this.r;
}

এই উদাহরণটি কাজ করবে এবং আপনি অনেক টিউটোরিয়ালে এটির মতো কোড দেখতে পাবেন। কিন্তু মানুষ, এটি new Shape()কুৎসিত: আমরা প্রকৃত শেপ তৈরি না করা সত্ত্বেও বেস ক্লাসটি ইনস্ট্যান্ট করছি। এটা এই সহজ ক্ষেত্রে কাজ ঘটবে কারণ জাভাস্ক্রিপ্ট তাই পঙ্কিল: এটি পারবেন শূন্য যুক্তি পাস করা যে ক্ষেত্রে xএবং yপরিণত undefinedএবং প্রোটোটাইপ এর হস্তান্তর করা হয়েছে this.xএবং this.y। যদি কনস্ট্রাক্টর ফাংশন আরও জটিল কিছু করে থাকে তবে এটি তার মুখের উপর ফ্ল্যাট পড়বে।

সুতরাং আমাদের যা করা দরকার তা হল একটি প্রোটোটাইপ অবজেক্ট তৈরির একটি উপায় সন্ধান করা যা বেস ক্লাসের কনস্ট্রাক্টর ফাংশনটিকে কল না করে ক্লাস পর্যায়ে আমাদের প্রয়োজনীয় পদ্ধতি এবং অন্যান্য সদস্য ধারণ করে want এটি করতে আমাদের হেল্পার কোড লেখা শুরু করতে হবে। এটি আমার জানা সবচেয়ে সহজ পন্থা:

function subclassOf(base) {
    _subclassOf.prototype= base.prototype;
    return new _subclassOf();
}
function _subclassOf() {};

এটি বেস শ্রেণীর সদস্যদের প্রোটোটাইপে একটি নতুন কনস্ট্রাক্টর ফাংশনে স্থানান্তর করে যা কিছুই করে না, তারপরে সেই কনস্ট্রাক্টর ব্যবহার করে। এখন আমরা সহজভাবে লিখতে পারি:

function Circle(x, y, r) {
    Shape.call(this, x, y);
    this.r= r;
}
Circle.prototype= subclassOf(Shape);

পরিবর্তে new Shape()অন্যায়ের। আমাদের কাছে এখন নির্মিত ক্লাসগুলিতে আদিমতার একটি গ্রহণযোগ্য সেট রয়েছে।

এই মডেলটির অধীনে আমরা কয়েকটি পরিমার্জন এবং এক্সটেনশন বিবেচনা করতে পারি। উদাহরণস্বরূপ এখানে একটি সিনট্যাক্টিকাল-চিনির সংস্করণ রয়েছে:

Function.prototype.subclass= function(base) {
    var c= Function.prototype.subclass.nonconstructor;
    c.prototype= base.prototype;
    this.prototype= new c();
};
Function.prototype.subclass.nonconstructor= function() {};

...

function Circle(x, y, r) {
    Shape.call(this, x, y);
    this.r= r;
}
Circle.subclass(Shape);

উভয় সংস্করণেই এমন একটি অপূর্ণতা রয়েছে যা নির্মাণকারী ফাংশন উত্তরাধিকার সূত্রে প্রাপ্ত হতে পারে না, কারণ এটি অনেক ভাষায়। সুতরাং এমনকি যদি আপনার সাবক্লাসটি নির্মাণ প্রক্রিয়াতে কিছু না জুড়ে, তবে অবশ্যই বেসটি যা চায় তত যুক্তি দিয়ে বেস কনস্ট্রাক্টরকে কল করতে হবে। এটি ব্যবহার করে সামান্য স্বয়ংক্রিয় করা যেতে পারে apply, তবে তবুও আপনাকে লিখতে হবে:

function Point() {
    Shape.apply(this, arguments);
}
Point.subclass(Shape);

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

function Shape() { this._init.apply(this, arguments); }
Shape.prototype._init= function(x, y) {
    this.x= x;
    this.y= y;
};

function Point() { this._init.apply(this, arguments); }
Point.subclass(Shape);
// no need to write new initialiser for Point!

এখন আমরা প্রতিটি ক্লাসের জন্য একই কনস্ট্রাক্টর ফাংশন বয়লারপ্লেট পেয়েছি। হতে পারে আমরা এটিকে তার নিজস্ব সহায়ক ফাংশনে স্থানান্তর করতে পারি সুতরাং এটি টাইপ করতে হবে না, উদাহরণস্বরূপ পরিবর্তে Function.prototype.subclass, এটি ঘুরিয়ে দেওয়া এবং বেস শ্রেণির ফাংশনটিকে উপক্লাসটি থুতু দেওয়া:

Function.prototype.makeSubclass= function() {
    function Class() {
        if ('_init' in this)
            this._init.apply(this, arguments);
    }
    Function.prototype.makeSubclass.nonconstructor.prototype= this.prototype;
    Class.prototype= new Function.prototype.makeSubclass.nonconstructor();
    return Class;
};
Function.prototype.makeSubclass.nonconstructor= function() {};

...

Shape= Object.makeSubclass();
Shape.prototype._init= function(x, y) {
    this.x= x;
    this.y= y;
};

Point= Shape.makeSubclass();

Circle= Shape.makeSubclass();
Circle.prototype._init= function(x, y, r) {
    Shape.prototype._init.call(this, x, y);
    this.r= r;
};

... যা অন্য ভাষার মতো আরও কিছুটা দেখতে শুরু করেছে, যদিও সামান্য ক্লামিয়ার সিনট্যাক্স সহ। আপনি চাইলে কয়েকটি অতিরিক্ত বৈশিষ্ট্যগুলিতে ছিটিয়ে দিতে পারেন। হতে পারে আপনি makeSubclassকোনও শ্রেণীর নাম নিতে এবং মনে রাখতে এবং toStringএটি ব্যবহার করে একটি ডিফল্ট সরবরাহ করতে চান। সম্ভবত আপনি নির্মাতাকে দুর্ঘটনাক্রমে newঅপারেটর ছাড়া কল করা হলে এটি সনাক্ত করতে চান (যা অন্যথায় প্রায়শই খুব বিরক্তিকর ডিবাগ হওয়ার কারণ হয়ে থাকে):

Function.prototype.makeSubclass= function() {
    function Class() {
        if (!(this instanceof Class))
            throw('Constructor called without "new"');
        ...

সম্ভবত আপনি সমস্ত নতুন সদস্যদের মধ্যে পাস করতে চান এবং makeSubclassএগুলি প্রোটোটাইপে যুক্ত করতে চান, Class.prototype...যাতে আপনাকে যথেষ্ট পরিমাণে লিখতে হয় । অনেকগুলি ক্লাস সিস্টেম এটি করে, যেমন:

Circle= Shape.makeSubclass({
    _init: function(x, y, z) {
        Shape.prototype._init.call(this, x, y);
        this.r= r;
    },
    ...
});

এমন কোনও সম্ভাব্য বৈশিষ্ট্য রয়েছে যা আপনি কোনও অবজেক্ট সিস্টেমে কাঙ্ক্ষিত বিবেচনা করতে পারেন এবং কেউই কোনও নির্দিষ্ট সূত্রে সত্যই সম্মত হয় না।


অবসান পথ , তারপর। এটি জাভাস্ক্রিপ্টের প্রোটোটাইপ-ভিত্তিক উত্তরাধিকারের সমস্যাগুলি এড়িয়ে চলে, উত্তরাধিকার একেবারেই ব্যবহার না করে। পরিবর্তে:

function Shape(x, y) {
    var that= this;

    this.x= x;
    this.y= y;

    this.toString= function() {
        return 'Shape at '+that.x+', '+that.y;
    };
}

function Circle(x, y, r) {
    var that= this;

    Shape.call(this, x, y);
    this.r= r;

    var _baseToString= this.toString;
    this.toString= function() {
        return 'Circular '+_baseToString(that)+' with radius '+that.r;
    };
};

var mycircle= new Circle();

এখন প্রতিটি একক উদাহরণের Shapeনিজস্ব কপি থাকবে toStringপদ্ধতিটির (এবং কোনও অন্যান্য পদ্ধতি বা আমরা যুক্ত অন্যান্য শ্রেণীর সদস্যদের)।

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

[এছাড়াও এখানে কোনও উত্তরাধিকার instanceofনা থাকায় অপারেটর কাজ করবে না; আপনার যদি প্রয়োজন হয় তবে আপনাকে ক্লাস-স্নিফিংয়ের জন্য নিজস্ব ব্যবস্থা সরবরাহ করতে হবে। যদিও আপনি পারে প্রোটোটাইপ উত্তরাধিকার হিসেবে একই ভাবে প্রোটোটাইপ বস্তু বেহালা, এটি একটি বিট চতুর এবং সত্যিই মূল্য এটা ঠিক করতে না instanceofকাজ।]

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

var ts= mycircle.toString;
alert(ts());

তবে thisপদ্ধতির অভ্যন্তরে যেমন প্রত্যাশা করা হয়েছে তেমন বৃত্ত উদাহরণ হবে না (এটি আসলে বিশ্বব্যাপী windowবস্তু হয়ে উঠবে , যার ফলে ব্যাপক ডিবাগিংয়ের জন্য হ'ল সমস্যা সৃষ্টি হবে)। বাস্তবে এটি বিশেষভাবে যখন একটি পদ্ধতি গ্রহণ করা হয় এবং একটি নির্ধারিত ঘটবে setTimeout, onclickবা EventListenerসাধারণভাবে।

প্রোটোটাইপ উপায়ে, আপনাকে এই জাতীয় প্রতিটি কার্যক্রমে একটি ক্লোজার অন্তর্ভুক্ত করতে হবে:

setTimeout(function() {
    mycircle.move(1, 1);
}, 1000);

অথবা, ভবিষ্যতে (বা এখন আপনি যদি ফাংশন.প্রোটোটাইপ হ্যাক করেন) আপনি এটি দিয়েও করতে পারেন function.bind():

setTimeout(mycircle.move.bind(mycircle, 1, 1), 1000);

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

ক্লোজার পদ্ধতিতেও প্রচুর বৈকল্পিক রয়েছে। আপনি thisসম্পূর্ণরূপে বাদ দিতে পছন্দ করতে পারেন , একটি নতুন তৈরি thatকরে newঅপারেটর ব্যবহারের পরিবর্তে এটি ফিরিয়ে দিতে :

function Shape(x, y) {
    var that= {};

    that.x= x;
    that.y= y;

    that.toString= function() {
        return 'Shape at '+that.x+', '+that.y;
    };

    return that;
}

function Circle(x, y, r) {
    var that= Shape(x, y);

    that.r= r;

    var _baseToString= that.toString;
    that.toString= function() {
        return 'Circular '+_baseToString(that)+' with radius '+r;
    };

    return that;
};

var mycircle= Circle(); // you can include `new` if you want but it won't do anything

কোন উপায় "যথাযথ"? উভয়। কোনটি "সেরা"? এটি আপনার পরিস্থিতির উপর নির্ভর করে। এফডব্লিউআইডাব্লু যখন আমি দৃ strongly়ভাবে ওও স্টাফ করছি এবং রিয়েল থ্রোওয়ে পৃষ্ঠের প্রভাবগুলির জন্য বন্ধ করে দিচ্ছি তখন সত্যিকারের জাভাস্ক্রিপ্ট উত্তরাধিকারের জন্য প্রোটোটাইপিংয়ের দিকে ঝুঁকছি।

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

[কেন জাভাস্ক্রিপ্টটি আমার প্রিয় প্রোগ্রামিং ভাষা নয়?] এর অংশ হয়েছে]


13
"শ্রেণি" ডিএফ থেকে অবজেক্ট ইনস্ট্যান্টেশন করার জন্য খুব সুন্দর ধীরে ধীরে ধাপ। এবং বাইপাসিং এ চমৎকার টাচ new
ক্রিসেন্ট তাজা

8
দেখে মনে হচ্ছে জাভাস্ক্রিপ্টটি আপনার পছন্দের ভাষা নয় কারণ আপনি এটি ব্যবহার করতে চান যেন এটির ক্লাস রয়েছে।
জোনাথন ফেইনবার্গ

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

4
বব আমি মনে করি এটি একটি দুর্দান্ত উত্তর while আমি এই দুটি ধরণের সাথে কিছুক্ষণ ঝাঁপিয়ে পড়েছি এবং আমি মনে করি আপনি রেজিগের চেয়ে কিছুটা সংক্ষিপ্তভাবে কোড করেছেন এবং ক্রকফোর্ডের চেয়ে আরও অন্তর্দৃষ্টি দিয়ে ব্যাখ্যা করেছেন। এর চেয়ে বড় কোন প্রশংসা আমি ভাবতে পারি না ....
জেমস ওয়েস্টগেট

4
আমার কাছে সর্বদা মনে হয় যে জাভাস্ক্রিপ্টের মতো প্রোটোটাইপিক ভাষায় ক্লাসিকাল উত্তরাধিকারের দৃষ্টান্তগুলি গ্রাফিং করা একটি বর্গক্ষেত্রের খোসা এবং একটি গোল গর্ত। এই সময়টি কি সত্যই প্রয়োজন হয় বা ভাষাটি কেবল ভাষাটির জন্য কেবল ভাষাটি ব্যবহার করার পরিবর্তে ভাষাটিকে তারা যেভাবে চায় তা হম-মুষ্টির উপায়?
slp

90

আমি এই নিদর্শনটি প্রায়শই ঘন ঘন ব্যবহার করি - আমি খুঁজে পেয়েছি যে এটি যখন প্রয়োজন হয় তখন এটি আমাকে একটি বিশাল পরিমাণে নমনীয়তা দেয়। ব্যবহারের ক্ষেত্রে এটি জাভা-স্টাইলের ক্লাসগুলির মতোই।

var Foo = function()
{

    var privateStaticMethod = function() {};
    var privateStaticVariable = "foo";

    var constructor = function Foo(foo, bar)
    {
        var privateMethod = function() {};
        this.publicMethod = function() {};
    };

    constructor.publicStaticMethod = function() {};

    return constructor;
}();

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

মূলত, এই পদ্ধতির আরও শক্তিশালী শ্রেণি তৈরি করতে স্ট্যান্ডার্ড জাভাস্ক্রিপ্ট অবজেক্টের সাথে ক্রকফোর্ডিয়ান পদ্ধতির সংমিশ্রণ ঘটে।

আপনি অন্য কোনও জাভাস্ক্রিপ্ট অবজেক্টের মতোই এটি ব্যবহার করতে পারেন:

Foo.publicStaticMethod(); //calling a static method
var test = new Foo();     //instantiation
test.publicMethod();      //calling a method

4
এটি আকর্ষণীয় দেখায়, কারণ এটি আমার "হোম-টার্ফ" এর কাছাকাছি যা C #। আমি আরও মনে করি যে প্রাইভেটস্ট্যাটিক ভেরিয়েবলটি আসলেই ব্যক্তিগত কেন তা বুঝতে শুরু করেছি (এটি কোনও ফাংশনের ক্ষেত্রের মধ্যে সংজ্ঞায়িত করা হয়েছে এবং যতক্ষণ পর্যন্ত এর উল্লেখ রয়েছে ততক্ষণ জীবিত থাকবে?)
মাইকেল স্টাম

যেহেতু এটি ব্যবহার করছে thisনা এটি এখনও ততক্ষণে ইনস্ট্যান্ট করা দরকার new?
জর্ডান পারমার

আসলে, this নেই মধ্যে ব্যবহার করতে পারেন constructorফাংশন, যা হয়ে ওঠে Fooউদাহরণ।
ShZ

4
এখানে সমস্যাটি হ'ল প্রতিটি বস্তু সমস্ত ব্যক্তিগত এবং পাবলিক কার্যাবলীর নিজস্ব অনুলিপি পায়।
ভার্চুয়ালনোবি

2
@virtualnobi এই প্যাটার্ন protytpe পদ্ধতি লেখার করতে প্রতিরোধ করা না: constructor.prototype.myMethod = function () { ... }
নিকোলাস লে থিয়েরি ডি'নেখুইন

25

ডগলাস ক্রকফোর্ড গুড পার্টস-এ সেই বিষয়টি নিয়ে ব্যাপক আলোচনা করেছেন । তিনি নতুন অবজেক্ট তৈরি করতে নতুন অপারেটর এড়ানোর পরামর্শ দেন । পরিবর্তে তিনি কাস্টমাইজড কনস্ট্রাক্টর তৈরির প্রস্তাব দেন। এই ক্ষেত্রে:

var mammal = function (spec) {     
   var that = {}; 
   that.get_name = function (  ) { 
      return spec.name; 
   }; 
   that.says = function (  ) { 
      return spec.saying || ''; 
   }; 
   return that; 
}; 

var myMammal = mammal({name: 'Herb'});

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

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

var person = new Person();
alert("name: " + person.name);**

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


5
এটি কি আমি বা আমার কাছে মনে হয় ক্রোকফোর্ড নতুন অপারেটরকে মারধর করার সাথে একেবারেই কোনও অর্থবোধ করে না?
মধ্যস্বত্বভোগী ওমরালিভিভ

3
@ মিডার: শুধু আপনি নন কমপক্ষে, আমি মনে করি নতুন অপারেটরটিতে কোনও ভুল নেই। এবং যাইহোক একটি অন্তর্নিহিত newআছে var that = {};
টিম ডাউন

17
ক্রকফোর্ড হ'ল এক কৃপণ বৃদ্ধ এবং আমি তার সাথে অনেকটাতেই একমত নই, তবে তিনি কমপক্ষে জাভাস্ক্রিপ্টের সমালোচনা করাতে উত্সাহ দিচ্ছেন এবং তার কী বলতে হবে তা শোনার মতো।
ববিনস

2
@ ববিন্স: সম্মত ক্লোজারগুলিতে তাঁর লেখা আমার প্রায় 5 বছর আগে প্রচুর স্টাফের দিকে চোখ খোলে এবং তিনি একটি চিন্তাশীল পদ্ধতির উত্সাহিত করেন।
টিম ডাউন

20
আমি ক্রকফোর্ডের সাথে একমত নতুন অপারেটরের সমস্যাটি হ'ল জাভাস্ক্রিপ্ট "এই" এর প্রসঙ্গটি অন্যথায় কোনও ফাংশন কল করার চেয়ে খুব আলাদা করবে। যথাযথ কেস কনভেনশন সত্ত্বেও, এমন সমস্যা রয়েছে যা বৃহত্তর কোড বেসগুলিতে উত্থাপিত হয় কারণ বিকাশকারীরা নতুন ব্যবহার করতে ভুলে যায়, মূলধনকে ভুলে যায় ইত্যাদি pra বাস্তববাদী হওয়ার জন্য, নতুন কীওয়ার্ড ব্যতীত আপনার যা কিছু করা দরকার তা করতে পারেন - সুতরাং কেন এটি ব্যবহার করুন এবং কোডে ব্যর্থতার আরও পয়েন্টগুলি প্রবর্তন করবেন? জেএস একটি প্রোটোটাইপাল, শ্রেণীভিত্তিক নয়, ভাষা। তাহলে আমরা কেন এটি স্থিরভাবে টাইপিত ভাষার মতো কাজ করতে চাই? আমি অবশ্যই না।
জোশুয়া রামিরেজ

13

বোবিন্সের উত্তর বন্ধ রাখার জন্য

এস In এ আপনি এখন একটি তৈরি করতে পারেন class

সুতরাং এখন আপনি এটি করতে পারেন:

class Shape {
    constructor(x, y) {
        this.x = x;
        this.y = y;
    }

    toString() {
        return `Shape at ${this.x}, ${this.y}`;
    }
}

সুতরাং আপনি করতে পারেন এমন চেনাশোনাতে প্রসারিত করুন (অন্য উত্তরের মতো):

class Circle extends Shape {
    constructor(x, y, r) {
        super(x, y);
        this.r = r;
    }

    toString() {
        let shapeString = super.toString();
        return `Circular ${shapeString} with radius ${this.r}`;
    }
}

Es6 এ কিছুটা ক্লিনার শেষ হয় এবং পড়ার জন্য আরও সহজ।


কর্মক্ষেত্রে এটির একটি উত্তম উদাহরণ এখানে:


6

কাঠামোগত ব্যবহার করে আপনি এটিও এভাবে করতে পারেন:

function createCounter () {
    var count = 0;

    return {
        increaseBy: function(nb) {
            count += nb;
        },
        reset: function {
            count = 0;
        }
    }
}

তারপরে:

var counter1 = createCounter();
counter1.increaseBy(4);

6
আমি সেভাবে পছন্দ করি না কারণ হোয়াইটস্পেস গুরুত্বপূর্ণ। ফিরার পরে কোঁকড়া অবশ্যই ক্রস ব্রাউজারের সামঞ্জস্যের জন্য একই লাইনে থাকতে হবে।
geowa4

5

অন্য উপায় হ'ল http://jsfiddle.net/nnUY4/ (আমি জানি না যে এই ধরণের হ্যান্ডলিং অবজেক্ট তৈরি করা এবং প্রকাশের ফাংশনগুলি কোনও নির্দিষ্ট নিদর্শন অনুসরণ করে কিনা)

// Build-Reveal

var person={
create:function(_name){ // 'constructor'
                        //  prevents direct instantiation 
                        //  but no inheritance
    return (function() {

        var name=_name||"defaultname";  // private variable

        // [some private functions]

        function getName(){
            return name;
        }

        function setName(_name){
            name=_name;
        }

        return {    // revealed functions
            getName:getName,    
            setName:setName
        }
    })();
   }
  }

  // … no (instantiated) person so far …

  var p=person.create(); // name will be set to 'defaultname'
  p.setName("adam");        // and overwritten
  var p2=person.create("eva"); // or provide 'constructor parameters'
  alert(p.getName()+":"+p2.getName()); // alerts "adam:eva"

4

কনস্ট্রাক্টর আহ্বানের সময় যখন কেউ "এটি" বন্ধ করার কৌশল ব্যবহার করে, তখন এটি কোনও ফাংশন লিখতে হয় যা কোনও কোনও বস্তুর দ্বারা কলব্যাক হিসাবে ব্যবহার করা যেতে পারে যা কোনও বস্তুর উপর কোনও পদ্ধতিতে অনুরোধ করতে চায় না। এটি "সুযোগটি সঠিক করা" সম্পর্কিত নয়।

এখানে একটি ভ্যানিলা জাভাস্ক্রিপ্ট অবজেক্টটি রয়েছে:

function MyThing(aParam) {
    var myPrivateVariable = "squizzitch";

    this.someProperty = aParam;
    this.useMeAsACallback = function() {
        console.log("Look, I have access to " + myPrivateVariable + "!");
    }
}

// Every MyThing will get this method for free:
MyThing.prototype.someMethod = function() {
    console.log(this.someProperty);
};

ডাবলাস ক্রকফোর্ড জাভাস্ক্রিপ্ট সম্পর্কে যা বলেছে তা আপনি পড়ার ফলে অনেকটা পেতে পারেন । জন রেসিগও উজ্জ্বল। শুভকামনা!


1
আহ, চারপাশে বন্ধ thisকরার সাথে "সুযোগটি সঠিক করে তোলা" এর সাথে সমস্ত কিছুই রয়েছে।
রোয়াতিন মার্থ

3
জোনাথন ঠিক বলেছেন। জেএস ফাংশনের সুযোগটি আপনি যা ডিজাইন করেছেন তা হ'ল। স্ব = এই কৌশলটি একটি নির্দিষ্ট উদাহরণের সাথে বেঁধে ফেলার এক উপায় তাই অন্য প্রসঙ্গে ডাকা হলেও এটি পরিবর্তন হয় না। তবে কখনও কখনও এটি আপনি যা চান তা চাই। প্রসঙ্গে নির্ভর করে।
মার্কো

আমি মনে করি আপনি আসলে একই কথা বলছেন। self=thisযদিও জোর thisকরে ধরে রাখতে বাধ্য করে না , সহজেই একটি বন্ধের মাধ্যমে "সঠিক" স্কোপিংয়ের অনুমতি দেয়।
ক্রিসেন্ট তাজা

2
আপনি যে কারণে = এটি নির্ধারিত ফাংশনটিতে উপস্থিত থাকার কারণে নেস্টেড ফাংশনগুলিকে এর সুযোগগুলিতে অ্যাক্সেস দেওয়া। নেস্টেড ফাংশনগুলি কনস্ট্রাক্টর ফাংশনের ভিতরে থাকলে, তাদের "এই" সুযোগটি বিশ্বব্যাপী স্কোপে ফিরে আসে to
জোশুয়া রামিরেজ

4

Closureবহুমুখী। বোবিনস প্রোটোটাইপ বনাম ক্লোজ করার পদ্ধতির ভালভাবে সংক্ষিপ্তসার রেখেছে যখন অবজেক্ট তৈরি করার সময়। তবে আপনি OOPকার্যনির্বাহী প্রোগ্রামিং পদ্ধতিতে ক্লোজার ব্যবহারের কয়েকটি দিক অনুকরণ করতে পারেন । মনে রাখবেন ফাংশনগুলি জাভাস্ক্রিপ্টে অবজেক্টস ; সুতরাং অন্যভাবে অবজেক্ট হিসাবে ফাংশন ব্যবহার করুন।

বন্ধের উদাহরণ এখানে:

function outer(outerArg) {
    return inner(innerArg) {
        return innerArg + outerArg; //the scope chain is composed of innerArg and outerArg from the outer context 
    }
}

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

কিভাবে?

মনে করুন আপনি কিছু আইটেমের ভ্যাট গণনা করতে চান। কোনও আবেদনের সময়কালে ভ্যাট স্থিতিশীল থাকতে পারে। ওওপিতে এটি করার একটি উপায় (সিউডো কোড):

public class Calculator {
    public property VAT { get; private set; }
    public Calculator(int vat) {
        this.VAT = vat;
    }
    public int Calculate(int price) {
        return price * this.VAT;
    }
}

মূলত আপনি আপনার কন্সট্রাক্টরে একটি ভ্যাট মান পাস করেন এবং আপনার গণনা পদ্ধতিটি এটি বন্ধের মাধ্যমে পরিচালনা করতে পারে । এখন কোনও ক্লাস / কনস্ট্রাক্টর ব্যবহার না করে আপনার ভ্যাটকে একটি ফাংশনে আর্গুমেন্ট হিসাবে পাস করুন। কারণ আপনার আগ্রহী একমাত্র জিনিস হ'ল গণনা নিজেই, একটি নতুন ফাংশন দেয় যা গণনা পদ্ধতি:

function calculator(vat) {
    return function(item) {
        return item * vat;
    }
}
var calculate = calculator(1.10);
var jsBook = 100; //100$
calculate(jsBook); //110

আপনার প্রকল্পে শীর্ষ-স্তরের মানগুলি সনাক্ত করুন যা গণনার জন্য ভ্যাট কী is থাম্বের নিয়ম হিসাবে আপনি যখনই একই আর্গুমেন্টটি চালিয়ে যান এবং বন্ধ করেন তখন বন্ধ করে এটির উন্নতি করার উপায় রয়েছে। Traditionalতিহ্যগত বস্তু তৈরি করার দরকার নেই।

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Closures


3

একটি অবজেক্ট তৈরি করা হচ্ছে

জাভাস্ক্রিপ্টে কোনও অবজেক্ট তৈরির সহজ উপায় হ'ল নিম্নলিখিত বাক্য গঠনটি ব্যবহার করা:

var test = {
  a : 5,
  b : 10,
  f : function(c) {
    return this.a + this.b + c;
  }
}

console.log(test);
console.log(test.f(3));

এটি কাঠামোগত উপায়ে ডেটা সংরক্ষণের জন্য দুর্দান্ত কাজ করে।

আরও জটিল ব্যবহারের ক্ষেত্রে, তবে কার্যকারিতাগুলির উদাহরণ তৈরি করা প্রায়শই ভাল:

function Test(a, b) {
  this.a = a;
  this.b = b;
  this.f = function(c) {
return this.a + this.b + c;
  };
}

var test = new Test(5, 10);
console.log(test);
console.log(test.f(3));

এটি আপনাকে একাধিক অবজেক্ট তৈরি করতে দেয় যা একই "ব্লুপ্রিন্ট" ভাগ করে, যেমন আপনি যেমন ক্লাসগুলি ব্যবহার করেন তার অনুরূপ। জাভা।

এটি এখনও আরও দক্ষতার সাথে করা যেতে পারে, তবে প্রোটোটাইপ ব্যবহার করে।

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

আমাদের ক্ষেত্রে, পদ্ধতিটি fপ্রোটোটাইপে স্থানান্তরিত করার জন্য এটি বোধগম্য হয় :

function Test(a, b) {
  this.a = a;
  this.b = b;
}

Test.prototype.f = function(c) {
  return this.a + this.b + c;
};

var test = new Test(5, 10);
console.log(test);
console.log(test.f(3));

উত্তরাধিকার

জাভাস্ক্রিপ্টে উত্তরাধিকার করার একটি সহজ তবে কার্যকরী উপায় হ'ল নিম্নলিখিত দু'লাইনারটি ব্যবহার করা:

B.prototype = Object.create(A.prototype);
B.prototype.constructor = B;

এটি করার অনুরূপ:

B.prototype = new A();

উভয়ের মধ্যে প্রধান পার্থক্য হ'ল এর Aব্যবহারকারীর ব্যবহারকারীর চালনা হয় না Object.createযা শ্রেণিভিত্তিক উত্তরাধিকারের সাথে আরও স্বজ্ঞাত এবং আরও অনুরূপ।

আপনি সর্বদা theচ্ছিকভাবে নির্মাণকারীর সাথে এটি যুক্ত করে Aএকটি নতুন উদাহরণ তৈরি করার সময় নির্মাণকারীর চালনা চয়ন করতে পারেন :BB

function B(arg1, arg2) {
    A(arg1, arg2); // This is optional
}

তোমাদের সবাইকে আর্গুমেন্ট পাস করতে চান, Bকরতে A, এছাড়াও আপনি ব্যবহার করতে পারেন Function.prototype.apply():

function B() {
    A.apply(this, arguments); // This is optional
}

আপনি যদি কনস্ট্রাক্টর চেইনের সাথে অন্য কোনও বস্তুর মিশ্রণ করতে চান তবে আপনি এর সাথে Bএকত্রিত করতে পারেন :Object.createObject.assign

B.prototype = Object.assign(Object.create(A.prototype), mixin.prototype);
B.prototype.constructor = B;

ডেমো

function A(name) {
  this.name = name;
}

A.prototype = Object.create(Object.prototype);
A.prototype.constructor = A;

function B() {
  A.apply(this, arguments);
  this.street = "Downing Street 10";
}

B.prototype = Object.create(A.prototype);
B.prototype.constructor = B;

function mixin() {

}

mixin.prototype = Object.create(Object.prototype);
mixin.prototype.constructor = mixin;

mixin.prototype.getProperties = function() {
  return {
    name: this.name,
    address: this.street,
    year: this.year
  };
};

function C() {
  B.apply(this, arguments);
  this.year = "2018"
}

C.prototype = Object.assign(Object.create(B.prototype), mixin.prototype);
C.prototype.constructor = C;

var instance = new C("Frank");
console.log(instance);
console.log(instance.getProperties());


বিঃদ্রঃ

Object.createআই 9 + সহ প্রতিটি আধুনিক ব্রাউজারে নিরাপদে ব্যবহার করা যেতে পারে। Object.assignআইই বা কোনও মোবাইল ব্রাউজারের কোনও সংস্করণে কাজ করে না। এটি পলিফিল Object.create এবং / অথবা Object.assignআপনি তাদের ব্যবহার করতে এবং ব্রাউজারগুলিকে সমর্থন করতে চান যা তাদের বাস্তবায়ন করে না বাঞ্ছনীয় ।

আপনার জন্য একটি polyfill জানতে পারেন Object.create এখানে এবং জন্য এক Object.assign এখানে


0
var Person = function (lastname, age, job){
this.name = name;
this.age = age;
this.job = job;
this.changeName = function(name){
this.lastname = name;
}
}
var myWorker = new Person('Adeola', 23, 'Web Developer');
myWorker.changeName('Timmy');

console.log("New Worker" + myWorker.lastname);

4
ইতিমধ্যে দেওয়া অসংখ্য বিস্তৃত উত্তরগুলিতে এটি কী যুক্ত করে?
blm

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

0

২০০৯ থেকে গৃহীত উত্তর ছাড়াও modern আপনি যদি আধুনিক ব্রাউজারগুলিকে লক্ষ্য করতে পারেন তবে কেউ অবজেক্ট.ডেফাইনপ্রোপার্টি ব্যবহার করতে পারেন ।

অবজেক্ট.ডিফাইনপ্রোপার্টি () পদ্ধতিটি সরাসরি কোনও বস্তুর উপরে একটি নতুন সম্পত্তি সংজ্ঞায়িত করে বা কোনও বস্তুর উপর বিদ্যমান সম্পত্তিটি সংশোধন করে এবং বস্তুকে প্রত্যাবর্তন করে। সূত্র: মজিলা

var Foo = (function () {
    function Foo() {
        this._bar = false;
    }
    Object.defineProperty(Foo.prototype, "bar", {
        get: function () {
            return this._bar;
        },
        set: function (theBar) {
            this._bar = theBar;
        },
        enumerable: true,
        configurable: true
    });
    Foo.prototype.toTest = function () {
        alert("my value is " + this.bar);
    };
    return Foo;
}());

// test instance
var test = new Foo();
test.bar = true;
test.toTest();

একটি ডেস্কটপ এবং মোবাইল উপযুক্ততা তালিকা দেখতে, মজিলার ব্রাউজারের সামঞ্জস্যের তালিকাটি দেখুন । হ্যাঁ, IE9 + সাফারি মোবাইলের পাশাপাশি এটি সমর্থন করে।


0

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

    function Person(obj) {
    'use strict';
    if (typeof obj === "undefined") {
        this.name = "Bob";
        this.age = 32;
        this.company = "Facebook";
    } else {
        this.name = obj.name;
        this.age = obj.age;
        this.company = obj.company;
    }

}

Person.prototype.print = function () {
    'use strict';
    console.log("Name: " + this.name + " Age : " + this.age + " Company : " + this.company);
};

var p1 = new Person({name: "Alex", age: 23, company: "Google"});
p1.print();

0
একটি নিদর্শন যা আমাকে ভালভাবে পরিবেশন করে
var Klass = function Klass() {
    var thus = this;
    var somePublicVariable = x
      , somePublicVariable2 = x
      ;
    var somePrivateVariable = x
      , somePrivateVariable2 = x
      ;

    var privateMethod = (function p() {...}).bind(this);

    function publicMethod() {...}

    // export precepts
    this.var1 = somePublicVariable;
    this.method = publicMethod;

    return this;
};

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

কোনটি ঘোষণাপত্র রিট হবে তা আমি এখানেই স্থির করব:

  • প্রসঙ্গ অবজেক্টে সরাসরি কোনও পদ্ধতি কখনই ঘোষণা করবেন না ( this)
  • যাক varঘোষণা উপর প্রাধান্য functionঘোষণা
  • আদিমগণ বস্তুর ( {}এবং []) চেয়ে বেশি অগ্রাধিকার গ্রহণ করুন
  • যাক publicঘোষণা উপর প্রাধান্য privateঘোষণা
  • পছন্দ Function.prototype.bindউপর thus, self, vm,etc
  • অন্য ক্লাসের মধ্যে ক্লাস ঘোষণা করা থেকে বিরত থাকুন, যদি না:
    • এটি দু'টি অবিচ্ছেদ্য যে স্পষ্ট হওয়া উচিত
    • ইনার ক্লাস কমান্ড প্যাটার্ন প্রয়োগ করে
    • ইনার ক্লাসটি সিঙ্গলটন প্যাটার্ন প্রয়োগ করে
    • অভ্যন্তর শ্রেণি স্টেট প্যাটার্ন প্রয়োগ করে
    • অভ্যন্তরীণ শ্রেণি আরেকটি ডিজাইন প্যাটার্ন প্রয়োগ করে যা এটির সতর্ক করে
  • ক্লোজার স্পেসের লেক্সিকাল স্কোপেরthis মধ্যে থেকে সর্বদা ফিরে আসুন

এই সহায়তা কেন এখানে:

কনস্ট্রাক্টর হাইজ্যাকিং
var Super = function Super() {
    ...
    this.inherited = true;
    ...
};
var Klass = function Klass() {
    ...
    // export precepts
    Super.apply(this);  // extends this with property `inherited`
    ...
};
মডেল ডিজাইন
var Model = function Model(options) {
    var options = options || {};

    this.id = options.id || this.id || -1;
    this.string = options.string || this.string || "";
    // ...

    return this;
};
var model = new Model({...});
var updated = Model.call(model, { string: 'modified' });
(model === updated === true);  // > true
নকশা নিদর্শন
var Singleton = new (function Singleton() {
    var INSTANCE = null;

    return function Klass() {
        ...
        // export precepts
        ...

        if (!INSTANCE) INSTANCE = this;
        return INSTANCE;
    };
})();
var a = new Singleton();
var b = new Singleton();
(a === b === true);  // > true

আপনি দেখতে পাচ্ছেন, thusযেহেতু আমি ( বা ) বেশি পছন্দFunction.prototype.bind.call.applythus করি সেহেতু আমার আসলেই কোনও প্রয়োজন নেই । আমাদের Singletonক্লাসে, আমরা এর নামও রাখি না thusকারণ INSTANCEআরও তথ্য জানায়। কারণ Model, আমরা ফিরে thisআসি যাতে আমরা এর মধ্যে যে .callউদাহরণটি দিয়েছি তা ফেরত দেওয়ার জন্য আমরা কনস্ট্রাক্টরকে অনুরোধ করতে পারি। অপ্রত্যাশিতভাবে, আমরা এটিকে পরিবর্তনশীল হিসাবে নির্ধারিত করেছি updated, যদিও এটি অন্যান্য পরিস্থিতিতে কার্যকর।

পাশাপাশি, আমি new{বন্ধনীগুলির উপরে কীওয়ার্ড ব্যবহার করে অবজেক্ট-লিটারালগুলি তৈরি করতে পছন্দ করি :

পছন্দের
var klass = new (function Klass(Base) {
    ...
    // export precepts
    Base.apply(this);  //
    this.override = x;
    ...
})(Super);
পছন্দসই নয়
var klass = Super.apply({
    override: x
});

আপনি দেখতে পাচ্ছেন যে, আধুনিক এটির সুপারক্লাসের "ওভাররাইড" সম্পত্তিটি ওভাররাইড করার ক্ষমতা নেই।

আমি যদি ক্লাসের prototypeঅবজেক্টে পদ্ধতিগুলি যুক্ত করি তবে আমি কোনও শব্দটিকে আক্ষরিক পছন্দ করি - newকীওয়ার্ডটি সহ বা ব্যবহার না করে :

পছন্দের
Klass.prototype = new Super();
// OR
Klass.prototype = new (function Base() {
    ...
    // export precepts
    Base.apply(this);
    ...
})(Super);
// OR
Klass.prototype = Super.apply({...});
// OR
Klass.prototype = {
    method: function m() {...}
};
পছন্দসই নয়
Klass.prototype.method = function m() {...};

0

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

var test = {

  useTitle : "Here we use 'a Title' to declare an Object",
  'useString': "Here we use 'a String' to declare an Object",
  
  onTitle : function() {
    return this.useTitle;
  },
  
  onString : function(type) {
    return this[type];
  }
  
}

console.log(test.onTitle());
console.log(test.onString('useString'));


-1

মূলত জেএসে ক্লাসের কোনও ধারণা নেই তাই আমরা ক্লাস কনস্ট্রাক্টর হিসাবে ফাংশনটি ব্যবহার করি যা বিদ্যমান ডিজাইনের ধরণগুলির সাথে প্রাসঙ্গিক।

//Constructor Pattern
function Person(name, age, job){
 this.name = name;
 this.age = age;
 this.job = job;
 this.doSomething = function(){
    alert('I am Happy');
}
}

এখনও অবধি জেএসের কোনও ক্লু নেই যে আপনি কোনও অবজেক্ট তৈরি করতে চান তাই এখানে নতুন কীওয়ার্ডটি আসবে।

var person1 = new Person('Arv', 30, 'Software');
person1.name //Arv

তথ্যসূত্র: ওয়েব বিকাশকারীদের জন্য পেশাদার জেএস - নিক জেড


ডাউনভোট গ্রহণ করেছেন: একটি বৈধ কারণ সহ আরও তথ্যবহুল হত এবং উন্নতির সুযোগটি দিত।
এয়ারউইন্ড 711

সেখানে হয় একটি ধারণা classজাতীয় এ, যে আপনি আপনার শিরোনাম উল্লেখ ব্যবহারfunction শব্দ। এটা না একটি নকশা প্যাটার্ন কিন্তু ভাষার একটি ইচ্ছাকৃত বৈশিষ্ট্য। আমি আপনাকে এটি হ্রাস করি নি, তবে দেখে মনে হচ্ছে যে কেউ কেউ ক্ষীণতা এবং প্রশ্নের সাথে প্রায় অপ্রাসঙ্গিকতার কারণে করেছে। আশা করি এই প্রতিক্রিয়াটি সাহায্য করবে।
কোডি
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.