নামযুক্ত ফাংশন এক্সপ্রেশন কেন ব্যবহার করবেন?


94

জাভাস্ক্রিপ্টে ফাংশন এক্সপ্রেশন করার জন্য আমাদের দুটি ভিন্ন উপায় রয়েছে:

নামযুক্ত ফাংশন এক্সপ্রেশন (এনএফই) :

var boo = function boo () {
  alert(1);
};

বেনামে ফাংশন এক্সপ্রেশন :

var boo = function () {
  alert(1);
};

এবং তাদের উভয় সঙ্গে কল করা যেতে পারে boo();। কেন / কখন বেনাম ফাংশন ব্যবহার করা উচিত এবং কখন নামযুক্ত ফাংশন এক্সপ্রেশন ব্যবহার করা উচিত তা আমি সত্যিই দেখতে পাচ্ছি না। তাদের মধ্যে কি পার্থক্য আছে?


উত্তর:


86

বেনামে ফাংশন প্রকাশের ক্ষেত্রে, ফাংশনটি বেনামে  - আক্ষরিক অর্থে, এর কোনও নাম নেই। যে ভেরিয়েবলটি আপনি এটিকে অর্পণ করছেন তার একটি নাম রয়েছে তবে ফাংশনটি তা করে না। (আপডেট: ES5 এর মাধ্যমে এটি সত্য ছিল E ES2015 [ওরফে ES6] হিসাবে, প্রায়শই বেনামে প্রকাশযুক্ত একটি ফাংশন একটি আসল নাম পায় [তবে কোনও স্বয়ংক্রিয় শনাক্তকারী নয়], পড়ুন ...)

নামগুলি দরকারী। নামগুলি স্ট্যাক ট্রেস, কল স্ট্যাক, ব্রেকপয়েন্টের তালিকা ইত্যাদিতে দেখা যায় নামগুলি একটি ভাল জিনিস ™ ™

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

নামযুক্ত ফাংশন এক্সপ্রেশন সম্পর্কে একটি মূল বিষয় হ'ল এটি ফান্টন বডির মধ্যে ফাংশনের জন্য সেই নামের সাথে একটি ইন-স্কোপ সনাক্তকারী তৈরি করে:

var x = function example() {
    console.log(typeof example); // "function"
};
x();
console.log(typeof example);     // "undefined"

ES2015 হিসাবে, যদিও অনেকগুলি "বেনামে" ফাংশন এক্সপ্রেশন নামের সাথে ফাংশন তৈরি করে এবং বিভিন্ন আধুনিক জাভাস্ক্রিপ্ট ইঞ্জিনগুলি প্রসঙ্গ থেকে অনুমানের নামগুলি সম্পর্কে যথেষ্ট স্মার্ট বলে পূর্বাভাস দেওয়া হয়েছিল। ES2015 এ, আপনার বেনামি ফাংশন এক্সপ্রেশনটির নামের সাথে একটি ফাংশন তৈরি করে boo। যাইহোক, এমনকি ES2015 + শব্দার্থবিজ্ঞান সহ, স্বয়ংক্রিয় শনাক্তকারী তৈরি হয় না:

var obj = {
    x: function() {
       console.log(typeof x);   // "undefined"
       console.log(obj.x.name); // "x"
    },
    y: function y() {
       console.log(typeof y);   // "function"
       console.log(obj.y.name); // "y"
    }
};
obj.x();
obj.y();

ফাংশনটির নামের জন্য অ্যাসাইনমেন্টটি সেপফঞ্চননাম অ্যাবস্ট্রাক্ট অপারেশন দিয়ে সম্পন্ন করা হয় যা বিভিন্ন বৈশিষ্ট্যে ব্যবহৃত হয়।

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

var boo = function() { /*...*/ };

(বা এটি হতে পারে letবা constপরিবর্তে হতে পারে var) , বা

var obj = {
    boo: function() { /*...*/ }
};

বা

doSomething({
    boo: function() { /*...*/ }
});

