'বন্ধ' কী?


432

আমি কারিিং সম্পর্কে একটি প্রশ্ন জিজ্ঞাসা করেছি এবং বন্ধগুলি উল্লেখ করা হয়েছিল। বন্ধ কী? এটি কারিঙের সাথে কীভাবে সম্পর্কিত?


22
এখন বন্ধটা ঠিক কী ??? কিছু উত্তর বলে, বন্ধটি হ'ল ফাংশন। কেউ কেউ বলেন এটি স্ট্যাক। কিছু উত্তর বলে যে এটি "লুকানো" মান। আমার বোঝার জন্য এটি ফাংশন + সংযুক্ত ভেরিয়েবল।
রোল্যান্ড

3
ব্যাখ্যা করেন কি একটি অবসান হল: stackoverflow.com/questions/4103750/...
dietbuddha

এছাড়াও দেখুন কি বন্ধ? সফ্টওয়্যারেনজেনারিং.স্ট্যাকেক্সচেঞ্জ
বি

বন্ধ এবং সাধারণ ব্যবহারের ক্ষেত্রে কী তা ব্যাখ্যা করে: ট্রুংক 18
এক্সপেরিয়েন্স

উত্তর:


743

পরিবর্তনশীল সুযোগ

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

function() {
  var a = 1;
  console.log(a); // works
}    
console.log(a); // fails

যদি আমি একটি স্থানীয় ভেরিয়েবল অ্যাক্সেস করার চেষ্টা করি তবে বেশিরভাগ ভাষাগুলি এটি বর্তমান স্কোপটিতে সন্ধান করবে, তারপরে মূল স্কোপগুলি না করে যতক্ষণ না তারা মূল স্কোপে পৌঁছায়।

var a = 1;
function() {
  console.log(a); // works
}    
console.log(a); // works

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

আমরা সাধারণত জিনিসগুলি কাজ করার আশা করি।

একটি ক্লোজার হল একটি স্থায়ী স্থানীয় পরিবর্তনশীল সুযোগ

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

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

এটি আমাদের ফাংশন বহনযোগ্যতা দেয়। আমরা যখন কোনও ফাংশনটিকে সম্পূর্ণ ভিন্ন প্রসঙ্গে কল করি, এমনকি আমরা পরে ফাংশনটি কল করি তখন ফাংশনটি প্রথমে স্কোপটিতে থাকার জন্য নির্ধারিত হওয়ার পরে স্কোপটিতে থাকা কোনও ভেরিয়েবলগুলি আমরা আশা করতে পারি।

উদাহরণ স্বরূপ

জাভাস্ক্রিপ্টে এখানে একটি খুব সাধারণ উদাহরণ যা দৃষ্টান্তটি তুলে ধরে:

outer = function() {
  var a = 1;
  var inner = function() {
    console.log(a);
  }
  return inner; // this returns a function
}

var fnc = outer(); // execute outer to get inner 
fnc();

এখানে আমি একটি ফাংশন মধ্যে একটি ফাংশন সংজ্ঞায়িত করেছি। অভ্যন্তরীণ ফাংশনটি বাইরের ফাংশনের সমস্ত স্থানীয় ভেরিয়েবলগুলিতে অ্যাক্সেস অর্জন করে a। ভেরিয়েবলটি aঅভ্যন্তরীণ ফাংশনের সুযোগে রয়েছে।

সাধারণত যখন কোনও ফাংশনটি প্রস্থান করে, তখন এর সমস্ত স্থানীয় ভেরিয়েবল উড়ে যায়। যাইহোক, আমরা যদি অভ্যন্তরীণ ফাংশনটি ফিরে পাই এবং এটিকে একটি পরিবর্তনশীল হিসাবে নির্ধারণ করি fncযাতে outerএটি প্রস্থান হওয়ার পরে অব্যাহত থাকে , সংজ্ঞায়িত হওয়ার সময় সুযোগগুলির মধ্যে থাকা সমস্ত ভেরিয়েবলগুলিও innerবজায় থাকে । ভেরিয়েবলটি aবন্ধ হয়ে গেছে - এটি বন্ধের মধ্যে রয়েছে।

নোট করুন যে ভেরিয়েবল aসম্পূর্ণরূপে ব্যক্তিগত fnc। এটি জাভাস্ক্রিপ্টের মতো ক্রিয়ামূলক প্রোগ্রামিং ভাষায় ব্যক্তিগত ভেরিয়েবলগুলি তৈরি করার একটি উপায়।

আপনি যেমন অনুমান করতে সক্ষম হবেন, যখন আমি fnc()এটি বলি তখন এর মান মুদ্রণ করে aযা "1"।

কোনও ভাষা বন্ধ না করে, ভেরিয়েবলটি aআবর্জনা সংগ্রহ করা এবং ফাংশনটি outerবের হওয়ার সময় ফেলে দেওয়া হত । কলিং এফএনসি একটি ত্রুটি ছুঁড়ে ফেলেছে কারণ এর aঅস্তিত্ব নেই।

জাভাস্ক্রিপ্টে, ভেরিয়েবলটি টিকে aথাকে কারণ ফাংশনটি প্রথম ঘোষণার সাথে সাথে ভেরিয়েবল স্কোপ তৈরি হয় এবং যতক্ষণ ফাংশনটি বিদ্যমান থাকে ততক্ষণ স্থায়ী হয়।

aএর ক্ষেত্রের অন্তর্গত outer। এর স্কোপটির স্কোপটিতে innerএকটি প্যারেন্ট পয়েন্টার রয়েছে outerfncএকটি চলক যা নির্দেশ করে inneraযতক্ষণ স্থির থাকে ততক্ষণ fncস্থির থাকে। aবন্ধের মধ্যে।


116
আমি ভেবেছিলাম এটি খুব সুন্দর এবং সহজে বোঝার উদাহরণ।
ব্যবহারকারী 12345613

16
দুর্দান্ত ব্যাখ্যাটির জন্য ধন্যবাদ, আমি অনেকগুলি দেখেছি তবে এই সময়টি আসলেই আমি পেয়েছি।
দিমিতর দিমিত্রভ

2
দ্বিতীয় থেকে শেষ অনুচ্ছেদে বর্ণিত জিকুয়েরির মতো লাইব্রেরিতে এটি কীভাবে কাজ করে তার উদাহরণ আমার থাকতে পারে? আমি পুরোপুরি বুঝতে পারিনি।
ডিপিএম

