ফাংশন যে ফাংশন ফিরে


109

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

স্নিপেট এক:

    function a() {
      
        alert('A!');
    
        function b(){
            alert('B!'); 
        }
    
        return b();
    }
    
    var s = a();
    alert('break');
    s();

আউটপুট:

A!
B!
break

স্নিপেট টু

function a() {
  
    alert('A!');

    function b(){
        alert('B!'); 
    }

    return b;
}

var s = a();
alert('break');
s();
আউটপুট:

A!
break
B!

দয়া করে কেউ কি আমাকে ফিরে মধ্যে পার্থক্য বলতে পারবেন bএবং b()উপরে স্নিপেট মধ্যে?


2
আপনি লক্ষ্য করবেন প্রথম স্নিপেট এস () এ ত্রুটি দেয়;
অদ্ভুতসাল্পফুলান

উত্তর:


121

কোনও ফাংশনে ভেরিয়েবল বরাদ্দ করা (প্রথম বন্ধনী ব্যতীত) ফাংশনের রেফারেন্সটি অনুলিপি করে। ফাংশন নামের শেষে প্রথম বন্ধনী রেখে ফাংশনটিকে ফিরতি মান প্রদান করে return

ডেমো

function a() {
    alert('A');
}
//alerts 'A', returns undefined

function b() {
    alert('B');
    return a;
}
//alerts 'B', returns function a

function c() {
    alert('C');
    return a();
}
//alerts 'C', alerts 'A', returns undefined

alert("Function 'a' returns " + a());
alert("Function 'b' returns " + b());
alert("Function 'c' returns " + c());

আপনার উদাহরণে, আপনি কোনও ফাংশনের মধ্যে ফাংশনগুলিও সংজ্ঞায়িত করছেন are যেমন:

function d() {
    function e() {
        alert('E');
    }
    return e;
}
d()();
//alerts 'E'

ফাংশনটি এখনও কলযোগ্য। এটি এখনও বিদ্যমান। এটি জাভাস্ক্রিপ্টে সর্বদা ব্যবহৃত হয়। কার্যাবলী প্রায় পাশ করা যাবে শুধু অন্য মান মত। নিম্নোক্ত বিবেচনা কর:

function counter() {
    var count = 0;
    return function() {
        alert(count++);
    }
}
var count = counter();
count();
count();
count();

ফাংশন গণনা তার বাইরে সংজ্ঞায়িত করা চলকগুলি রাখতে পারে can একে ক্লোজার বলা হয়। এটি জাভাস্ক্রিপ্টে প্রচুর ব্যবহৃত হয়েছে।


