জাভাস্ক্রিপ্টের প্রারম্ভিক সংস্করণগুলিতে নামযুক্ত ফাংশন এক্সপ্রেশনগুলিকে অনুমতি দেয়নি এবং এর কারণে আমরা একটি পুনরাবৃত্ত ফাংশন প্রকাশ করতে পারি না:
// This snippet will work:
function factorial(n) {
return (!(n>1))? 1 : factorial(n-1)*n;
}
[1,2,3,4,5].map(factorial);
// But this snippet will not:
[1,2,3,4,5].map(function(n) {
return (!(n>1))? 1 : /* what goes here? */ (n-1)*n;
});
এটি পেতে, arguments.callee
যোগ করা হয়েছিল যাতে আমরা করতে পারি:
[1,2,3,4,5].map(function(n) {
return (!(n>1))? 1 : arguments.callee(n-1)*n;
});
তবে এটি আসলে খুব খারাপ সমাধান ছিল কারণ এটি (অন্যান্য যুক্তি, কলি এবং কলার সমস্যাগুলির সাথে একত্রে) ইনলাইনিং এবং লেজ পুনরাবৃত্তি সাধারণ ক্ষেত্রে অসম্ভব করে তোলে (আপনি এটি ট্রেসিং ইত্যাদির মাধ্যমে নির্বাচিত ক্ষেত্রে এটি অর্জন করতে পারেন তবে সেরা কোডও চেকগুলির কারণে সাব অনুকূলতম যা অন্যথায় প্রয়োজনীয় হবে না)। অন্যান্য বড় সমস্যাটি হ'ল পুনরাবৃত্তি কলটি একটি পৃথক this
মান পাবে, উদাহরণস্বরূপ:
var global = this;
var sillyFunction = function (recursed) {
if (!recursed)
return arguments.callee(true);
if (this !== global)
alert("This is: " + this);
else
alert("This is the global");
}
sillyFunction();
যাইহোক, একমাস্ক্রিপ্ট 3 নামযুক্ত ফাংশন এক্সপ্রেশনগুলির অনুমতি দিয়ে এই সমস্যাগুলি সমাধান করেছে, যেমন:
[1,2,3,4,5].map(function factorial(n) {
return (!(n>1))? 1 : factorial(n-1)*n;
});
এর অসংখ্য সুবিধা রয়েছে:
ফাংশনটি আপনার কোডের অভ্যন্তর থেকে অন্য যেকোন মত কল করা যেতে পারে।
এটি নামস্থান দূষিত করে না।
মান this
পরিবর্তন হয় না।
এটি আরও পারফরম্যান্ট ( আর্গুমেন্ট অবজেক্টে অ্যাক্সেস ব্যয়বহুল)।
ওহো,
কেবল উপলব্ধি হয়ে গেছে যে অন্য সমস্ত কিছুর পাশাপাশি প্রশ্নটি arguments.callee.caller
বা আরও সুনির্দিষ্টভাবে ছিল Function.caller
।
যেকোন সময় আপনি স্ট্যাকের যে কোনও ফাংশনের গভীরতম কলার খুঁজে পেতে পারেন এবং আমি উপরে যেমন বলেছি, কল স্ট্যাকের দিকে তাকানোর একটি একক বড় প্রভাব রয়েছে: এটি প্রচুর সংখ্যক অপটিমাইজেশনকে অসম্ভব বা আরও অনেক কঠিন করে তোলে।
যেমন। যদি আমরা গ্যারান্টি দিতে পারি না যে কোনও ফাংশন f
কোনও অজানা ফাংশন কল করবে না, তবে ইনলাইন করা সম্ভব নয় f
। মূলত এর অর্থ হ'ল যে কোনও কল সাইট যা তুচ্ছভাবে অন্তর্নিহিতভাবে অন্তর্ভুক্ত হতে পারে সেগুলি প্রচুর পরিমাণে রক্ষক সংগ্রহ করে, নিন:
function f(a, b, c, d, e) { return a ? b * c : d * e; }
যদি জেএস ইন্টারপ্রেটার গ্যারান্টি দিতে না পারে যে সমস্ত প্রদত্ত আর্গুমেন্ট কল করা হয়েছে এমন বিন্দুতে নম্বর, তবে এটি হয় ইনলাইনড কোডের আগে সমস্ত আর্গুমেন্টের জন্য চেক সন্নিবেশ করা প্রয়োজন, অথবা এটি ফাংশনটি ইনলাইন করতে পারে না।
এখন এই বিশেষ ক্ষেত্রে একজন স্মার্ট দোভাষীকে চেকগুলি আরও অনুকূল হতে পুনরায় সাজানো এবং এমন কোনও মান ব্যবহার করা যাচাই করে না যাচাই করে নেওয়া উচিত। তবে অনেক ক্ষেত্রে এটি ঠিক সম্ভব নয় এবং তাই লাইন করা অসম্ভব হয়ে পড়ে।