6
হাই জুব্বাত, হ্যাঁ, jquery.js খুলুন এবং প্রথম লাইনে একবার দেখুন। দেখবেন একটি ফাংশন খোলা আছে। এখন শেষে যান, আপনি উইন্ডোজ.জিকিউরি = উইন্ডোটি দেখতে পাবেন $ = jQuery। তারপরে ফাংশনটি বন্ধ হয়ে যায় এবং স্ব সম্পাদিত হয়। আপনার এখন $ ফাংশনে অ্যাক্সেস রয়েছে, যার ফলে বন্ধের মধ্যে সংজ্ঞায়িত অন্যান্য ফাংশনগুলিতে অ্যাক্সেস রয়েছে। এতে আপনার প্রশ্নের উত্তর হলো কি?
সুপারলুমিনিয়

4
ওয়েবে সেরা ব্যাখ্যা। আমি যা ভাবি তার চেয়ে সহজতর উপায়
মান্টিস

95

আমি একটি উদাহরণ দেব (জাভাস্ক্রিপ্টে):

function makeCounter () {
  var count = 0;
  return function () {
    count += 1;
    return count;
  }
}

var x = makeCounter();

x(); returns 1

x(); returns 2

...etc...

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

এখানে আমার কারিগর উদাহরণ আবার:

function add (a) {
  return function (b) {
    return a + b;
  }
}

var add3 = add(3);

add3(4); returns 7

আপনি যা দেখতে পাচ্ছেন তা হ'ল আপনি যখন প্যারামিটারটি অ্যাডের সাথে যুক্ত হন (যা 3 হয়) তখন মানটি ফিরে আসার ফাংশনটি বন্ধ করার মধ্যে থাকে যা আমরা অ্যাড 3 হিসাবে সংজ্ঞায়িত করছি। এইভাবে, আমরা যখন অ্যাড 3 বলি তখন এটি জানে যে সংযোজনটি সম্পাদনের জন্য কোনও মান কোথায় পাওয়া যায়।


4
আইডি কে, কোন ভাষাটি (সম্ভবত এফ #) আপনি উপরের ভাষায় ব্যবহার করেছেন। সিউডোকোডে দয়া করে উপরে উদাহরণ দিতে পারেন? এটি বুঝতে আমার খুব কষ্ট হচ্ছে।
ব্যবহারকারী


3
@ কাইলক্রোনিন দুর্দান্ত উদাহরণ, ধন্যবাদ। প্রশ্ন: "লুকানো মানটিকে ক্লোজার বলা হয়", বা "ফাংশন যা মানকে আড়াল করে তা হ'ল বন্ধ" বলা কি আরও সঠিক? অথবা "মানটি লুকানোর প্রক্রিয়াটি কি বন্ধ?" ধন্যবাদ!

2
@ রবার্টহিউম ভাল প্রশ্ন। শব্দার্থকভাবে, "ক্লোজার" শব্দটি কিছুটা অস্পষ্ট। আমার ব্যক্তিগত সংজ্ঞাটি হ'ল লুকানো মান এবং এর সাথে সংযুক্তি ফাংশনটির ব্যবহার উভয়ের সংমিশ্রণটি বন্ধ করে দেয়।
কাইল ক্রোনিন

1
@ কাইলক্রোনিন ধন্যবাদ - সোমবার আমার একটি স্কিম মধ্যমেয়াদী রয়েছে। :) আমার মাথায় "ক্লোজার" ধারণাটি শক্ত হতে চেয়েছিল। ওপির প্রশ্নের দুর্দান্ত উত্তরটি পোস্ট করার জন্য ধন্যবাদ!

58

কাইলের উত্তরটি বেশ ভাল। আমি মনে করি কেবলমাত্র অতিরিক্ত স্পষ্টতা হ'ল লম্বা ফাংশনটি তৈরি হওয়ার সময় বন্ধটি মূলত স্ট্যাকের একটি স্ন্যাপশট। তারপরে যখন ফাংশনটি পুনরায় সম্পাদন করা হয় তখন ফাংশনটি কার্যকর করার আগে স্ট্যাকটি সেই অবস্থায় ফিরিয়ে দেওয়া হয়। কাইল যেমন উল্লেখ করেছেন, countল্যাম্বদা ফাংশন সম্পাদন করে তখন সেই লুকানো মান ( ) পাওয়া যায়।


14
এটি কেবল স্ট্যাক নয় - এটি স্ট্যাক বা স্তূপে (বা উভয়) সঞ্চিত কিনা তা বিবেচনা না করেই এটি সংযুক্ত লেজিকাল স্কোপগুলি সংরক্ষণ করা হয়।
ম্যাট ফেনউইক

38

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

উদাহরণস্বরূপ, যখন আপনার একটি জাভাস্ক্রিপ্ট ফাংশন থাকবে:

function closed(x) {
  return x + 3;
}

এটি একটি বদ্ধ অভিব্যক্তি, কারণ এর মধ্যে উপস্থিত সমস্ত চিহ্নগুলিকে এটি সংজ্ঞায়িত করা হয়েছে (তাদের অর্থ পরিষ্কার হয়), সুতরাং আপনি এটি মূল্যায়ন করতে পারেন। অন্য কথায়, এটি স্বয়ংসম্পূর্ণ

তবে আপনার যদি এর মতো কোনও ফাংশন থাকে:

function open(x) {
  return x*y + 3;
}

এটি একটি প্রকাশ্য অভিব্যক্তি কারণ এর মধ্যে এমন চিহ্ন রয়েছে যা এর মধ্যে সংজ্ঞায়িত হয়নি। যথা y,। এই ফাংশনটি দেখার সময়, আমরা কী বলতে পারি yএবং এর অর্থ কী তা বলতে পারি না, আমরা এর মান জানি না, তাই আমরা এই অভিব্যক্তিটি মূল্যায়ন করতে পারি না। অর্থাৎ আমরা এর yমধ্যে কী বোঝাতে চাইছে তা না জানিয়ে আমরা এই ফাংশনটিকে কল করতে পারি না । এই yএকটি বলা হয় বিনামূল্যে পরিবর্তনশীল