(যারা শেষ দুটি সত্যিই একই জিনিস) , ফলস্বরূপ ফাংশনটির একটি নাম থাকবে ( booউদাহরণগুলিতে)।

একটি গুরুত্বপূর্ণ এবং ইচ্ছাকৃত ব্যতিক্রম আছে: একটি বিদ্যমান বস্তুর উপর সম্পত্তি অর্পণ:

obj.boo = function() { /*...*/ }; // <== Does not get a name

এটি যখন নতুন বৈশিষ্ট্য যুক্ত হওয়ার প্রক্রিয়াটি চলছিল তখন তথ্য ফাঁসের উদ্বেগ উত্থাপিত হয়েছিল; আমার অন্য প্রশ্নের উত্তর এখানে বিশদ


4
কমপক্ষে দুটি জায়গা রয়েছে যেখানে এনএফই ব্যবহার করে এখনও কংক্রিট সুবিধা দেওয়া হয়: প্রথমত, newঅপারেটরের মাধ্যমে কনস্ট্রাক্টর হিসাবে ব্যবহার করার উদ্দেশ্যে যে ফাংশনগুলির জন্য (এই জাতীয় সমস্ত ফাংশনের নাম দেওয়া .constructorহ্যাকটি সন্ধান করার জন্য ডিবাগিংয়ের সময় সম্পত্তিটিকে আরও কার্যকর করে তোলে কিছু অবজেক্টের উদাহরণ রয়েছে), এবং ফাংশনটির জন্য প্রথমে কোনও সম্পত্তি বা ভেরিয়েবলকে (যেমন setTimeout(function () {/*do stuff*/});) বরাদ্দ না করে সরাসরি কোনও ফাংশনে প্রবেশ করে । এমনকি ক্রোম এগুলি হিসাবে দেখায় (anonymous function)যতক্ষণ না আপনি এগুলিকে নামকরণের মাধ্যমে সহায়তা করেন।
মার্ক অ্যামেরি

4
@ মার্ক অ্যামেরি: "এটি কি এখনও সত্য? আমি ... এই বিধিগুলির জন্য সিটিআরএল-এফ চেষ্টা করেছি এবং সেগুলি খুঁজে পাইনি" ওহ হ্যাঁ। :-) এটি নিয়মের একটি সেট সংজ্ঞায়িত করে এক জায়গায় থাকার চেয়ে পুরো স্পেস জুড়েই ছড়িয়ে পড়েছে, কেবল "setFunctionName" অনুসন্ধান করুন। আমি উপরে লিঙ্কগুলির একটি ছোট উপসেট যোগ করেছি, তবে এটি বর্তমানে places 29 টি বিভিন্ন জায়গায় প্রদর্শিত হবে। আমি কেবলমাত্র হালকাভাবে অবাক হব যদি আপনার setTimeoutউদাহরণটি setTimeoutযদি এটির জন্য প্রথাগত যুক্তির জন্য ঘোষিত আনুষ্ঠানিক নামটি ধরে না নেয় তবে তা যদি থাকে। :-) তবে হ্যাঁ, এনএফইগুলি অবশ্যই কার্যকর হয় যদি আপনি জানেন যে আপনি পুরানো ব্রাউজারগুলির সাথে একটি হ্যাশ তৈরি করছেন না।
টিজে ক্রাউডার

24

নামকরণ ফাংশনগুলি যদি তাদের নিজেদের উল্লেখ করা প্রয়োজন (উদাহরণস্বরূপ পুনরাবৃত্ত কলগুলির জন্য) প্রয়োজন। প্রকৃতপক্ষে, আপনি যদি অন্য কোনও ফাংশনে সরাসরি আর্গুমেন্ট হিসাবে আক্ষরিক ফাংশন এক্সপ্রেশনটি পাস করেন তবে that ফাংশন এক্সপ্রেশনটি নামকরণ না করা হলে সরাসরি নিজেকে ES5 কঠোর মোডে উল্লেখ করতে পারে না