স্নিপেট ওয়ান: var নায়ক = {নাম: 'রাফায়েলো', sayName: ফাংশন () {রিটার্ন নায়ক.নাম; ;, nayName: নায়ক.সায়নাম} নায়ক.নায়নাম (); স্নিপেট দুই: var নায়ক = {নাম: 'রাফায়েলো', sayName: ফাংশন () {রিটার্ন নায়ক.নাম; ;, nayName: this.sayName} hero.nayName (); প্রথম স্নিপেট আমাকে সঠিক আউটপুট দেয় যখন দ্বিতীয়টি তা দেয় না। কেন? শুভেচ্ছা।
ক্যাফেওরারিডোর

thisকেবলমাত্র কোনও ক্রিয়াকলাপের দেহের ভিতরে থাকা অর্থ, অন্যথায় এটি বৈশ্বিক। আপনি যা বলছেন this.sayNameতা হ'ল আপনি বৈশ্বিক পরিবর্তনশীল চান sayNameযা বিদ্যমান নেই, এটি অপরিজ্ঞাত, সুতরাং কলযোগ্য নয়।
kzh

7
আমি ডি () () দ্বারা বিভ্রান্ত হয়ে পড়েছিলাম; প্রথমে তবে তারপরে বুঝতে পেরেছি যে প্রথম () কলটি ডি এবং দ্বিতীয়টি () কল করে ডি এর রিটার্ন মান, যা ই।
স্কাল

1
আট বছর পরে এবং এটি এখনও প্রাসঙ্গিক!
ব্র্যাড ভ্যান্ডারবাশ

45

ফাংশনটির নাম বাদ দিয়ে ফাংশনটির ()একটি রেফারেন্স প্রদান করে, যা আপনি যেমন করেছেন তেমন বরাদ্দ করা যেতে পারে var s = a()sএখন ফাংশনটির জন্য একটি রেফারেন্স রয়েছে b()এবং কলিং s()কার্যত কলিংয়ের সমতুল্য b()

// Return a reference to the function b().
// In your example, the reference is assigned to var s
return b;

()রিটার্ন স্টেটমেন্টের সাথে ফাংশনটিতে কল করা ফাংশনটি কার্যকর করে এবং ফাংশন দ্বারা যে কোনও মান ফিরিয়ে দেয় তা প্রদান করে। এটি কল করার মতো var x = b();, তবে আপনার রিটার্ন মান নির্ধারণের পরিবর্তে b()কলিং ফাংশন থেকে এটি ফিরিয়ে দিচ্ছেন a()। যদি ফাংশনটি b()নিজেই কোনও মান ফেরত undefinedনা দেয়, অন্য যে কোনও কাজ করার পরে কলটি ফিরে আসে b()

// Execute function b() and return its value
return b();
// If b() has no return value, this is equivalent to calling b(), followed by
// return undefined;

1
সমস্ত উত্তরগুলির মধ্যে, আমি আপনার উত্তরটি এর সরলতার কারণে বেশি পছন্দ করেছি।
আনার খলিলভ

ভাল করা! এই উত্তরটি বোঝা খুব সহজ।
অ্যান্ড্রুস্টেইনহাইজার

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

37

return b(); বি () ফাংশনটি কল করে এবং তার ফলাফলটি দেয়।

return b; বি ফাংশনের একটি রেফারেন্স প্রদান করে, যা আপনি পরে কল করার জন্য একটি ভেরিয়েবলের মধ্যে সঞ্চয় করতে পারেন।


17

রিটার্নিং bএকটি ফাংশন অবজেক্ট ফিরিয়ে দিচ্ছে। জাভাস্ক্রিপ্টে, ফাংশনগুলি হ'ল অন্য অবজেক্টের মতো কেবল অবজেক্টস। যদি আপনি এটি সহায়ক না হন তবে কেবল "বস্তু" শব্দটি "জিনিস" দিয়ে প্রতিস্থাপন করুন। আপনি কোনও ফাংশন থেকে যে কোনও অবজেক্ট ফিরিয়ে দিতে পারেন। আপনি একটি সত্য / মিথ্যা মান দিতে পারেন। একটি পূর্ণসংখ্যা (1,2,3,4 ...)। আপনি একটি স্ট্রিং ফিরে আসতে পারেন। আপনি একাধিক বৈশিষ্ট্য সহ একটি জটিল অবজেক্ট ফিরিয়ে দিতে পারেন। এবং আপনি একটি ফাংশন ফিরে আসতে পারেন। একটি ফাংশন কেবল একটি জিনিস।

আপনার ক্ষেত্রে, bজিনিসটি ফিরে আসায়, জিনিসটি কলযোগ্য ফাংশন। প্রত্যাবর্তন b()কলযোগ্য ফাংশন দ্বারা ফিরে মান প্রদান করে।

এই কোডটি বিবেচনা করুন:

function b() {
   return 42;
}

উপরের সংজ্ঞাটি ব্যবহার করে, return b();মানটি 42 প্রদান করে the অন্যদিকে return b;একটি ফাংশন ফেরত দেয় যা নিজেই 42 এর মান দেয় They এগুলি দুটি ভিন্ন জিনিস।


4
এটি ফিরে আসা উচিত 42;)
c69

4

আপনি যখন ফিরে আসেন b, এটি কেবল ফাংশন বি এর একটি রেফারেন্স, তবে এই মুহুর্তে কার্যকর করা হচ্ছে না।

যখন আপনি ফিরে আসবেন b(), আপনি ফাংশনটি সম্পাদন করছেন এবং এর মানটি ফিরিয়ে দিচ্ছেন।

আপনার উদাহরণগুলিতে অন্তর্ভুক্ত alertকরার চেষ্টা করুন typeof(s)। স্নিপেট বি আপনাকে 'ফাংশন' দেবে। একটি স্নিপেট আপনাকে কী দেবে?


প্রথমটি 'অপরিজ্ঞাত' দেয়। এর অর্থ কী রিটার্ন বি () সম্পূর্ণ অকেজো? এছাড়াও, দ্বিতীয় স্নিপেটে, ফাংশন বিটি ব্যক্তিগত। তাহলে কীভাবে আমরা ফাংশনের বাইরে রেফারেন্সটি অ্যাক্সেস করতে পারি? দয়া করে আমাকে একটি লিঙ্ক সরবরাহ করুন যা সম্ভব হলে এই ধারণাটি পরিষ্কারভাবে ব্যাখ্যা করে। ধন্যবাদ!
ক্যাফেওরারিডোর ২৩ শে

আমি প্রথমটির উত্তর পেয়েছি। ফাংশন বি () এ 1 + 2 এবং টাইপফো নম্বর দেখায়। ধন্যবাদ।
ক্যাফেওরারিডোর

ভাগ্যিশ তুমি বুঝতে পেরেছ! ব্যক্তিগত ফাংশন হিসাবে: এটি ইতিমধ্যে দ্বিতীয় উদাহরণটিতে ব্যক্তিগত নয় কারণ আপনি ইতিমধ্যে এটি ফিরিয়ে দিয়েছেন। আসলে, এটি নির্ধারিত হয় sreturn thisপরিবর্তে চেষ্টা করুন return b... আপনি s.b()তখন করতে সক্ষম হবেন ;)
ভিজউইক