এটি yএকটি সংজ্ঞার জন্য প্রার্থনা করে, তবে এই সংজ্ঞাটি ফাংশনের অংশ নয় - এটি এর "পার্শ্ববর্তী প্রসঙ্গে" ( পরিবেশ হিসাবেও পরিচিত ) এটি অন্য কোথাও সংজ্ঞায়িত হয় । কমপক্ষে আমরা এটাই প্রত্যাশা করছি: পি

উদাহরণস্বরূপ, এটি বিশ্বব্যাপী সংজ্ঞায়িত করা যেতে পারে:

var y = 7;

function open(x) {
  return x*y + 3;
}

অথবা এটি এমন কোনও ফাংশনে সংজ্ঞায়িত করা যেতে পারে যা এটি আবৃত করে:

var global = 2;

function wrapper(y) {
  var w = "unused";

  return function(x) {
    return x*y + 3;
  }
}

পরিবেশের যে অংশটি মুক্ত অর্থকে ভেরিয়েবলগুলি তাদের অর্থ বোঝায় তা হ'ল বন্ধ । এটিকে বলা হয়, কারণ এটি একটি মুক্ত অভিব্যক্তিটিকে তার সমস্ত বিনামূল্যে ভেরিয়েবলের জন্য এই নিখোঁজ সংজ্ঞা সরবরাহ করে একটি বন্ধ করে পরিণত করে , যাতে আমরা এটি মূল্যায়ন করতে পারি।

উপরের উদাহরণে, অভ্যন্তরীণ ফাংশন (যা আমাদের প্রয়োজন হয়নি বলে একটি নাম দেয়নি) এটি একটি প্রকাশ্য অভিব্যক্তি কারণ yএটির ভেরিয়েবলটি বিনামূল্যে - এর সংজ্ঞাটি ফাংশনটির বাইরে, ফাংশনে যা এটি আবৃত করে । পরিবেশ যে বেনামী ফাংশন জন্য ভেরিয়েবল সেট হল:

{
  global: 2,
  w: "unused",
  y: [whatever has been passed to that wrapper function as its parameter `y`]
}

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

{
  y: [whatever has been passed to that wrapper function as its parameter `y`]
}

পরিবেশে সংজ্ঞায়িত অন্য দুটি প্রতীক function ফাংশনটি বন্ধ করার অংশ নয় , কারণ এটি চালানোর প্রয়োজন নেই। এটি বন্ধ করার জন্য তাদের প্রয়োজন হয় না ।

এর পিছনে তত্ত্ব সম্পর্কে আরও এখানে: https://stackoverflow.com/a/36878651/434562

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

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


1
একটি উপমা যা এর সূচনাকারীদের সাহায্য করতে পারে তা হ'ল একটি ক্লোসারের সমস্ত আলগা প্রান্তকে সংযুক্ত করে , যা কোনও ব্যক্তি যখন বন্ধের সন্ধান করেন তখন তা করেন (বা এটি সমস্ত প্রয়োজনীয় রেফারেন্সগুলি সমাধান করে , বা ...)। ঠিক আছে, এটি আমাকে সেভাবে এটি ভাবতে সাহায্য করেছিল: ও)
উইল ক্র্যাফোর্ড

আমি বছরের পর বছর ধরে বন্ধের প্রচুর সংজ্ঞা পড়েছি, তবে আমি মনে করি এটি এখন পর্যন্ত আমার প্রিয়। আমি অনুমান করি যে আমাদের সকলের নিজের মতো করে মানসিকভাবে ম্যাপিংয়ের নিজস্ব পদ্ধতি রয়েছে এবং এটি আমার সাথে খুব জীভ।
জেসন এস 16

29

ক্লোজার হ'ল এমন একটি ফাংশন যা অন্য ফাংশনে রাষ্ট্রের উল্লেখ করতে পারে। উদাহরণস্বরূপ, পাইথনে এটি "অভ্যন্তরীণ" বন্ধটি ব্যবহার করে:

def outer (a):
    b = "variable in outer()"
    def inner (c):
        print a, b, c
    return inner

# Now the return value from outer() can be saved for later
func = outer ("test")
func (1) # prints "test variable in outer() 1

23

ক্লোজারগুলি বোঝার সুবিধার্থে এটি কীভাবে একটি পদ্ধতিগত ভাষায় প্রয়োগ করা যেতে পারে তা পরীক্ষা করে নেওয়া দরকারী। এই ব্যাখ্যাটি স্কিমের ক্লোজারগুলির সরল বাস্তবায়ন অনুসরণ করবে।

শুরু করতে, আমাকে অবশ্যই একটি নেমস্পেসের ধারণাটি প্রবর্তন করতে হবে। আপনি যখন কোনও স্কিম ইন্টারপ্রেটারে কোনও কমান্ড প্রবেশ করেন, তা অবশ্যই ভাবের বিভিন্ন চিহ্নের মূল্যায়ন করতে হবে এবং তাদের মান অর্জন করবে। উদাহরণ:

(define x 3)

(define y 4)

(+ x y) returns 7

সংজ্ঞায়িত এক্সপ্রেশন এক্স এর জন্য স্পটে 3 মান এবং y এর জন্য স্পটে 4 মান সংরক্ষণ করে। তারপরে আমরা যখন (+ xy) কল করি, দোভাষী তার নাম স্থানের মানগুলি সন্ধান করে এবং ক্রিয়াকলাপ সম্পাদন করতে সক্ষম হন এবং 7 ফিরিয়ে দিতে সক্ষম হন।

যাইহোক, স্কিমটিতে এমন ভাব রয়েছে যা আপনাকে অস্থায়ীভাবে একটি চিহ্নের মানকে ওভাররাইড করতে দেয়। এখানে একটি উদাহরণ:

(define x 3)

(define y 4)

(let ((x 5))
   (+ x y)) returns 9

x returns 3

লেট কীওয়ার্ডটি যা করে x এর সাথে নতুন নামের স্থানটি 5 মান হিসাবে চিহ্নিত করে আপনি দেখতে পাবেন যে এটি এখনও 4 দেখতে পাবে, যোগফলটি 9 হয়ে যাবে এবং আপনি আরও দেখতে পারবেন যে এক্সপ্রেশনটি শেষ হয়ে গেলে x আবার ফিরে আসে 3.. এই অর্থে, x স্থানীয় মান দ্বারা অস্থায়ীভাবে মুখোশ পেয়েছে।