উদাহরণস্বরূপ, এই কোডটি বিবেচনা করুন:

setTimeout(function sayMoo() {
    alert('MOO');
    setTimeout(sayMoo, 1000);
}, 1000);

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

Anতিহাসিকভাবে এটি কোনও বেনাম ফাংশন এক্সপ্রেশন ব্যবহার করে, শোষণ করে এই জাতীয় কোড লেখা সম্ভব ছিল arguments.callee...

setTimeout(function () {
    alert('MOO');
    setTimeout(arguments.callee, 1000);
}, 1000);

... তবে arguments.calleeঅবহেলিত এবং ES5 কঠোর মোডে একেবারে নিষিদ্ধ। এমডিএন পরামর্শ দেয়:

arguments.callee()হয় ফাংশন এক্সপ্রেশন একটি নাম দিয়ে ব্যবহার করা বা একটি ফাংশন নিজেই কল করতে হবে যেখানে একটি ফাংশন ঘোষণা ব্যবহার করে এড়ানো ।

(জোর আমার)


3

কোনও ফাংশন যদি ফাংশন এক্সপ্রেশন হিসাবে নির্দিষ্ট করা থাকে, তবে এটি একটি নাম দেওয়া যেতে পারে।

এটি কেবল ফাংশনের অভ্যন্তরে উপলব্ধ থাকবে (আইই 8- ব্যতীত)।

var f = function sayHi(name) {
  alert( sayHi ); // Inside the function you can see the function code
};

alert( sayHi ); // (Error: undefined variable 'sayHi')

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

এছাড়াও, NFE (নামযুক্ত ফাংশন এক্সপ্রেশন) নামটি নীচের Object.defineProperty(...)পদ্ধতি অনুসারে ওভাররাইট করা যেতে পারে :

var test = function sayHi(name) {
  Object.defineProperty(test, 'name', { value: 'foo', configurable: true });
  alert( test.name ); // foo
};

test();

দ্রষ্টব্য: ফাংশন ঘোষণার সাথে এটি করা যায় না। এই "বিশেষ" অভ্যন্তরীণ ফাংশন নামটি কেবল ফাংশন এক্সপ্রেশন সিনট্যাক্সে নির্দিষ্ট করা হয়।


2

আপনার সর্বদা নামযুক্ত ফাংশন এক্সপ্রেশন ব্যবহার করা উচিত , এজন্য:

  1. আপনার পুনরাবৃত্তি প্রয়োজন হলে আপনি সেই ফাংশনের নামটি ব্যবহার করতে পারেন।

  2. অজ্ঞাতনামা ফাংশনগুলি ডিবাগ করার সময় সহায়তা করে না কারণ আপনি যে ফাংশনটির কারণে সমস্যার সৃষ্টি হয় তার নাম দেখতে পাচ্ছেন না।

  3. আপনি যখন কোনও ক্রিয়াকলাপের নাম রাখেন না, পরে এটি কী করছে তা বোঝা শক্ত। এটি একটি নাম দেওয়া বোঝা সহজ করে তোলে।

var foo = function bar() {
    //some code...
};

foo();
bar(); // Error!

এখানে, উদাহরণস্বরূপ, কারণ নাম বারটি একটি ফাংশন এক্সপ্রেশনের মধ্যে ব্যবহৃত হয়, এটি বাইরের স্কোপে ঘোষিত হয় না। নামযুক্ত ফাংশন এক্সপ্রেশন সহ, ফাংশন এক্সপ্রেশনটির নামটি তার নিজস্ব ক্ষেত্রের মধ্যে আবদ্ধ।


1

নামযুক্ত ফাংশন এক্সপ্রেশনগুলি ব্যবহার করা আরও ভাল, যখন আপনি অবহেলিত বৈশিষ্ট্যের উপর নির্ভর না করে যেমন প্রশ্নে ফাংশনটি উল্লেখ করতে সক্ষম হতে চান arguments.callee


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