সতর্কতা: এটি একটি দীর্ঘ পোস্ট।
আসুন এটি সহজ রাখা যাক। আমি যখনই জাভাস্ক্রিপ্টে কোনও কনস্ট্রাক্টরকে কল করি তখন নতুন অপারেটরের উপসর্গ রাখা এড়াতে চাই। এটি কারণ আমি এটি ভুলে যাওয়ার প্রবণতা করি এবং আমার কোডগুলি খারাপভাবে স্ক্রু হয়।
এর চারপাশের সহজ উপায় হ'ল ...
function Make(x) {
if ( !(this instanceof arguments.callee) )
return new arguments.callee(x);
// do your stuff...
}
তবে, আমার পরিবর্তনশীল নংটি গ্রহণ করার জন্য এটি দরকার। এই মত যুক্তি, ...
m1 = Make();
m2 = Make(1,2,3);
m3 = Make('apple', 'banana');
প্রথম তাত্ক্ষণিক সমাধানটি এর মতো 'প্রয়োগ' পদ্ধতি বলে মনে হচ্ছে ...
function Make() {
if ( !(this instanceof arguments.callee) )
return new arguments.callee.apply(null, arguments);
// do your stuff
}
যদিও ভুল - নতুন বস্তু পাস করা হয়েছে apply
না আমাদের কন্সট্রাকটর করার পদ্ধতি এবং arguments.callee
।
এখন, আমি তিনটি সমাধান নিয়ে এসেছি। আমার সহজ প্রশ্নটি: কোনটি সবচেয়ে ভাল বলে মনে হচ্ছে। অথবা, আপনার যদি আরও ভাল পদ্ধতি থাকে তবে এটি বলুন।
প্রথম - eval()
গতিশীলভাবে জাভাস্ক্রিপ্ট কোড তৈরি করতে ব্যবহার করুন যা নির্মাণকারীকে কল করে calls
function Make(/* ... */) {
if ( !(this instanceof arguments.callee) ) {
// collect all the arguments
var arr = [];
for ( var i = 0; arguments[i]; i++ )
arr.push( 'arguments[' + i + ']' );
// create code
var code = 'new arguments.callee(' + arr.join(',') + ');';
// call it
return eval( code );
}
// do your stuff with variable arguments...
}
দ্বিতীয় - প্রতিটি বস্তুর __proto__
সম্পত্তি রয়েছে যা তার প্রোটোটাইপ অবজেক্টের 'গোপন' লিঙ্ক। ভাগ্যক্রমে এই সম্পত্তি লিখনযোগ্য।
function Make(/* ... */) {
var obj = {};
// do your stuff on 'obj' just like you'd do on 'this'
// use the variable arguments here
// now do the __proto__ magic
// by 'mutating' obj to make it a different object
obj.__proto__ = arguments.callee.prototype;
// must return obj
return obj;
}
তৃতীয় - এটি দ্বিতীয় সমাধানের অনুরূপ।
function Make(/* ... */) {
// we'll set '_construct' outside
var obj = new arguments.callee._construct();
// now do your stuff on 'obj' just like you'd do on 'this'
// use the variable arguments here
// you have to return obj
return obj;
}
// now first set the _construct property to an empty function
Make._construct = function() {};
// and then mutate the prototype of _construct
Make._construct.prototype = Make.prototype;
eval
সমাধান আনাড়ি বলে মনে হয় এবং "অশুভ বিভাজন" এর সমস্ত সমস্যার সাথে আসে।__proto__
সমাধানটি মানহীন এবং "গ্রেট ব্রাউজার অফ মিছরি" এটি সম্মান করে না।তৃতীয় সমাধান অত্যধিক জটিল বলে মনে হচ্ছে।
তবে উপরোক্ত তিনটি সমাধানের সাহায্যে আমরা এরকম কিছু করতে পারি, যা আমরা অন্যথায় পারি না ...
m1 = Make();
m2 = Make(1,2,3);
m3 = Make('apple', 'banana');
m1 instanceof Make; // true
m2 instanceof Make; // true
m3 instanceof Make; // true
Make.prototype.fire = function() {
// ...
};
m1.fire();
m2.fire();
m3.fire();
সুতরাং কার্যকরভাবে উপরের সমাধানগুলি আমাদের "সত্য" কনস্ট্রাক্টর দেয় যা ভেরিয়েবল নং গ্রহণ করে। তর্ক এবং প্রয়োজন নেই new
। আপনার এই কি গ্রহণ করা।
-- হালনাগাদ --
কেউ কেউ "শুধু একটি ত্রুটি নিক্ষেপ" বলেছেন। আমার প্রতিক্রিয়াটি হ'ল: আমরা ১০++ কনস্ট্রাক্টর সহ একটি ভারী অ্যাপ্লিকেশন করছি এবং আমি মনে করি যে যদি প্রতিটি নির্মাতা কনসোলটিতে ত্রুটি বার্তা না ছুঁড়ে দিয়ে "ভুল করে" ভুলটি পরিচালনা করতে পারে তবে এটি আরও বেশি মজাদার হতে চাই।
Make()
এটি না করে করেন new
কারণ মেক মূলধন হয় এবং সুতরাং এটি এটি
new
? কারণ যদি এটি পরে হয় তবে আপনি সম্ভবত ভুল সাইটে জিজ্ঞাসা করছেন। যদি এটি পূর্বের হয় তবে আপনি নতুন ব্যবহার করতে এবং ত্রুটিগুলি সনাক্ত করার জন্য এত তাড়াতাড়ি পরামর্শগুলি খারিজ করতে চান না ... যদি আপনার অ্যাপটি সত্যই "ভারী" হয় তবে আপনি সর্বশেষত চাইছেন এটি হ্রাস করার জন্য কিছু ওভারভারথ নির্মাণ পদ্ধতি mechanism new
, এটি যে সমস্ত ফ্ল্যাক পায় তা খুব দ্রুতগতির।