পদ্ধতিগত এবং অবজেক্ট-ভিত্তিক ভাষার একটি একই ধারণা আছে। যখনই আপনি কোনও ফাংশনে ভেরিয়েবল ঘোষণা করেন যা বৈশ্বিক চলকের মতো একই নাম রাখে আপনি একই প্রভাব পান।

আমরা কীভাবে এটি বাস্তবায়ন করব? একটি সহজ উপায় একটি লিঙ্কযুক্ত তালিকার সাথে রয়েছে - মাথাতে নতুন মান থাকে এবং লেজটিতে পুরাতন নেমস্পেস থাকে। যখন আপনাকে একটি প্রতীক সন্ধান করতে হবে, আপনি মাথা থেকে শুরু করুন এবং আপনার লেজের নীচে থেকে কাজ করবেন work

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

(define x 3)

(define (plus-x y)
  (+ x y))

(let ((x 5))
  (plus-x 4)) returns ?

আমরা এক্সকে 3 এবং প্যারাম-এক্স এর পরামিতি, y, এবং এক্স এর মান হতে সংজ্ঞায়িত করি। পরিশেষে আমরা এমন একটি পরিবেশে প্লাস-এক্স কল করি যেখানে এক্স একটি নতুন এক্স দ্বারা মুখোশ পেয়েছে, এটির একটি মূল্য 5 we যদি আমরা কেবলমাত্র ক্রিয়াকলাপের জন্য ক্রিয়াকলাপের জন্য (+ xy), (+ xy) সংরক্ষণ করি, কারণ আমরা প্রসঙ্গে আছি এক্স এর 5 হওয়ার ফলে ফলাফলটি 9 হবে 9.

যাইহোক, স্কিম, কমন লিস্প এবং আরও অনেক ভাষায় লেক্সিকাল স্কোপিং বলে যার নাম রয়েছে - অপারেশন (+ xy) সংরক্ষণ করার পাশাপাশি আমরা সেই নির্দিষ্ট জায়গায় নেমস্পেসও সংরক্ষণ করি। এইভাবে, আমরা যখন মানগুলি সন্ধান করি তখন আমরা দেখতে পাব যে এক্স, এই প্রসঙ্গে, আসলে 3 is এটি একটি বন্ধ is

(define x 3)

(define (plus-x y)
  (+ x y))

(let ((x 5))
  (plus-x 4)) returns 7

সংক্ষেপে, ফাংশন সংজ্ঞা চলাকালীন সময়ে আমরা নেমস্পেসের রাজ্য সংরক্ষণ করতে একটি লিঙ্কযুক্ত তালিকা ব্যবহার করতে পারি, ঘের স্কোপগুলি থেকে ভেরিয়েবলগুলি অ্যাক্সেসের অনুমতি দেওয়ার পাশাপাশি বাকী অংশগুলিকে প্রভাবিত না করে স্থানীয়ভাবে একটি ভেরিয়েবলকে মুখোশ দেওয়ার সক্ষমতা সরবরাহ করে কার্যক্রম.


ঠিক আছে, আপনার উত্তরের জন্য ধন্যবাদ, আমি মনে করি যে অবশেষে বন্ধ হওয়ার বিষয়ে আমার কিছু ধারণা আছে। তবে একটি বড় প্রশ্ন রয়েছে: "ফাংশন সংজ্ঞা চলাকালীন আমরা নেমস্পেসের রাজ্য সংরক্ষণ করতে একটি লিঙ্কযুক্ত তালিকা ব্যবহার করতে পারি, ভেরিয়েবলগুলিতে অ্যাক্সেসের অনুমতি দিয়ে থাকি যা অন্যথায় আর সুযোগ নেই" " Why do we want to access variables that are out of scope? when we say let x = 5, we want x to be 5 and not 3. What is happening?
Lazer

@ লেজার: দুঃখিত, এই বাক্যটি খুব একটা বোঝায় না, তাই আমি এটি আপডেট করেছি। আমি আশা করি এটি এখন আরও সার্থক হয়ে উঠবে। এছাড়াও, লিঙ্কযুক্ত তালিকাকে বাস্তবায়নের বিশদ হিসাবে ভাবেন না (কারণ এটি অত্যন্ত অদক্ষ) তবে কীভাবে এটি করা যায় তা ধারণার সহজ উপায় হিসাবে।
কাইল ক্রোনিন

10

ক্লোজাররা কেন লাথি মারছে তার একটি বাস্তব বিশ্বের উদাহরণ এখানে ... এটি সরাসরি আমার জাভাস্ক্রিপ্ট কোডের বাইরে। আমাকে উদাহরণস্বরূপ।

Function.prototype.delay = function(ms /*[, arg...]*/) {
  var fn = this,
      args = Array.prototype.slice.call(arguments, 1);

  return window.setTimeout(function() {
      return fn.apply(fn, args);
  }, ms);
};

আপনি এখানে এটি কীভাবে ব্যবহার করবেন তা এখানে:

var startPlayback = function(track) {
  Player.play(track);  
};
startPlayback(someTrack);

এখন আপনি কল্পনা করুন যে আপনি প্লেব্যাকটি বিলম্ব শুরু করতে চান যেমন উদাহরণস্বরূপ 5 সেকেন্ড পরে এই কোড স্নিপেট চালানোর পরে। ভাল এটি দিয়ে সহজ delayএবং এটি বন্ধ:

startPlayback.delay(5000, someTrack);
// Keep going, do other things

আপনি যখন এমএস delayদিয়ে কল করেন 5000, প্রথম স্নিপেটটি চলে এবং এটি বন্ধ হওয়ার সাথে সাথে পাস হওয়া যুক্তিগুলিকে সংরক্ষণ করে। তারপরে 5 সেকেন্ড পরে, যখন setTimeoutকলব্যাক হয়, বন্ধটি এখনও সেই পরিবর্তনশীলগুলি বজায় রাখে, তাই এটি মূল পরামিতিগুলির সাহায্যে মূল ফাংশনটিকে কল করতে পারে।
এটি কারিরিং বা ফাংশন সজ্জা এক প্রকারের।

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