আমি এটি চেষ্টা করে দেখতে চেষ্টা করব। জাভাস্ক্রিপ্টে এই ধারণাটি পৌঁছেছে না। দু'দিনেই হতে পারে। ধন্যবাদ! :)
ক্যাফেওরারিডোর

ফাংশন a () {সতর্কতা ("এ!"); ফাংশন বি () {সতর্কতা ("বি!"); } প্রত্যাবর্তন খ; } var s = a (); মুছুন; গুলি (); ---- শেষ ---- জাভাস্ক্রিপ্টে রেফারেন্সের ধারণাটি কি জাভার মতো? এখানে আমি একটি () ফাংশনটি মুছে ফেলেছি এবং তারপরে (()) এর একটি কল কার্যকর করেছে খ ()। সুতরাং আমি কি বলতে পারি যে এসগুলিতে বি এর একটি অনুলিপি রয়েছে এবং একটি () এ সংজ্ঞায়িত খ () এর দিকে নির্দেশ করছে না?
ক্যাফেকারিডর

2

কোন প্রকারের মতো কোনও ক্রিয়া হিসাবে ফাংশনটি কল্পনা করুন। আপনি একটি ফাংশন ints ফিরে আসতে পারেন। আপনি ফাংশনগুলিও ফিরিয়ে দিতে পারেন, তারা "ফাংশন" টাইপের অবজেক্ট।

এখন সিনট্যাক্স সমস্যা: কারণ ফাংশনগুলি মান দেয়, আপনি কীভাবে কোনও ফাংশন ফিরিয়ে দিতে পারবেন এবং এটির মান ফিরে আসবে না?

বন্ধনী বাদ দিয়ে! কারণ বন্ধনী ব্যতীত, ফাংশনটি কার্যকর করা হবে না! তাই:

return b;

"ফাংশন" ফিরিয়ে দেবে (এটি কল্পনা করুন যেমন আপনি একটি নম্বর ফিরিয়ে দিচ্ছেন), যখন:

return b();

প্রথমে ফাংশনটি কার্যকর করে তারপরে এটি সম্পাদন করে প্রাপ্ত মানটি ফিরিয়ে দেয়, এটি বড় পার্থক্য!


দ্বিতীয় স্নিপেটে, ফাংশন বিটি ব্যক্তিগত। তাহলে কীভাবে আমরা ফাংশনের বাইরে রেফারেন্সটি অ্যাক্সেস করতে পারি? একই নিয়ন্ত্রক কোন নিয়ম আছে?
ক্যাফেওরারিডোর

জাভাস্ক্রিপ্টে থাকা অবজেক্টস (এতে ফাংশন অন্তর্ভুক্ত) আপনি ভাগ করে নিলে সেগুলি আর ব্যক্তিগত নয়।
কেজেড

@ ক্যাফাকরিডর: যদি ব্যক্তিগত ফাংশনটি কোনও কিছু দিয়ে (জনসাধারণের ফাংশন) ফেরত দেওয়া হয় বা কোনও সর্বজনীন ভেরিয়েবলের জন্য বরাদ্দ করা হয় (ভাল, একটি অ্যাপ্লিকেশন-অ্যাক্সেসযোগ্য ভেরিয়েবল), আপনি সহজেই আপনার পরিবর্তনশীল () করতে পারেন ; , অন্যথায় ফাংশনটি একটি ভেরিয়েবলকে ফেরত দিন এবং আপনার পরিবর্তনশীল ()
ফ্রান্সেস্কো বেলাদোনা

2

একটি পরিবর্তনশীল তৈরি করুন :

var thing1 = undefined;

একটি ঘোষণা ফাংশন :

function something1 () {
    return "Hi there, I'm number 1!";
}

সতর্ক করুন মান এর thing1(আমাদের প্রথম পরিবর্তনশীল):

alert(thing1); // Outputs: "undefined".

এখন, আমরা যদি ফাংশনটির thing1একটি রেফারেন্স হতে চাইতাম something1, যার অর্থ এটি আমাদের তৈরি ফাংশনটির মতো হবে তবে আমরা এটি করব:

thing1 = something1;

যাইহোক, আমরা যদি ফাংশনের return মান চাইতাম তবে আমাদের অবশ্যই এটি সম্পাদিত ফাংশনের রিটার্ন মান নির্ধারণ করতে হবে। আপনি প্রথম বন্ধনী ব্যবহার করে ফাংশনটি সম্পাদন করুন:

thing1 = something1(); // Value of thing1: "Hi there, I'm number 1!" 

-1

স্নিপেট এক:

function a() {
  
    alert('A!');

    function b(){
        alert('B!'); 
    }

    return b(); //return nothing here as b not defined a return value
}

var s = a(); //s got nothing assigned as b() and thus a() return nothing.
alert('break');
s(); // s equals nothing so nothing will be executed, JavaScript interpreter will complain

বিবৃতি 'বি ()' এর অর্থ 'বি' নামক ফাংশনটি সম্পাদন করা যা 'বি' টেক্সট সহ একটি ডায়ালগ বক্স দেখায়!

বিবৃতি 'রিটার্ন বি ();' এর অর্থ 'বি' নামক একটি ফাংশন সম্পাদন করা এবং তারপরে কোন ফাংশন 'বি' রিটার্ন ফিরে আসে। তবে 'বি' কিছুই দেয় না, তবে এই বিবৃতি 'রিটার্ন বি ()' তেমন কিছুই দেয় না। যদি খ () কোনও সংখ্যা ফেরত দেয়, তবে 'রিটার্ন বি ()' একটি সংখ্যাও।

