javascript - জাভাস্ক্রিপ্ট বন্ধ বনাম বেনামী ফাংশন




scope closures (8)

আমার এবং আমার একজন বন্ধু বর্তমানে জেএস-এ বন্ধ হয়ে যাচ্ছেন এবং কী না তা নিয়ে আলোচনা করছেন। আমরা ঠিক নিশ্চিত করতে চাই আমরা সত্যিই এটি সঠিকভাবে বুঝি।

চল এই উদাহরণ নিতে। আমরা একটি কাউন্টিং লুপ আছে এবং কনসোল বিলম্বিত পাল্টা পরিবর্তনশীল মুদ্রণ করতে চান। অতএব আমরা সেট setTimeout এবং setTimeout পাল্টা পরিবর্তনশীলের মানটি ক্যাপচার করতে ব্যবহার করে নিশ্চিত করতে এটি N বার মানটি মুদ্রণ করবে না।

বন্ধ বা closures কাছাকাছি কিছু ছাড়া ভুল সমাধান হবে:

for(var i = 0; i < 10; i++) {
    setTimeout(function() {
        console.log(i);
    }, 1000);
}

অবশ্যই যা 10 লুপ পরে লুপ পরে 10 বার মুদ্রণ করবে।

তাই তার প্রচেষ্টা ছিল:

for(var i = 0; i < 10; i++) {
    (function(){
        var i2 = i;
        setTimeout(function(){
            console.log(i2);
        }, 1000)
    })();
}

মুদ্রণ 0 থেকে 9 হিসাবে প্রত্যাশিত।

আমি তাকে বলেছিলাম যে সে আমাকে ধরতে বন্ধ করে দিচ্ছে না, কিন্তু সে জোর করে বলে। আমি প্রমাণ করেছি যে লুপ শরীরের জন্য অন্য setTimeout (তার setTimeout ফাংশনটি সেট setTimeout ) এর মধ্যে বন্ধ করে ব্যবহার করে না, আবার 10 গুণ 10 টি মুদ্রণ করে। একইভাবে প্রয়োগ করা হয় যদি আমি তার ফাংশনটি একটি var এবং লুপের পরে এটি চালান, 10 গুণ 10 মুদ্রণ করে। সুতরাং আমার যুক্তি হল যে তিনি সত্যিই i মানটি ক্যাপচার করেন না , তার সংস্করণটি বন্ধ না করে।

আমার প্রচেষ্টা ছিল:

for(var i = 0; i < 10; i++) {
    setTimeout((function(i2){
        return function() {
            console.log(i2);
        }
    })(i), 1000);
}

তাই আমি আমি ক্যাপচার (নামকরণ i2 মধ্যে বন্ধ), কিন্তু এখন আমি অন্য ফাংশন ফিরে এবং প্রায় এই পাস। আমার ক্ষেত্রে, ফাংশন setTimeout পাস সত্যিই i captures।

এখন কে বন্ধ করছে এবং কে না?

দ্রষ্টব্য, উভয় সমাধান কনসোলের বিলম্বিত 0 থেকে 9 টি মুদ্রণ করে, তাই তারা মূল সমস্যাটি সমাধান করে, কিন্তু আমরা বুঝতে চাই যে এই দুটি সমাধানগুলির মধ্যে কোনটি সমাধানটি বন্ধ করার জন্য এটি বন্ধ করে।


আপনি এবং আপনার বন্ধুর বন্ধ উভয় ব্যবহার করুন:

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

MDN: interesting