1
এটি লক্ষ করা উচিত যে ভাষা বা হোস্ট অবজেক্টগুলিকে প্রসারিত করা সাধারণত একটি খারাপ জিনিস হিসাবে বিবেচিত হয় কারণ তারা বিশ্বব্যাপী নেমস্পেসের অংশ
জোন কুক

9

নিখরচায় ভেরিয়েবলযুক্ত ফাংশনগুলিকে খাঁটি ফাংশন বলে।

এক বা একাধিক ফ্রি ভেরিয়েবল যুক্ত ফাংশনগুলিকে ক্লোজার বলা হয়।

var pure = function pure(x){
  return x 
  // only own environment is used
}

var foo = "bar"

var closure = function closure(){
  return foo 
  // foo is a free variable from the outer environment
}

src: https://leanpub.com/javascriptallongesix/read#leanpub-auto-if-function-without-free-variables-are-pure-are-closures-impure


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

সত্যিই আমার কোন আইডিয়া নেই । এজন্য স্ট্যাকওভারফ্লো চুষছে। শুধু আমার উত্তরের উত্স দেখুন। এর সাথে কে তর্ক করতে পারে?
সাউন্ডোগোগি

তাই চুষে না এবং আমি কখনই "ফ্রি ভেরিয়েবল" শব্দটি শুনিনি
কাই

বিনামূল্যে ভেরিয়েবলের উল্লেখ না করে ক্লোজার সম্পর্কে কথা বলা শক্ত hard শুধু তাদের চেহারা। স্ট্যান্ডার্ড সিএস পরিভাষা।
ComDubh

"এক বা একাধিক ফ্রি ভেরিয়েবল যুক্ত ফাংশনগুলিকে ক্লোজার বলা হয়" যদিও সঠিক সংজ্ঞা নয় - ক্লোজারগুলি সর্বদা প্রথম-শ্রেণীর অবজেক্ট।
ComDubh

7

TL; ড

ক্লোজার হ'ল একটি ফাংশন এবং এর স্কোপটি একটি ভেরিয়েবলকে (বা হিসাবে ব্যবহৃত) নির্ধারিত হয়। সুতরাং, নাম বন্ধ: সুযোগ এবং ফাংশনটি অন্য কোনও সত্তার মতোই বদ্ধ এবং ব্যবহৃত হয় used

গভীরতা উইকিপিডিয়া শৈলী ব্যাখ্যা

উইকিপিডিয়া অনুসারে, একটি বন্ধটি হ'ল:

প্রথম শ্রেণীর ফাংশন সহ ভাষাগুলিতে স্কোপড নেম বাইন্ডিং বাস্তবায়নের কৌশল iques

ওটার মানে কি? কিছু সংজ্ঞা বিবেচনা করা যাক।

এই উদাহরণটি ব্যবহার করে ক্লোজার এবং অন্যান্য সম্পর্কিত সংজ্ঞাটি ব্যাখ্যা করব:

function startAt(x) {
    return function (y) {
        return x + y;
    }
}

var closure1 = startAt(1);
var closure2 = startAt(5);

console.log(closure1(3)); // 4 (x == 1, y == 3)
console.log(closure2(3)); // 8 (x == 5, y == 3)

প্রথম শ্রেণির কাজ

মূলত এর অর্থ আমরা অন্য সত্তার মতোই ফাংশনগুলি ব্যবহার করতে পারি । আমরা এগুলি সংশোধন করতে পারি, তাদেরকে আর্গুমেন্ট হিসাবে পাস করতে পারি, ফাংশন থেকে তাদের ফিরিয়ে দিতে পারি বা ভেরিয়েবলের জন্য তাদের নির্ধারণ করতে পারি। প্রযুক্তিগতভাবে বলতে গেলে, তারা প্রথম-শ্রেণীর নাগরিক , সুতরাং নাম: প্রথম শ্রেণির ফাংশন।

উপরের উদাহরণে, startAtএকটি ( বেনামে ) ফাংশন প্রদান করে যা ফাংশনটি নির্ধারিত হয় closure1এবং closure2। আপনি যখন দেখেন যে জাভাস্ক্রিপ্ট অন্যান্য সংস্থার (প্রথম শ্রেণির নাগরিক) ঠিক তেমন কাজ করে।

নাম বাঁধাই

নাম বাঁধাই দুঃশ্চিন্তা সম্পর্কে কোন ডেটা একটি পরিবর্তনশীল (শনাক্তকারী) রেফারেন্স । সুযোগটি এখানে সত্যই গুরুত্বপূর্ণ, কারণ এটি সেই জিনিস যা নির্ধারণ করবে যে কোনও বাঁধাই কীভাবে সমাধান করা হয়।

উপরের উদাহরণে:

  • অভ্যন্তরীণ বেনামে ফাংশন এর সুযোগ, yআবদ্ধ 3
  • ইন startAtএর সুযোগ xআবদ্ধ হয় 1বা 5(অবসান উপর নির্ভর করে)।

বেনামে ফাংশনটির সুযোগের ভিতরে, xকোনও মানের সাথে আবদ্ধ নয়, সুতরাং এটি একটি উপরের ( startAtগুলি) স্কোপে সমাধান করা দরকার।

লেক্সিকাল স্কোপিং

উইকিপিডিয়া যেমন বলেছে , সুযোগটি:

একটি কম্পিউটার প্রোগ্রামের অঞ্চল যেখানে বাঁধাই বৈধ: যেখানে নামটি সত্ত্বাকে বোঝাতে ব্যবহার করা যেতে পারে

দুটি কৌশল রয়েছে:

  • লেক্সিকাল (স্ট্যাটিক) স্কোপিং: একটি ভেরিয়েবলের সংজ্ঞাটি এতে থাকা ব্লক বা ফাংশনটি অনুসন্ধান করে সমাধান করা হয়, তবে যদি তা বাহ্যিক ব্লকটি অনুসন্ধান করতে ব্যর্থ হয় ইত্যাদি on
  • ডায়নামিক স্কোপিং: কলিং ফাংশনটি অনুসন্ধান করা হয়, তারপরে যে কলটি সেই কলিং ফাংশনটিকে ডেকে আনে এবং তাই কল স্ট্যাকের অগ্রগতি হয়।