এখন 's' কে 'a ()' রিটার্নের মান নির্ধারিত হয়েছে, যা 'b ()' দেয়, যা কিছুই নয়, তাই 'গুলি' কিছুই নয় (জাভাস্ক্রিপ্টে এটি আসলে একটি জিনিস, এটি একটি 'অপরিজ্ঞাত') So যখন আপনি জাভাস্ক্রিপ্টকে 's' কীভাবে ডেটা টাইপ করেন তা ব্যাখ্যা করতে বলুন, জাভাস্ক্রিপ্ট ইন্টারপ্রেটার আপনাকে বলবে যে এর 'একটি অপরিজ্ঞাত)) যখন আপনি জাভাস্ক্রিপ্টকে এই বিবৃতি' গুলি () 'সম্পাদন করতে বলেন, আপনি জাভাস্ক্রিপ্টকে 's' নামে একটি ফাংশন সম্পাদন করতে বলছেন, তবে এখানে 's' একটি 'অপরিজ্ঞাত', কোনও ফাংশন নয়, তাই জাভাস্ক্রিপ্ট অভিযোগ করবে, "আরে, কোনও ফাংশন নয়, আমি জানি না কীভাবে এই এসটি করার জন্য ", তারপরে একটি" আনকচড টাইপয়েরর: গুলি কোনও ফাংশন নয় "ত্রুটি বার্তা জাভাস্ক্রিপ্ট দ্বারা প্রদর্শিত হবে (ফায়ারফক্স এবং ক্রোমে পরীক্ষিত)


স্নিপেট টু

function a() {
  
    alert('A!');

    function b(){
        alert('B!'); 
    }

    return b; //return pointer to function b here
}

var s = a();  //s get the value of pointer to b
alert('break');
s(); // b() function is executed

এখন, 'a' ফাংশনটি 'বি' নামের একটি ফাংশনে একটি পয়েন্টার / ওরফে ফিরে আসবে। সুতরাং 's = a ()' নির্বাহের সময়, 's' বি এর দিকে নির্দেশিত একটি মান পাবে, অর্থাত্ 's' এখন 'বি' এর একটি নাম, 's' সমান কল করাকে 'বি' বলবে। অর্থাত্ 's' এখন একটি ফাংশন। এক্সিকিউট করার অর্থ 'বি' ('বি ()' নির্বাহের সমান) ফাংশন চালানো, একটি ডায়ালগ বক্স যা 'বি' দেখায়! হাজির হবে (যেমন 'সতর্কতা চালানো (' বি! '); ফাংশন' বি 'তে বিবৃতি)


-2

এটি বাস্তব জীবনে অত্যন্ত দরকারী।

এক্সপ্রেস.জেএস এর সাথে কাজ করা

সুতরাং আপনার নিয়মিত expressরুটটি এমন দেখাচ্ছে:

function itWorksHandler( req, res, next ) {
  res.send("It works!");
}

router.get("/check/works", itWorksHandler );

তবে আপনার যদি কিছু মোড়ক, ত্রুটি হ্যান্ডলার বা স্মেথ যুক্ত করার দরকার হয় তবে?

তারপরে আপনি নিজের ফাংশনটি একটি মোড়কের আড়ালে বন্ধ করুন।

function loggingWrapper( req, res, next, yourFunction ) {
  try {
    yourFunction( req, res );
  } catch ( err ) {
    console.error( err );
    next( err );
  }
}

router.get("/check/works", function( req, res, next ) {
  loggingWrapper( req, res, next, itWorksHandler );
});

জটিল মনে হচ্ছে? ঠিক আছে, এটি সম্পর্কে:

function function loggingWrapper( yourFunction ) => ( req, res, next ) {
  try {
    yourFunction( req, res, next );
  } catch ( err ) {
    console.error( err );
    next( err );
  }
}

router.get("/check/works", loggingWrapper( itWorksHandler ) );

শেষে দেখুন আপনি loggingWrapperঅন্য ফাংশন হিসাবে একটি যুক্তিযুক্ত একটি ফাংশনটি পাস করছেন itWorksHandler, এবং আপনার আর্গুমেন্ট হিসাবে গ্রহণ করে এমন loggingWrapperএকটি নতুন ফাংশন req, res, nextপ্রদান করবে।

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