আপনার বন্ধুর কোড ফাংশন function(){ console.log(i2); } function(){ console.log(i2); } বেনামী ফাংশন function(){ var i2 = i; ... বন্ধের ভিতরে সংজ্ঞায়িত function(){ var i2 = i; ... function(){ var i2 = i; ... এবং স্থানীয় পরিবর্তনশীল i2 পড়তে / লিখতে পারেন।

আপনার কোড ফাংশন function(){ console.log(i2); } function(){ console.log(i2); } ফাংশন function(i2){ return ... বন্ধ function(i2){ return ... এবং স্থানীয় মূল্যবান i2 (এই প্যারামিটার হিসাবে ঘোষিত function(i2){ return ... পড়তে / লিখতে পারেন।

উভয় ক্ষেত্রে ফাংশন function(){ console.log(i2); } function(){ console.log(i2); } তারপর setTimeout মধ্যে পাস।

অন্য সমতুল্য (কিন্তু কম মেমরি ব্যবহার সঙ্গে) হল:

function fGenerator(i2){
    return function(){
        console.log(i2);
    }
}
for(var i = 0; i < 10; i++) {
    setTimeout(fGenerator(i), 1000);
}

আপনি বন্ধ উভয় ব্যবহার করছেন।

আমি এখানে উইকিপিডিয়া সংজ্ঞা দিয়ে যাচ্ছি:

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

আপনার বন্ধুর প্রচেষ্টা স্পষ্টভাবে পরিবর্তনশীল i ব্যবহার করে, যা অ-স্থানীয়, তার মূল্য গ্রহণ করে এবং একটি অনুলিপি স্থানীয় i2 তে সঞ্চয় করার মাধ্যমে তৈরি করে।

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


আমি কিছুটা আগেই লিখেছিলাম এটি কী বন্ধ করে দেওয়া এবং এটি কীভাবে JS তে কাজ করে।

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

var z = 1;
function x(){
    var z = 2; 
    y(function(){
      alert(z);
    });
}
function y(f){
    var z = 3;
    f();
}
x(); //alerts '2' 

আসুন উভয় দিকে তাকান:

(function(){
    var i2 = i;
    setTimeout(function(){
        console.log(i2);
    }, 1000)
})();

ঘোষণা করে এবং অবিলম্বে একটি বেনামী ফাংশন চালায় যা setTimeout() নিজের প্রসঙ্গে চালায়। i বর্তমান মান i2 প্রথম কপি করে সংরক্ষণ করা হয়; এটা অবিলম্বে execution কারণ কাজ করে।

setTimeout((function(i2){
    return function() {
        console.log(i2);
    }
})(i), 1000);

অভ্যন্তরীণ ফাংশনের জন্য একটি কার্যকরকরণের প্রেক্ষাপট ঘোষণা করে যার মাধ্যমে আমার বর্তমান মান i2 সংরক্ষিত থাকে; এই পদ্ধতির মান সংরক্ষণ করার জন্য অবিলম্বে নির্বাহ ব্যবহার করে।

গুরুত্বপূর্ণ

এটি উল্লেখ করা উচিত যে রান পদ্ধতিগুলি উভয় পন্থাগুলির মধ্যে একই নয়; আপনার অভ্যন্তরীণ ফাংশন setTimeout() থেকে পাস করা হয় যখন তার অভ্যন্তরীণ ফাংশন setTimeout() নিজেই কল।

অন্য setTimeout() ভিতরে উভয় কোড setTimeout() প্রমাণ করে না যে শুধুমাত্র দ্বিতীয় পদ্ধতিতে setTimeout() ব্যবহার করা হয়, এর সাথে শুরু করার মতো একই জিনিস নেই।

উপসংহার

উভয় পদ্ধতি বন্ধের ব্যবহার, তাই এটি ব্যক্তিগত স্বাদ নিচে আসে; দ্বিতীয় পদ্ধতির কাছাকাছি "সরানো" বা সাধারণকরণ করা সহজ।


সংক্ষেপে জাভাস্ক্রিপ্ট ক্লোজারগুলি একটি ফাংশনকে একটি পরিবর্তনশীল অ্যাক্সেসের অনুমতি দেয় যা একটি লেক্সিক্যাল-প্যারেন্ট ফাংশনে ঘোষিত হয়

এর আরো বিস্তারিত ব্যাখ্যা দেখুন। বন্ধ করে বোঝার জন্য জাভাস্ক্রিপ্ট কীভাবে ভেরিয়েবলগুলিকে স্কোপ করে তা বোঝা গুরুত্বপূর্ণ।

সুযোগগুলি

জাভাস্ক্রিপ্ট scopes ফাংশন সঙ্গে সংজ্ঞায়িত করা হয়। প্রতিটি ফাংশন একটি নতুন সুযোগ সংজ্ঞায়িত করে।

নিম্নলিখিত উদাহরণ বিবেচনা করুন;

function f()
{//begin of scope f
  var foo='hello'; //foo is declared in scope f
  for(var i=0;i<2;i++){//i is declared in scope f
     //the for loop is not a function, therefore we are still in scope f
     var bar = 'Am I accessible?';//bar is declared in scope f
     console.log(foo);
  }
  console.log(i);
  console.log(bar);
}//end of scope f

কলিং প্রিন্ট কলিং

hello
hello
2
Am I Accessible?

আসুন এখন বিবেচনা করি যে আমাদের ফাংশন g অন্য ফাংশনের মধ্যে সংজ্ঞায়িত করা হয়েছে।

function f()
{//begin of scope f
  function g()
  {//being of scope g
    /*...*/
  }//end of scope g
  /*...*/
}//end of scope f

আমরা g lexical পিতামাতার কল হবে। আমরা এখন 2 scopes আছে আগে ব্যাখ্যা হিসাবে; সুযোগ f এবং সুযোগ g

কিন্তু একটি সুযোগ অন্যরকমের মধ্যে "ভিতরে", তাই সন্তানের সুযোগ পিতামাতার ফাংশনের সুযোগের ফাংশন অংশ? পিতা বা মাতা ফাংশন সুযোগ মধ্যে ঘোষণা ভেরিয়েবল সঙ্গে কি হবে; আমি শিশু ফাংশন সুযোগ থেকে তাদের অ্যাক্সেস করতে পারবেন? যে ঠিক যেখানে ধাপে ধাপে।

বন্ধ

জাভাস্ক্রিপ্টে ফাংশন g জিতে ঘোষিত যেকোনো ভেরিয়েবল অ্যাক্সেস করতে পারে না তবে প্যারেন্ট ফাংশন এর সুযোগে ঘোষিত যেকোনো ভেরিয়েবল অ্যাক্সেস করতে পারে।

নিম্নলিখিত বিবেচনা করুন;

function f()//lexical parent function
{//begin of scope f
  var foo='hello'; //foo declared in scope f
  function g()
  {//being of scope g
    var bar='bla'; //bar declared in scope g
    console.log(foo);
  }//end of scope g
  g();
  console.log(bar);
}//end of scope f

কলিং প্রিন্ট কলিং

hello
undefined

চলুন লাইন console.log(foo); । এই সময়ে আমরা সুযোগ g এবং আমরা সুযোগ f ঘোষণা করা পরিবর্তনশীল foo অ্যাক্সেস করার চেষ্টা। কিন্তু আগে বর্ণিত যে আমরা এখানে বর্ণিত কোনও রেফারেল প্যারেন্ট ফাংশনে ঘোষিত কোন পরিবর্তনশীল অ্যাক্সেস করতে পারি; g fx এর অভিজাত পিতামাতা হয়। অতএব hello মুদ্রিত হয়।
চলুন এখন লাইন console.log(bar); । এই পর্যায়ে আমরা সুযোগ f এবং আমরা সুযোগ g ঘোষণা করা হয় যে পরিবর্তনশীল bar অ্যাক্সেস করার চেষ্টা। bar বর্তমান সুযোগ ঘোষণা করা হয় না এবং ফাংশন g f এর পিতা নয়, তাই bar অনির্ধারিত

প্রকৃতপক্ষে আমরা একটি বিষাক্ত "গ্র্যান্ড পিতা বা মাতা" ফাংশনের সুযোগে ঘোষিত ভেরিয়েবলগুলিতেও অ্যাক্সেস করতে পারি। সুতরাং ফাংশন g মধ্যে সংজ্ঞায়িত একটি ফাংশন h হবে

function f()
{//begin of scope f
  function g()
  {//being of scope g
    function h()
    {//being of scope h
      /*...*/
    }//end of scope h
    /*...*/
  }//end of scope g
  /*...*/
}//end of scope f

তারপর h ফাংশন h , g , এবং f এর সুযোগে ঘোষিত সমস্ত ভেরিয়েবল অ্যাক্সেস করতে সক্ষম হবেন। এই বন্ধ সঙ্গে সম্পন্ন করা হয়। জাভাস্ক্রিপ্ট বন্ধের ক্ষেত্রে আমরা এক্সিকিউটিভ পিতামাতার ফাংশনে ঘোষিত যেকোনো পরিবর্তনশীল অ্যাক্সেস করতে পারি, লেক্সিক্যাল গ্র্যান্ড প্যারেন্ট ফাংশনে, লেক্সিক্যাল গ্র্যান্ড-গ্র্যান্ড পিতামাতা ফাংশনে, ইত্যাদি। এটি একটি সুযোগ চেন হিসাবে দেখা যেতে পারে; scope of current function -> scope of lexical parent function -> scope of lexical grand parent function -> ... যা শেষ পিতার ফাংশন না থাকে, যার কোনও লিখিত পিতা বা মাতা নেই।

উইন্ডো বস্তু

প্রকৃতপক্ষে চেইন শেষ পিতামাতার ফাংশন এ থামাতে না। আরো একটি বিশেষ সুযোগ আছে; বিশ্বব্যাপী সুযোগ । একটি ফাংশন ঘোষণা না প্রতি পরিবর্তনশীল বিশ্বব্যাপী সুযোগ ঘোষণা করা হয়। বৈশ্বিক সুযোগ দুটি বিশিষ্টতা আছে;

  • বিশ্বব্যাপী সুযোগ ঘোষণা প্রতিটি পরিবর্তনশীল সর্বত্র অ্যাক্সেসযোগ্য
  • বৈশ্বিক সুযোগে ঘোষিত ভেরিয়েবল window অবজেক্টের বৈশিষ্ট্যগুলির সাথে সামঞ্জস্যপূর্ণ।

অতএব বৈশ্বিক সুযোগে একটি পরিবর্তনশীল foo ঘোষণা করার ঠিক দুটি উপায় রয়েছে; এটি একটি ফাংশনে ঘোষণা না করে বা উইন্ডো অবজেক্টের সম্পত্তি foo সেট করে।

উভয় প্রচেষ্টা বন্ধ ব্যবহার করে

এখন আপনি আরো বিস্তারিত ব্যাখ্যা পড়েছেন এটি এখন স্পষ্ট হতে পারে যে উভয় সমাধান ক্লোজার ব্যবহার করে। কিন্তু নিশ্চিত হতে, একটি প্রমাণ করা যাক।

আসুন একটি নতুন প্রোগ্রামিং ভাষা তৈরি করি; জাভাস্ক্রিপ্ট-কোন-বন্ধ। নামটি যেমন প্রস্তাব করে, জাভাস্ক্রিপ্ট-ন-ক্লোজারটি জাভাস্ক্রিপ্টের সমতুল্য তবে এটি ক্লোজারগুলিকে সমর্থন করে না।

অন্য কথায়;

var foo = 'hello';
function f(){console.log(foo)};
f();
//JavaScript-No-Closure prints undefined
//JavaSript prints hello

ঠিক আছে, জাভাস্ক্রিপ্ট-নন-ক্লোজারের সাথে প্রথম সমাধানটির সাথে কী ঘটেছে তা দেখি;

for(var i = 0; i < 10; i++) {
  (function(){
    var i2 = i;
    setTimeout(function(){
        console.log(i2); //i2 is undefined in JavaScript-No-Closure 
    }, 1000)
  })();
}

অতএব এটি জাভাস্ক্রিপ্ট-নন-ক্লোজারে 10 বার undefined মুদ্রণ করবে।

অতএব প্রথম সমাধান বন্ধ ব্যবহার করে।

আসুন দ্বিতীয় সমাধান তাকান;

for(var i = 0; i < 10; i++) {
  setTimeout((function(i2){
    return function() {
        console.log(i2); //i2 is undefined in JavaScript-No-Closure
    }
  })(i), 1000);
}

অতএব এটি জাভাস্ক্রিপ্ট-নন-ক্লোজারে 10 বার undefined মুদ্রণ করবে।

উভয় সমাধান বন্ধ ব্যবহার করে।

সম্পাদনা: এটি ধরা হয় যে এই 3 কোড স্নিপেটগুলি বিশ্বব্যাপী সুযোগে সংজ্ঞায়িত করা হয় না। অন্যথায় ভেরিয়েবল foo এবং i window অবজেক্টের সাথে যুক্ত হবে এবং সেইজন্য জাভাস্ক্রিপ্ট এবং জাভাস্ক্রিপ্ট-ন-ক্লোজার উভয় window অবজেক্টের মাধ্যমে অ্যাক্সেসযোগ্য হবে।


closure সংজ্ঞা সংজ্ঞা অনুযায়ী:

একটি "বন্ধকরণ" একটি অভিব্যক্তি (সাধারণত একটি ফাংশন) যা এমন একটি পরিবেশের সাথে একযোগে বিনামূল্যে ভেরিয়েবল থাকতে পারে যা ঐ ভেরিয়েবলগুলিকে আবদ্ধ করে (যেটি "অভিব্যক্তিটি বন্ধ করে")।

আপনি ফাংশনের বাইরে সংজ্ঞায়িত করা একটি পরিবর্তনশীল ব্যবহার করে একটি ফাংশন সংজ্ঞায়িত যদি আপনি closure ব্যবহার করছেন। (আমরা পরিবর্তনশীল একটি বিনামূল্যে পরিবর্তনশীল কল)।
তারা সব closure ব্যবহার (এমনকি 1 ম উদাহরণ)।


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

বন্ধ জন্য একটি সহজ ব্যাখ্যা:

  1. একটি ফাংশন নিন। আসুন এটিকে কল করি এফ।
  2. এফ এর সব ভেরিয়েবল তালিকা।
  3. ভেরিয়েবল দুই ধরনের হতে পারে:
    1. স্থানীয় ভেরিয়েবল (আবদ্ধ ভেরিয়েবল)
    2. অ-স্থানীয় ভেরিয়েবল (বিনামূল্যে ভেরিয়েবল)
  4. যদি কোনও ফ্রি ভেরিয়েবল থাকে তবে এটি বন্ধ করা যাবে না।
  5. যদি F এ কোনও ফ্রি ভেরিয়েবল থাকে (যা F এর পিতামাতার সুযোগে সংজ্ঞায়িত করা হয়) তাহলে:
    1. একটি ফ্রি পরিবর্তনশীল আবদ্ধ যা F এর শুধুমাত্র একটি পিতা-মাতা সুযোগ থাকতে হবে।
    2. যদি পিতাকে সেই অভিভাবকের সুযোগের বাইরে থেকে উল্লেখ করা হয় তবে এটি সেই মুক্ত পরিবর্তনশীলের জন্য বন্ধ হয়ে যায়।
    3. যে ফ্রি পরিবর্তনশীল বন্ধ F একটি আপত্তিকর বলা হয়।

এখন বন্ধ করার জন্য কে ব্যবহার করে এবং কে না (ব্যাখ্যা করার জন্য আমি ফাংশন নামকরণ করেছি) ব্যবহার করার জন্য এটি ব্যবহার করি।

কেস 1: আপনার বন্ধুর প্রোগ্রাম

for (var i = 0; i < 10; i++) {
    (function f() {
        var i2 = i;
        setTimeout(function g() {
            console.log(i2);
        }, 1000);
    })();
}

উপরের প্রোগ্রামে দুটি ফাংশন রয়েছে: f এবং g । দেখা যাক তারা বন্ধ আছে কিনা:

f :

  1. ভেরিয়েবল তালিকা:
    1. i2 একটি স্থানীয় পরিবর্তনশীল।
    2. i একটি বিনামূল্যে পরিবর্তনশীল।
    3. setTimeout একটি বিনামূল্যে পরিবর্তনশীল।
    4. g একটি স্থানীয় পরিবর্তনশীল।
    5. console একটি বিনামূল্যে পরিবর্তনশীল।
  2. প্রতিটি বিনামূল্যে পরিবর্তনশীল আবদ্ধ করা হয় যা পিতামাতার সুযোগ খুঁজুন:
    1. i বিশ্বব্যাপী সুযোগ আবদ্ধ
    2. setTimeout আন্তর্জাতিক সুযোগ আবদ্ধ হয়।
    3. console বৈশ্বিক সুযোগ আবদ্ধ হয়।
  3. ফাংশন রেফারেন্স যা কোন সুযোগ হয়? বিশ্বব্যাপী সুযোগ
    1. তাই i f দ্বারা বন্ধ করা হয় না।
    2. তাই setTimeout f দ্বারা বন্ধ করা হয় না।
    3. তাই console f দ্বারা বন্ধ করা হয় না।

সুতরাং ফাংশন f বন্ধ একটি নয়।

g :

  1. ভেরিয়েবল তালিকা:
    1. console একটি বিনামূল্যে পরিবর্তনশীল।
    2. i2 একটি বিনামূল্যে পরিবর্তনশীল।
  2. প্রতিটি বিনামূল্যে পরিবর্তনশীল আবদ্ধ করা হয় যা পিতামাতার সুযোগ খুঁজুন:
    1. console বৈশ্বিক সুযোগ আবদ্ধ হয়।
    2. i2 f এর সুযোগ আবদ্ধ হয়।
  3. ফাংশন রেফারেন্স যা কোন সুযোগ হয়? setTimeout সুযোগ
    1. তাই console g দ্বারা বন্ধ করা হয় না।
    2. তাই i2 দ্বারা g বন্ধ করা হয়।

এভাবে ফাংশন জিটি ফ্রি ভেরিয়েবল i2 (যা জিটির জন্য উচ্চতর হয়) -এর জন্য বন্ধ করা হয় যখন এটি সেট setTimeout মধ্যে থেকে উল্লেখ করা setTimeout

আপনার জন্য খারাপ: আপনার বন্ধুর একটি বন্ধ ব্যবহার করা হয়। ভিতরের ফাংশন একটি বন্ধ।

কেস 2: আপনার প্রোগ্রাম

for (var i = 0; i < 10; i++) {
    setTimeout((function f(i2) {
        return function g() {
            console.log(i2);
        };
    })(i), 1000);
}

উপরের প্রোগ্রামে দুটি ফাংশন রয়েছে: f এবং g । দেখা যাক তারা বন্ধ আছে কিনা:

f :

  1. ভেরিয়েবল তালিকা:
    1. i2 একটি স্থানীয় পরিবর্তনশীল।
    2. g একটি স্থানীয় পরিবর্তনশীল।
    3. console একটি বিনামূল্যে পরিবর্তনশীল।
  2. প্রতিটি বিনামূল্যে পরিবর্তনশীল আবদ্ধ করা হয় যা পিতামাতার সুযোগ খুঁজুন:
    1. console বৈশ্বিক সুযোগ আবদ্ধ হয়।
  3. ফাংশন রেফারেন্স যা কোন সুযোগ হয়? বিশ্বব্যাপী সুযোগ
    1. তাই console f দ্বারা বন্ধ করা হয় না।

সুতরাং ফাংশন f বন্ধ একটি নয়।

g :

  1. ভেরিয়েবল তালিকা:
    1. console একটি বিনামূল্যে পরিবর্তনশীল।
    2. i2 একটি বিনামূল্যে পরিবর্তনশীল।
  2. প্রতিটি বিনামূল্যে পরিবর্তনশীল আবদ্ধ করা হয় যা পিতামাতার সুযোগ খুঁজুন:
    1. console বৈশ্বিক সুযোগ আবদ্ধ হয়।
    2. i2 f এর সুযোগ আবদ্ধ হয়।
  3. ফাংশন রেফারেন্স যা কোন সুযোগ হয়? setTimeout সুযোগ
    1. তাই console g দ্বারা বন্ধ করা হয় না।
    2. তাই i2 দ্বারা g বন্ধ করা হয়।

এভাবে ফাংশন জিটি ফ্রি ভেরিয়েবল i2 (যা জিটির জন্য উচ্চতর হয়) -এর জন্য বন্ধ করা হয় যখন এটি সেট setTimeout মধ্যে থেকে উল্লেখ করা setTimeout

আপনার জন্য ভাল: আপনি একটি বন্ধ ব্যবহার করছেন। ভিতরের ফাংশন একটি বন্ধ।

সুতরাং আপনি এবং আপনার বন্ধু উভয় বন্ধ ব্যবহার করা হয়। তর্ক করা বন্ধ করুন. আমি আশা করি বন্ধ করার ধারণাটি এবং আপনার উভয়ের জন্য কীভাবে তাদের সনাক্ত করা যায়।

সম্পাদন: সমস্ত ফাংশন বন্ধ করার জন্য একটি সাধারণ ব্যাখ্যা (ক্রেডিট @ পিটার):

প্রথমে আসুন নিম্নলিখিত প্রোগ্রামটি বিবেচনা করি (এটি control ):

lexicalScope();

function lexicalScope() {
    var message = "This is the control. You should be able to see this message being alerted.";

    regularFunction();

    function regularFunction() {
        alert(eval("message"));
    }
}

  1. আমরা জানি যে উভয় lexicalScope এবং regularFunction উপরের সংজ্ঞা থেকে বন্ধ নয়।
  2. যখন আমরা প্রোগ্রামটি কার্যকর করি তখন আমরা message সতর্ক রাখতে আশা করি কারণ regularFunction বন্ধ করা হয় না (অর্থাত এটি তার পিতামাতার সুযোগে সমস্ত ভেরিয়েবলের অ্যাক্সেস আছে - message সহ)।
  3. যখন আমরা প্রোগ্রামটি কার্যকর করি তখন আমরা লক্ষ্য করি যে message প্রকৃতপক্ষে সতর্ক করা হয়েছে।

এর পরবর্তী প্রোগ্রামটি বিবেচনা করা যাক (এটি alternative ):

var closureFunction = lexicalScope();

closureFunction();

function lexicalScope() {
    var message = "This is the alternative. If you see this message being alerted then in means that every function in JavaScript is a closure.";

    return function closureFunction() {
        alert(eval("message"));
    };
}

  1. আমরা জানি যে শুধুমাত্র ক্লোজার closureFunction উপরের সংজ্ঞা থেকে একটি বন্ধ।
  2. যখন আমরা প্রোগ্রামটি কার্যকর করি তখন আমরা message সতর্ক রাখতে চাই না কারণ closureFunction বন্ধ করা হয় (অর্থাৎ ফাংশন তৈরি হওয়ার সময় এটি কেবল তার সমস্ত অ-স্থানীয় ভেরিয়েবলের অ্যাক্সেস আছে ( এই উত্তরটি দেখুন ) - closureFunction message অন্তর্ভুক্ত নেই)।
  3. যখন আমরা প্রোগ্রামটি কার্যকর করি তখন আমরা লক্ষ্য করি যে message আসলে সতর্ক করা হচ্ছে।

আমরা এই থেকে কি বোঝা?

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

আমি আমার উদাহরণ এবং বন্ধ সম্পর্কে একটি ব্যাখ্যা শেয়ার করতে চাই। আমি একটি পাইথন উদাহরণ, এবং দুই পরিসংখ্যান স্ট্যাক রাজ্যের প্রদর্শন।

def maker(a, b, n):
    margin_top = 2
    padding = 4
    def message(msg):
        print('\n’ * margin_top, a * n, 
            '  * padding, msg, ' ‘ * padding, b * n)
    return message

f = maker('*', '#', 5)
g = maker('', '♥’, 3)
…
f('hello')
g(‘good bye!')

নিম্নরূপ এই কোড আউটপুট হবে:

*****      hello      #####

      good bye!    ♥♥♥

স্ট্যাক এবং ফাংশন বস্তুর সাথে সংযুক্ত বন্ধ দেখানোর জন্য এখানে দুটি পরিসংখ্যান রয়েছে।

ফাংশন নির্মাতার থেকে ফিরে যখন

যখন ফাংশন পরে বলা হয়

যখন ফাংশনটি কোন প্যারামিটার বা ননলোকাল ভেরিয়েবলের মাধ্যমে বলা হয়, তখন কোডটি স্থানীয় পরিবর্তনশীল বাইন্ডিংগুলির প্রয়োজন যেমন মার্জিন_टॉप, প্যাডিং পাশাপাশি a, b, n। কাজ করার ফাংশন কোডটি নিশ্চিত করার জন্য, সৃষ্টিকর্তা ফাংশনটির স্ট্যাক ফ্রেম যা পূর্বে চলে গিয়েছিল তা অ্যাক্সেসযোগ্য হওয়া উচিত, যা ফাংশন বার্তা বস্তুর পাশাপাশি বন্ধ করা যেতে পারে।






closures