আরো ব্যাখ্যার জন্য দেখুন, এই প্রশ্ন খুঁজে বার করো এবং উইকিপিডিয়া কটাক্ষপাত করা

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

মোড়ানো (বন্ধ হওয়া) আপ

আমাদের উদাহরণস্বরূপ, আমরা যখন কল করি তখন startAtএটি একটি (প্রথম শ্রেণির) ফাংশনটি ফিরিয়ে দেয় যা নির্ধারিত হবে closure1এবং closure2এভাবে একটি ক্লোজার তৈরি করা হবে, কারণ উত্তীর্ণ ভেরিয়েবলগুলি 1এবং 'স্কোপ'-এর 5মধ্যে সংরক্ষণ করা startAtহবে, এটি প্রত্যাবর্তনকৃত দ্বারা আবদ্ধ হবে বেনামে ফাংশন। যখন আমরা এই বেনাম ফাংশনটির মাধ্যমে কল করবclosure1closure2 একই আর্গুমেন্ট ( 3) এর এবং , তখন এর মানটি yতাত্ক্ষণিকভাবে পাওয়া যাবে (এটি সেই ফাংশনের প্যারামিটার হিসাবে) তবে xবেনামে ফাংশনের সুযোগে আবদ্ধ হয় না, তাই রেজুলেশন অব্যাহত থাকে (বর্ণনাক্রমে) উপরের ফাংশন স্কোপ (এটি বন্ধে সংরক্ষণ করা হয়েছিল) যেখানে xপাওয়া যায় 1বা হয় না bound5। এখন আমরা সংমিশ্রনের জন্য সমস্ত কিছু জানি যাতে ফলাফলটি ফেরত দেওয়া যায়, তারপরে মুদ্রণ করা যায়।

এখন আপনার ক্লোজারগুলি এবং তারা কীভাবে আচরণ করে তা বুঝতে হবে যা জাভাস্ক্রিপ্টের একটি মৌলিক অংশ।

সংবাহন

ওহ, এবং কারিরিং সম্পর্কে কী তা আপনি শিখেছেন : আপনি একাধিক পরামিতিগুলির সাথে একটি ফাংশন ব্যবহার না করে কোনও ক্রিয়াকলাপের প্রতিটি যুক্তি পাস করার জন্য ফাংশন (ক্লোজার) ব্যবহার করেন।


5

অবসান জাভাস্ক্রিপ্টের একটি বৈশিষ্ট্য যেখানে কোনও ফাংশনের নিজস্ব স্কোপ ভেরিয়েবলের অ্যাক্সেস, বহিরাগত ফাংশন ভেরিয়েবলের অ্যাক্সেস এবং গ্লোবাল ভেরিয়েবলের অ্যাক্সেস রয়েছে।

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

অভ্যন্তরীণ ফাংশনটি তার নিজস্ব ক্ষেত্র, বহিরাগত ফাংশনটির সুযোগ এবং বৈশ্বিক সুযোগে সংজ্ঞায়িত ভেরিয়েবলগুলি অ্যাক্সেস করতে পারে। এবং বাইরের ফাংশনটি তার নিজস্ব সুযোগ এবং বৈশ্বিক স্কোপে সংজ্ঞায়িত ভেরিয়েবলটি অ্যাক্সেস করতে পারে।

বন্ধের উদাহরণ :

var globalValue = 5;

function functOuter() {
  var outerFunctionValue = 10;

  //Inner function has access to the outer function value
  //and the global variables
  function functInner() {
    var innerFunctionValue = 5;
    alert(globalValue + outerFunctionValue + innerFunctionValue);
  }
  functInner();
}
functOuter();  

আউটপুট 20 হবে যা এর অভ্যন্তরীণ ফাংশনটির নিজস্ব ভেরিয়েবল, বহিরাগত ফাংশন ভেরিয়েবল এবং গ্লোবাল ভেরিয়েবল মানের যোগফল।


4

একটি সাধারণ পরিস্থিতিতে, ভেরিয়েবলগুলি স্কোপিং বিধি দ্বারা আবদ্ধ হয়: স্থানীয় ভেরিয়েবলগুলি কেবল নির্ধারিত ফাংশনটির মধ্যেই কাজ করে। সুবিধার জন্য সাময়িকভাবে এই নিয়ম ভাঙ্গার একটি উপায় los

def n_times(a_thing)
  return lambda{|n| a_thing * n}
end

উপরের কোডে, lambda(|n| a_thing * n}বন্ধ কারণa_thing ল্যাম্বদা (একটি বেনাম ফাংশন স্রষ্টা) দ্বারা উল্লেখ করা হয়েছে।

এখন, যদি আপনি ফলস্বর ভেরিয়েবলের ফলাফল বেনামে ফাংশন রাখেন।

foo = n_times(4)

foo সাধারণ স্কোপিংয়ের নিয়ম ভেঙে অভ্যন্তরীণভাবে 4 ব্যবহার শুরু করবে।

foo.call(3)

রিটার্ন 12


2

সংক্ষেপে, ফাংশন পয়েন্টারটি প্রোগ্রাম কোড বেসের একটি অবস্থানের জন্য কেবলমাত্র পয়েন্টার (প্রোগ্রামের কাউন্টারের মতো)। যেখানে বন্ধ = ফাংশন পয়েন্টার + স্ট্যাক ফ্রেম


1

Closure একটি ক্লোজার হল একটি উপ-প্রোগ্রাম এবং রেফারেন্সিং পরিবেশ যেখানে এটি সংজ্ঞায়িত হয়েছিল

- প্রোগ্রামটির যেকোন স্বেচ্ছাসেবী স্থান থেকে সাবপ্রগ্রামটি কল করা যেতে পারে তবে রেফারেন্সিং পরিবেশ প্রয়োজন

- একটি স্থির-স্কোপযুক্ত ভাষা যা নেস্টেড সাবপ্রগ্রামগুলিকে অনুমতি দেয় না, বন্ধ হওয়ার দরকার নেই

- বন্ধকরণগুলি কেবল তখনই প্রয়োজন হয় যদি কোনও উপ-প্রকল্প নীড়ের স্কোপে ভেরিয়েবল অ্যাক্সেস করতে পারে এবং এটিকে যে কোনও জায়গা থেকে ডেকে আনা যেতে পারে

- ক্লোজারগুলিকে সমর্থন করার জন্য, বাস্তবায়নের জন্য কিছু ভেরিয়েবলের সীমাহীন পরিমাণ সরবরাহ করা প্রয়োজন হতে পারে (কারণ একটি উপ-প্রকল্পটি ননলোকাল ভেরিয়েবল অ্যাক্সেস করতে পারে যা সাধারণত আর জীবিত থাকে না)

উদাহরণ

function makeAdder(x) {
return function(y) {return x + y;}
}
var add10 = makeAdder(10);
var add5 = makeAdder(5);
document.write(″add 10 to 20: ″ + add10(20) +
″<br />″);
document.write(″add 5 to 20: ″ + add5(20) +
″<br />″);

0

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

local old_dofile = dofile

function dofile( filename )
  if filename == nil then
    error( 'Can not use default of stdin.' )
  end

  old_dofile( filename )
end

পুরাতন_ডোফাইলের মানটি অদৃশ্য হয়ে যায় যখন এই কোডের ব্লকটি এর সুযোগটি শেষ করে (কারণ এটি স্থানীয়), তবে মানটি একটি বন্ধের সাথে আবদ্ধ করা হয়েছে, সুতরাং নতুন পুনরায় সংজ্ঞায়িত ডফিল ফাংশন এটি অ্যাক্সেস করতে পারে, বা পরিবর্তিত হিসাবে ফাংশন সহ একটি অনুলিপি সংরক্ষিত রয়েছে 'upvalue'।


0

লুয়া.অর্গ.এর থেকে :

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


0

আপনি যদি জাভা বিশ্ব থেকে থাকেন তবে আপনি ক্লাসের সদস্য ফাংশনের সাথে ক্লোজারের তুলনা করতে পারেন। এই উদাহরণটি দেখুন

var f=function(){
  var a=7;
  var g=function(){
    return a;
  }
  return g;
}

ফাংশনটি gএকটি বন্ধকরণ: gবন্ধ হয়ে যায় aSo সুতরাং gকোনও সদস্য ফাংশনের aসাথে তুলনা করা যেতে পারে, শ্রেণির ক্ষেত্রের সাথে এবং একটি শ্রেণীর সাথে ফাংশনটির তুলনা করা যেতে পারে f


0

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

Listing 2-18:
    function outerFunction(arg) {
     var variableInOuterFunction = arg;

     function bar() {
             console.log(variableInOuterFunction); // Access a variable from the outer scope
     }
     // Call the local function to demonstrate that it has access to arg
     bar(); 
    }
    outerFunction('hello closure!'); // logs hello closure!

সূত্র: http://index-of.es/Varios/Baraarat%20Ali%20Syed%20(auth.)-Beginning%20Node.js-Apress%20(2014).pdf


0

আরও গভীরভাবে ক্লোজারটি বোঝার জন্য দয়া করে নীচের কোডটি দেখুন:

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

এখানে কি আউটপুট হবে? 0,1,2,3,4এটি 5,5,5,5,5বন্ধ হওয়ার কারণে হবে না

তাহলে কীভাবে সমাধান হবে? উত্তর নীচে:

       for(var i=0; i< 5; i++){
           (function(j){     //using IIFE           
                setTimeout(function(){
                               console.log(j);
                           },1000);
            })(i);          
        }

আমাকে সহজভাবে ব্যাখ্যা করতে দাও, যখন কোনও ফাংশন তৈরি না হয় যতক্ষণ না এটি 1 ম কোডে লুপের জন্য 5 বার কল করা হয় তবে তা অবিলম্বে বলা হয় না যখন এটি বলা হয় 1 সেকেন্ডের পরে এবং এটি এটি অ্যাসিনক্রোনাস তাই লুপ শেষ হওয়ার আগে এবং স্টোরের মান 5 var i তে এবং শেষ পর্যন্ত setTimeoutফাংশনটি পাঁচবার চালিত করে মুদ্রণ করুন5,5,5,5,5

এখানে এটি কীভাবে আইআইএফই অর্থাত্ তাত্ক্ষণিক ইনভোকিং ফাংশন এক্সপ্রেশন ব্যবহার করে সমাধান করা হয়

       (function(j){  //i is passed here           
            setTimeout(function(){
                           console.log(j);
                       },1000);
        })(i);  //look here it called immediate that is store i=0 for 1st loop, i=1 for 2nd loop, and so on and print 0,1,2,3,4

আরও তথ্যের জন্য, দয়া করে বন্ধ বোঝার জন্য নির্বাহের প্রসঙ্গটি বুঝুন।

  • লেট (ES6 বৈশিষ্ট্য) ব্যবহার করে এটি সমাধান করার জন্য আরও একটি সমাধান রয়েছে তবে উপরের ফণার নীচে ফাংশনটি কাজ করা হয়

     for(let i=0; i< 5; i++){           
         setTimeout(function(){
                        console.log(i);
                    },1000);                        
     }
    
    Output: 0,1,2,3,4
    

=> আরও ব্যাখ্যা:

স্মৃতিতে, যখন লুপের জন্য এক্সিকিউট করা ছবি নীচের মত করুন:

লুপ 1)

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

লুপ 2)

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

লুপ 3)

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

লুপ 4)

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

লুপ 5)

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

এখানে আমি মৃত্যুদন্ড কার্যকর করা হয় না এবং তারপরে সম্পূর্ণ লুপের পরে, আমি মেমরিতে 5 মান সংরক্ষণ করি তবে এর স্কোপটি শিশুদের ফাংশনে সর্বদা দৃশ্যমান থাকে তাই যখন ফাংশনটি কার্যকর setTimeoutহয় পাঁচবারের মধ্যে এটি মুদ্রিত হয়5,5,5,5,5

সুতরাং উপরোক্ত ব্যাখ্যা হিসাবে আইআইএফই ব্যবহারটি সমাধান করুন।


আপনার উত্তরের জন্য ধন্যবাদ. আপনি কোডটি ব্যাখ্যা থেকে আলাদা করলে এটি আরও পঠনযোগ্য হবে। (কোড নয় এমন লাইনগুলি ইনডেন্ট করবেন না)
ইএমবি

0

কার্য়িং করা: এটি আপনাকে কেবল কোনও যুক্তিগুলির একটি উপসেটে পাস করে কোনও ফাংশন আংশিকভাবে মূল্যায়ন করতে দেয়। এই বিবেচনা:

function multiply (x, y) {
  return x * y;
}

const double = multiply.bind(null, 2);

const eight = double(4);

eight == 8;

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

function apple(x){
   function google(y,z) {
    console.log(x*y);
   }
   google(7,2);
}

apple(3);

// the answer here will be 21

0

বন্ধ খুব সহজ। আমরা এটি নিম্নলিখিত হিসাবে বিবেচনা করতে পারি: বন্ধ = ফাংশন + এর লেজিকাল পরিবেশ

নিম্নলিখিত ফাংশন বিবেচনা করুন:

function init() {
    var name = “Mozilla”;
}

উপরের ক্ষেত্রে বন্ধ কী হবে? ফাংশন init () এবং এর লেজিকাল পরিবেশে নামগুলি যেমন ভেরিয়েবল। বন্ধ = init () + নাম

অন্য ফাংশন বিবেচনা করুন:

function init() {
    var name = “Mozilla”;
    function displayName(){
        alert(name);
}
displayName();
}

এখানে কি বন্ধ হবে? অভ্যন্তরীণ ফাংশন বাইরের ফাংশনের ভেরিয়েবল অ্যাক্সেস করতে পারে। displayName () প্যারেন্ট ফাংশন, init () এ ঘোষিত চলক নামটি অ্যাক্সেস করতে পারে। তবে ডিসপ্লেনেমে একই স্থানীয় ভেরিয়েবলগুলি উপস্থিত থাকলে তাদের ব্যবহার করা হবে।

সমাপ্তি 1: আরম্ভ ফাংশন + (নাম ভেরিয়েবল + ডিসপ্লেনাম () ফাংশন) -> লেজিকাল স্কোপ

সমাপ্তি 2: ডিসপ্লেনাম ফাংশন + (নাম পরিবর্তনশীল) -> লেজিকাল স্কোপ


0

বন্ধগুলি রাষ্ট্রের সাথে জাভাস্ক্রিপ্ট সরবরাহ করে।

প্রোগ্রামিংয়ে স্টেটের অর্থ জিনিসগুলি স্মরণ করা।

উদাহরণ

var a = 0;

a = a + 1; // => 1
a = a + 1; // => 2
a = a + 1; // => 3

উপরের ক্ষেত্রে, রাষ্ট্রটি "এ" ভেরিয়েবলে সংরক্ষণ করা হয়। আমরা বেশ কয়েকবার 1 এ "এ" যুক্ত করে অনুসরণ করি। আমরা কেবল এটি করতে পারি কারণ আমরা মানটি "মনে রাখতে" সক্ষম হয়েছি। রাষ্ট্রধারক, "ক", স্মৃতিতে সেই মানটি ধারণ করে।

প্রায়শই প্রোগ্রামিং ভাষায়, আপনি জিনিসগুলি নজর রাখতে চান, তথ্য মনে রাখতে এবং পরবর্তী সময়ে এটিকে অ্যাক্সেস করতে চান।

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

উদাহরণ

class Bread {
  constructor (weight) {
    this.weight = weight;
  }

  render () {
    return `My weight is ${this.weight}!`;
  }
}

"রেন্ডার" পদ্ধতির মধ্যে থেকে কীভাবে আমরা "ওজন" অ্যাক্সেস করতে পারি? ভাল, রাষ্ট্র ধন্যবাদ। ব্রেড শ্রেণীর প্রতিটি উদাহরণ "স্টেট" থেকে এটি পড়ার মাধ্যমে নিজের ওজন রেন্ডার করতে পারে, এটি মেমরির একটি জায়গা যেখানে আমরা সেই তথ্য সংরক্ষণ করতে পারি।

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

উদাহরণ

var n = 0;
var count = function () {
  n = n + 1;
  return n;
};

count(); // # 1
count(); // # 2
count(); // # 3

উপরের উদাহরণটি একটি পরিবর্তনশীল সহ "রাষ্ট্রের রাখার" লক্ষ্য অর্জন করেছিল। এটা অসাধারণ! তবে ভেরিয়েবল ("রাষ্ট্র" ধারক) এখন উন্মুক্ত হওয়ার সাথে এর অসুবিধাও রয়েছে। আমরা আরও ভাল করতে পারি আমরা বন্ধ ব্যবহার করতে পারি।

উদাহরণ

var countGenerator = function () {
  var n = 0;
  var count = function () {
    n = n + 1;
    return n;
  };

  return count;
};

var count = countGenerator();
count(); // # 1
count(); // # 2
count(); // # 3

এটি চমৎকার.

এখন আমাদের "কাউন্ট" ফাংশনটি গণনা করতে পারে। এটি কেবল এটি করতে সক্ষম কারণ এটি "রাষ্ট্র" ধরে রাখতে পারে। এই ক্ষেত্রে রাষ্ট্রটি পরিবর্তনশীল "এন"। এই পরিবর্তনশীলটি এখন বন্ধ। সময় এবং স্থান বন্ধ। সময়মতো কারণ আপনি কখনই এটি পুনরুদ্ধার করতে, এটিকে পরিবর্তন করতে, এটিকে একটি মূল্য নির্ধারণ করতে বা এটির সাথে সরাসরি ইন্টারঅ্যাক্ট করতে পারবেন না। স্পেসে কারণ এটি ভৌগোলিকভাবে "কাউন্টজেনেটর" ফাংশনের মধ্যে নেস্টেড।

কেন এই চমত্কার? কারণ অন্য কোনও পরিশীলিত এবং জটিল সরঞ্জামকে জড়িত না করে (উদাহরণস্বরূপ শ্রেণি, পদ্ধতি, উদাহরণ, ইত্যাদি) আমরা সক্ষম করতে পারি 1. গোপন করতে পারি 2. দূরত্ব থেকে নিয়ন্ত্রণ 2

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

জাভাস্ক্রিপ্ট এর সরলতার মধ্যে সত্যই আশ্চর্যজনক।

বন্ধ কেন এটি হয় তার একটি বড় অংশ।


0

আপনার রেফারেন্সের জন্য গ্রোভির একটি সাধারণ উদাহরণ:

def outer() {
    def x = 1
    return { -> println(x)} // inner
}
def innerObj = outer()
innerObj() // prints 1
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.