javascript এর - কিভাবে জাভাস্ক্রিপ্ট কাজ বন্ধ করে?




ফাংশন কোড (25)

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

এবং হ্যাঁ, আমি এমনকি এটি 6 বছরের বৃদ্ধকে সুপারিশ করব - 6 বছর বয়সী যদি বন্ধের বিষয়ে শিখতে পারে তবে এটি যৌক্তিক এবং নিবন্ধে দেওয়া সংক্ষিপ্ত এবং সহজ ব্যাখ্যাটি বোঝার জন্য প্রস্তুত ।

আপনি কীভাবে ধারণার ধারণাগুলির সাথে জাভাস্ক্রিপ্ট বন্ধের ব্যাখ্যা করবেন (উদাহরণস্বরূপ ফাংশন, ভেরিয়েবল এবং এর মত), তবে নিজের বন্ধন বুঝতে পারে না?

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


একটি বন্ধন একটি বস্তুর মত অনেক। যখনই আপনি ফাংশন কল করেন তা তাত্ক্ষণিক পায়।

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

একটি পরিবর্তনশীল আপনি বন্ধ যদি অন্তর্ভুক্ত করা হয়

  1. সঙ্গে এটি বরাদ্দ করা var foo=1; অথবা
  2. শুধু লেখো var foo;

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

একটি ক্লোজার এটি spawned যে ফাংশন রানটাইম outlives। যদি অন্যান্য ফাংশনগুলি সেগুলি সংজ্ঞায়িত করা হয় এমন বন্ধ / স্কোপের বাইরে ফেলে দেয় (উদাহরণস্বরূপ ফেরত মান হিসাবে), তখন সেগুলি বন্ধ করে দেওয়ার বিষয়টি অব্যাহত থাকবে ।

উদাহরণ

function example(closure) {
  // define somevariable to live in the closure of example
  var somevariable = 'unchanged';

  return {
    change_to: function(value) {
      somevariable = value;
    },
    log: function(value) {
      console.log('somevariable of closure %s is: %s',
        closure, somevariable);
    }
  }
}

closure_one = example('one');
closure_two = example('two');

closure_one.log();
closure_two.log();
closure_one.change_to('some new value');
closure_one.log();
closure_two.log();

আউটপুট

somevariable of closure one is: unchanged
somevariable of closure two is: unchanged
somevariable of closure one is: some new value
somevariable of closure two is: unchanged

বন্ধ উইকিপিডিয়া :

কম্পিউটার বিজ্ঞানে, একটি ফাংশনটি সেই ফাংশনের ননলোকাল নামগুলির (বিনামূল্যে ভেরিয়েবল) জন্য একটি রেফারেন্সিং পরিবেশের সাথে এক ফাংশন।

টেকনিক্যালি, JavaScript , প্রতিটি ফাংশন একটি বন্ধ । এটি সর্বদা পার্শ্ববর্তী সুযোগ সংজ্ঞায়িত ভেরিয়েবল একটি অ্যাক্সেস আছে।

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

ক্লোজারগুলি প্রায়শই কিছু লুকানো ব্যক্তিগত তথ্য সহ ফাংশন তৈরির জন্য ব্যবহৃত হয় (তবে এটি সর্বদা কেস নয়)।

var db = (function() {
    // Create a hidden object, which will hold the data
    // it's inaccessible from the outside.
    var data = {};

    // Make a function, which will provide some access to the data.
    return function(key, val) {
        if (val === undefined) { return data[key] } // Get
        else { return data[key] = val } // Set
    }
    // We are calling the anonymous surrounding function,
    // returning the above inner function, which is a closure.
})();

db('x')    // -> undefined
db('x', 1) // Set x to 1
db('x')    // -> 1
// It's impossible to access the data object itself.
// We are able to get or set individual it.

EMS

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


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

function sing(person) {

    var firstPart = "There was " + person + " who swallowed ";

    var fly = function() {
        var creature = "a fly";
        var result = "Perhaps she'll die";
        alert(firstPart + creature + "\n" + result);
    };

    var spider = function() {
        var creature = "a spider";
        var result = "that wiggled and jiggled and tickled inside her";
        alert(firstPart + creature + "\n" + result);
    };

    var bird = function() {
        var creature = "a bird";
        var result = "How absurd!";
        alert(firstPart + creature + "\n" + result);
    };

    var cat = function() {
        var creature = "a cat";
        var result = "Imagine That!";
        alert(firstPart + creature + "\n" + result);
    };

    fly();
    spider();
    bird();
    cat();
}

var person="an old lady";

sing(person);

নির্দেশাবলীর

তথ্য: তথ্য ঘটনা একটি সংগ্রহ। এটি সংখ্যা, শব্দ, পরিমাপ, পর্যবেক্ষণ বা এমনকি জিনিস বিবরণ হতে পারে। আপনি এটি স্পর্শ করতে পারেন না, এটি গন্ধ বা এটি স্বাদ। আপনি এটি লিখতে পারেন, কথা বলতে এবং এটি শুনতে পারেন। আপনি কম্পিউটার ব্যবহার করে স্পর্শ গন্ধ এবং স্বাদ তৈরি করতে এটি ব্যবহার করতে পারেন । এটি কোড ব্যবহার করে একটি কম্পিউটার দ্বারা দরকারী করা যেতে পারে।

কোড: উপরে লেখা সব কোড কোড বলা হয় । এটা জাভাস্ক্রিপ্ট লেখা হয়।

জাভাস্ক্রিপ্ট: জাভাস্ক্রিপ্ট একটি ভাষা। ইংরেজি বা ফরাসি বা চীনা মত ভাষা। কম্পিউটার এবং অন্যান্য ইলেকট্রনিক প্রসেসর দ্বারা বোঝা যায় এমন অনেকগুলি ভাষা রয়েছে। একটি কম্পিউটার দ্বারা জাভাস্ক্রিপ্ট বোঝার জন্য এটি একটি দোভাষী প্রয়োজন। কল্পনা করুন যে একজন শিক্ষক যিনি শুধুমাত্র রাশিয়ান কথা বলে তা স্কুলে আপনার ক্লাস শেখান। যখন শিক্ষক বলছেন "все садятся", ক্লাস বুঝবে না। কিন্তু সৌভাগ্যক্রমে আপনার ক্লাসে একটি রাশিয়ান শিক্ষার্থী রয়েছে যারা সবাই বলে যে "সবাই বসে আছে" - তাই আপনি সবাই করেন। ক্লাস একটি কম্পিউটারের মত এবং রাশিয়ান ছাত্র ইন্টারপ্রেটার হয়। জাভাস্ক্রিপ্টের জন্য সবচেয়ে সাধারণ দোভাষীকে ব্রাউজার বলা হয়।

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

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

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

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

একটি ফাংশন সাধারণত একটি নাম, বন্ধনী এবং ধনুর্বন্ধনী আছে। এটার মত:

function cookMeal() {  /*  STUFF INSIDE THE FUNCTION  */  }

নোট করুন /*...*/এবং //ব্রাউজার দ্বারা কোড পড়া বন্ধ করুন।

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

PARENTHESES: "প্যানথেসেসস" বা ()ফ্যাক্টরিতে তথ্যের প্যাকেট পাঠানোর জন্য জাভাস্ক্রিপ্ট ফাংশন ফ্যাক্টরির দরজা বা রাস্তার একটি পোস্ট বাক্সের অক্ষর বাক্স। কখনও কখনও পোস্টবক্সটি উদাহরণস্বরূপ চিহ্নিত করা যেতে পারে cookMeal(you, me, yourFriend, myFriend, fridge, dinnerTime), কোন ক্ষেত্রে আপনি জানেন যে কোন ডেটা আপনাকে দিতে হবে।

ব্র্যাকেস: "ব্রাসেস" যা {}আমাদের কারখানাগুলির রঙিন জানালা। কারখানার ভিতর থেকে আপনি দেখতে পারেন, কিন্তু বাইরে থেকে আপনি দেখতে পারবেন না।

দীর্ঘ কোড উদাহরণ উপরে

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

function sing(person) {  /* STUFF INSIDE THE FUNCTION */  }

তাই এই ফাংশন গাওয়া সঙ্গে কিছু করতে পারে, এবং একটি ব্যক্তির সম্পর্কে কিছু তথ্য প্রয়োজন হতে পারে। এটা ভিতরে তথ্য আছে যে তথ্য সঙ্গে কিছু করতে।

এখন, ফাংশন পরে গান () , কোড শেষে কাছাকাছি লাইন

var person="an old lady";

VARIABLE: অক্ষর var "পরিবর্তনশীল" জন্য দাঁড়ানো। একটি পরিবর্তনশীল একটি খামখেয়াল মত। বাইরে এই খামে "ব্যক্তি" চিহ্নিত করা হয়। অভ্যন্তরে এটি আমাদের ফাংশনের প্রয়োজনীয় তথ্য সহ কাগজের একটি স্লিপ রয়েছে, কিছু অক্ষর এবং স্পেস একসঙ্গে স্ট্রিং (এটি একটি স্ট্রিং বলা হয়) এর সাথে যুক্ত হয়েছে যা একটি ফ্রেজ "পুরানো ভদ্রমহিলা" পড়ে। আমাদের লিফলে অন্যান্য ধরণের জিনিস থাকতে পারে যেমন সংখ্যা (পূর্ণসংখ্যা বলা), নির্দেশাবলী (ফাংশন বলা হয়), তালিকা ( অ্যারে বলা হয় )। কারণ এই পরিবর্তনশীল সমস্ত ধনুর্বন্ধনীগুলির বাইরে লেখা হয়েছে {}, এবং আপনি যখন ব্রাসিসের ভিতরে আছেন তখন আপনি টিন্ড উইন্ডোগুলির মাধ্যমে দেখতে পারেন, এই পরিবর্তনশীল কোডটি যে কোনও জায়গায় দেখা যেতে পারে। আমরা এটি একটি 'গ্লোবাল পরিবর্তনশীল' কল।

বিশ্বব্যাপী পরিবর্তনশীল: ব্যক্তি , একটি বিশ্বব্যাপী পরিবর্তনশীল, যার অর্থ যে আপনি যদি থেকে "একটি পুরানো ভদ্রমহিলা" থেকে "একটি যুবক" এর মান পরিবর্তন করেন, ব্যক্তি যতক্ষণ না আপনি এটিকে পুনরায় পরিবর্তন করার সিদ্ধান্ত নেন এক যুবকের হচ্ছে রাখা এবং করবে অন্য কোন ফাংশন কোড দেখতে পারেন যে এটি একটি যুবক। টিপুন F12বোতাম বা একটি ব্রাউজার বিকাশকারীর কনসোল খুলুন এবং "ব্যক্তি" টাইপ তা দেখতে এই মান হয় বিকল্পগুলি সেটিংস দিকে তাকাও। টাইপ করুন person="a young man"আবার দেখতে এটি পরিবর্তিত হয়েছে এটিকে পরিবর্তন করতে এবং তারপর টাইপ করুন "ব্যক্তি"।

এর পর আমরা লাইন আছে

sing(person);

এই লাইন ফাংশন কল করা হয়, যেমন এটি একটি কুকুর কলিং ছিল

"চলো Sing , 'এস পেতে ব্যক্তি !"

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

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

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

ক্লোজারগুলি সবাই জানে যে গান () ফাংশনের ভেরিয়েবলটি প্রথমভাগকে বলা হয়, কারণ তারা তাদের রঙিন উইন্ডো থেকে দেখতে পারে।

বন্ধ পর লাইন আসা

fly();
spider();
bird();
cat();

গান () ফাংশন তাদের দেওয়া ক্রিয়ায় প্রতিটি ফাংশন কল করবে। তারপর গান () ফাংশন এর কাজ করা হবে।


লেখক Closures চমত্কার বন্ধ ব্যাখ্যা করেছেন কেন আমরা তাদের প্রয়োজন ব্যাখ্যা এবং LexicalEnvironment যা বন্ধ বুঝতে প্রয়োজনীয় ব্যাখ্যা।
এখানে সারাংশ আছে:

যদি একটি পরিবর্তনশীল অ্যাক্সেস করা হয়, কিন্তু এটি স্থানীয় নয়? এখানকার মত:

এই ক্ষেত্রে, দোভাষী বাইরের LexicalEnvironmentবস্তুর পরিবর্তনশীল খুঁজে বের করে ।

প্রক্রিয়া দুটি ধাপ রয়েছে:

  1. প্রথম, যখন একটি ফাংশন F তৈরি হয়, এটি খালি জায়গায় তৈরি হয় না। একটি বর্তমান LexicalEnvironment বস্তু আছে। উপরের ক্ষেত্রে, এটি উইন্ডো (একটি ফাংশন তৈরির সময় অনির্ধারিত)।

যখন একটি ফাংশন তৈরি হয়, তখন এটি একটি লুকানো সম্পত্তি পায়, [[স্কোপ]], যা বর্তমান লেক্সিক্যাল এনভায়রনমেন্টকে উল্লেখ করে।

একটি পরিবর্তনশীল পড়া হয়, কিন্তু কোথাও পাওয়া যাবে না, একটি ত্রুটি উত্পন্ন হয়।

নেস্টেড ফাংশন

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

সুতরাং, ফাংশন জি, অ্যাক্সেস জি এবং একটি।

বন্ধ

বাহ্যিক ফাংশন সমাপ্ত হওয়ার পরে একটি নেস্টেড ফাংশন লাইভ থাকতে পারে:

লেক্সিকাল এনভায়রনমেন্টগুলি চিহ্নিত করা হচ্ছে:

যেমনটি আমরা দেখি, this.sayব্যবহারকারীর বস্তুর একটি সম্পত্তি, তাই এটি ব্যবহারকারীর সম্পন্ন হওয়ার পরেই চলতে থাকে।

এবং যদি আপনি মনে করেন, কখন this.sayতৈরি হয়, এটি (প্রতিটি ফাংশন হিসাবে) this.say.[[Scope]]বর্তমান লেক্সিক্যাল এনভায়রনমেন্টের অভ্যন্তরীণ রেফারেন্স পায় । সুতরাং, বর্তমান ব্যবহারকারীর সঞ্চালনের লেক্সিক্যাল এনভায়রনমেন্ট মেমরিতে থাকে। ব্যবহারকারীর সমস্ত ভেরিয়েবল তার বৈশিষ্ট্যও রয়েছে, তাই তারাও সাবধানে রাখা হয়, সাধারণত সাধারণত জাঙ্ক করা হয় না।

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

সংক্ষেপ:

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

এই একটি বন্ধ বলা হয়।


কিভাবে আমি কাজ বন্ধ কিভাবে ব্যাখ্যা একটি ইন্টারেক্টিভ জাভাস্ক্রিপ্ট টিউটোরিয়াল রাখা। একটি বন্ধ কি?

এখানে উদাহরণ একটি:

var create = function (x) {
    var f = function () {
        return x; // We can refer to x here!
    };
    return f;
};
// 'create' takes one argument, creates a function

var g = create(42);
// g is a function that takes no arguments now

var y = g();
// y is 42 here

Closures ব্যাখ্যা করা কঠিন কারণ তারা কিছু আচরণ কাজ করার জন্য ব্যবহার করা হয় যে সবাই intuitively যাই হোক না কেন কাজ করার আশা। আমি তাদের ব্যাখ্যা করার সর্বোত্তম উপায় খুঁজে পেয়েছি (এবং যেভাবে তারা যা শিখেছে তা আমি শিখেছি) তাদের ছাড়া পরিস্থিতি কল্পনা করা:

    var bind = function(x) {
        return function(y) { return x + y; };
    }
    
    var plus5 = bind(5);
    console.log(plus5(3));

জাভাস্ক্রিপ্ট বন্ধ না জানলে কি হবে? শুধু তার পদ্ধতির শরীরের দ্বারা শেষ লাইনে কলটিকে প্রতিস্থাপন করুন (যা মূলত ফাংশন কল করে) এবং আপনি পান:

console.log(x + 3);

এখন, x এর সংজ্ঞা কোথায়? আমরা বর্তমান সুযোগ এটি সংজ্ঞায়িত না। একমাত্র সমাধান plus5 তার সুযোগ (বা বরং, তার পিতামাতার সুযোগ) বহন করা যাক। এই ভাবে, x ভাল সংজ্ঞায়িত এবং এটি মান 5 থেকে আবদ্ধ।


জাভাস্ক্রিপ্ট বন্ধ জন্য beginners

মরিস অন ট্যু দ্বারা জমা, 2006-02-21 10:19। সম্প্রদায় থেকে সম্পাদিত।

বন্ধন ম্যাজিক হয় না

এই পৃষ্ঠা বন্ধ করার ব্যাখ্যা দেয় যাতে একটি প্রোগ্রামার তাদের বুঝতে পারে - জাভাস্ক্রিপ্ট কোড ব্যবহার করে। এটা গুরু বা কার্যকরী প্রোগ্রামারদের জন্য নয়।

কোর ধারণা grokked একবার closos বুঝতে কঠিন হয় না । যাইহোক, তারা কোনো তাত্ত্বিক বা একাডেমিক ভিত্তিক ব্যাখ্যা পড়া দ্বারা বুঝতে অসম্ভব!

এই নিবন্ধটি মূলধারার ভাষাতে কিছু প্রোগ্রামিং অভিজ্ঞতা সহ প্রোগ্রামারদের উদ্দেশ্যে, এবং নিম্নলিখিত জাভাস্ক্রিপ্ট ফাংশনটি কে পড়তে পারে:

function sayHello(name) {
  var text = 'Hello ' + name;
  var say = function() { console.log(text); }
  say();
}
sayHello('Joe');

দুই সংক্ষিপ্ত সারসংক্ষেপ

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

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

একটি বন্ধ করার একটি উদাহরণ

নিম্নলিখিত কোড একটি ফাংশন একটি রেফারেন্স ফেরত:

function sayHello2(name) {
  var text = 'Hello ' + name; // Local variable
  var say = function() { console.log(text); }
  return say;
}
var say2 = sayHello2('Bob');
say2(); // logs "Hello Bob"

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

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

উপরের কোডটি বন্ধ আছে কারণ বেনামী ফাংশন function() { console.log(text); } function() { console.log(text); } অন্য ফাংশনের ভিতরে ঘোষণা করা হয়েছে, এই উদাহরণে sayHello2() । জাভাস্ক্রিপ্টে, যদি আপনি অন্য ফাংশনের ভিতরে function কীওয়ার্ডটি ব্যবহার করেন, তবে আপনি একটি বন্ধকরণ তৈরি করছেন।

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

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

function() { console.log(text); } // Output of say2.toString();

say2.toString() এর আউটপুট এ খুঁজছেন, আমরা কোড পরিবর্তনশীল text বোঝায় যে দেখতে পারেন। বেনামী ফাংশন এমন text উল্লেখ করতে পারে যা মানটি 'Hello Bob' ধারণ করে, কারণ স্থানীয় sayHello2() গোপনভাবে বন্ধ করে রাখা হয়েছে।

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

আরো উদাহরণ

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

উদাহরণ 3

এই উদাহরণটি দেখায় যে স্থানীয় ভেরিয়েবল কপি করা হয় না - তারা রেফারেন্স দ্বারা রাখা হয়। বাইরের ফাংশন বিদ্যমান থাকলেও স্ম্যাক ফ্রেম স্মৃতিতে জীবিত থাকে!

function say667() {
  // Local variable that ends up within closure
  var num = 42;
  var say = function() { console.log(num); }
  num++;
  return say;
}
var sayNumber = say667();
sayNumber(); // logs 43

উদাহরণ 4

সমস্ত তিনটি গ্লোবাল ফাংশন একই ক্লোজারে একটি সাধারণ রেফারেন্স আছে কারণ তারা সমস্ত setupSomeGlobals() থেকে একটি কলের মধ্যে ঘোষণা করা হয়।

var gLogNumber, gIncreaseNumber, gSetNumber;
function setupSomeGlobals() {
  // Local variable that ends up within closure
  var num = 42;
  // Store some references to functions as global variables
  gLogNumber = function() { console.log(num); }
  gIncreaseNumber = function() { num++; }
  gSetNumber = function(x) { num = x; }
}

setupSomeGlobals();
gIncreaseNumber();
gLogNumber(); // 43
gSetNumber(5);
gLogNumber(); // 5

var oldLog = gLogNumber;

setupSomeGlobals();
gLogNumber(); // 42

oldLog() // 5

তিনটি ফাংশন একই বন্ধের অ্যাক্সেস ভাগ করেছে - setupSomeGlobals() এর স্থানীয় ভেরিয়েবলগুলি যখন তিনটি ফাংশন সংজ্ঞায়িত করা হয়েছে।

উল্লেখ্য যে উপরে উল্লেখিত উদাহরণে, যদি আপনি setupSomeGlobals() আবার কল করেন, তবে একটি নতুন বন্ধন (স্ট্যাক-ফ্রেম!) তৈরি করা হয়। পুরনো gLogNumber , gIncreaseNumber , gSetNumber ভেরিয়েবলগুলি নতুন ফাংশনগুলির নতুন ফাংশনগুলির সাথে ওভাররাইট করা হয়। (জাভাস্ক্রিপ্টে, যখনই আপনি অন্য ফাংশনের ভেতর একটি ফাংশন ঘোষণা করেন, ভিতরে ফাংশন (গুলি) বার বার ফাংশন বলা হয় / পুনরায় তৈরি হয়।)

উদাহরণ 5

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

function sayAlice() {
    var say = function() { console.log(alice); }
    // Local variable that ends up within closure
    var alice = 'Hello Alice';
    return say;
}
sayAlice()();// logs "Hello Alice"

ট্রিকিক: এটিও লক্ষ্য করুন যে say পরিবর্তনশীলও বন্ধের ভিতরে রয়েছে এবং এটি অন্য কোনও ফাংশন দ্বারা অ্যাক্সেস করা যেতে পারে যা sayAlice() মধ্যে ঘোষণা করা যেতে পারে, অথবা এটি অভ্যন্তরীণ ফাংশনের মধ্যে পুনরাবৃত্তি করা যেতে পারে।

উদাহরণ 6

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

এই উদাহরণটি বোঝার জন্য আপনাকে জাভাস্ক্রিপ্টে "পরিবর্তনশীল উত্তোলন" বৈশিষ্ট্যটি বুঝতে হবে।

function buildList(list) {
    var result = [];
    for (var i = 0; i < list.length; i++) {
        var item = 'item' + i;
        result.push( function() {console.log(item + ' ' + list[i])} );
    }
    return result;
}

function testList() {
    var fnlist = buildList([1,2,3]);
    // Using j only to help prevent confusion -- could use i.
    for (var j = 0; j < fnlist.length; j++) {
        fnlist[j]();
    }
}

 testList() //logs "item2 undefined" 3 times

লাইন result.push( function() {console.log(item + ' ' + list[i])} ফলাফল অ্যারেতে তিনবার একটি বেনামী ফাংশনের একটি রেফারেন্স যুক্ত করে। আপনি যদি বেনামী ফাংশনগুলির সাথে এত পরিচিত না হন তবে মনে রাখবেন এটা মত:

pointer = function() {console.log(item + ' ' + list[i])};
result.push(pointer);

উল্লেখ্য, যখন আপনি উদাহরণটি চালান, "item2 undefined" তিনবার লগ করা হয়! এটি পূর্বের উদাহরণগুলির মতই, buildList জন্য স্থানীয় ভেরিয়েবলের জন্য শুধুমাত্র এক ক্লোজার buildList (যা result , i এবং item )। যখন বেনামী ফাংশন লাইন fnlist[j]() তে বলা হয়; তারা সবাই একই একক বন্ধন ব্যবহার করে, এবং তারা i এবং item জন্য এক ক্লোজারের মধ্যে বর্তমান মানটি ব্যবহার করে (যেখানে i 3 মান রয়েছে, কারণ লুপটি সম্পন্ন হয়েছে এবং item 'item2' মান রয়েছে)। উল্লেখ্য আমরা 0 থেকে সূচী করছি তাই item item2 একটি মান আছে। এবং আই ++ i মান 3 বৃদ্ধি হবে।

কী ঘটবে তা দেখতে সহায়ক হতে পারে যখন ভেরিয়েবল item একটি ব্লক স্তরের ঘোষণাটি var শব্দ দ্বারা ফাংশন-স্কোপেড পরিবর্তনশীল ঘোষণার পরিবর্তে (শব্দের সাহায্যে) ব্যবহার করা হয়। যে পরিবর্তন করা হয়, তারপর অ্যারে result প্রতিটি বেনামী ফাংশন নিজস্ব বন্ধ আছে; যখন উদাহরণ চালানো হয় আউটপুট নিম্নরূপ:

item0 undefined
item1 undefined
item2 undefined

যদি পরিবর্তনশীল i পরিবর্তে var ব্যবহার করে সংজ্ঞায়িত করা হয়, তারপর আউটপুট হয়:

item0 1
item1 2
item2 3

উদাহরণ 7

এই চূড়ান্ত উদাহরণে, প্রধান ফাংশনে প্রতিটি কল একটি পৃথক বন্ধ করে তোলে।

function newClosure(someNum, someRef) {
    // Local variables that end up within closure
    var num = someNum;
    var anArray = [1,2,3];
    var ref = someRef;
    return function(x) {
        num += x;
        anArray.push(num);
        console.log('num: ' + num +
            '; anArray: ' + anArray.toString() +
            '; ref.someVar: ' + ref.someVar + ';');
      }
}
obj = {someVar: 4};
fn1 = newClosure(4, obj);
fn2 = newClosure(5, obj);
fn1(1); // num: 5; anArray: 1,2,3,5; ref.someVar: 4;
fn2(1); // num: 6; anArray: 1,2,3,6; ref.someVar: 4;
obj.someVar++;
fn1(2); // num: 7; anArray: 1,2,3,5,7; ref.someVar: 5;
fn2(2); // num: 8; anArray: 1,2,3,6,8; ref.someVar: 5;

সারাংশ

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

চূড়ান্ত পয়েন্ট:

  • যখনই আপনি অন্য function ভিতরে function ব্যবহার করেন, একটি বন্ধকরণ ব্যবহার করা হয়।
  • যখনই আপনি একটি ফাংশনের ভিতরে eval() ব্যবহার করেন, একটি বন্ধকরণ ব্যবহার করা হয়। আপনার লেখা পাঠ্যটি ফাংশনের স্থানীয় ভেরিয়েবলগুলি উল্লেখ করতে পারে এবং eval মধ্যে আপনি eval('var foo = …') ব্যবহার করে নতুন স্থানীয় ভেরিয়েবল তৈরি করতে পারেন।
  • যখন আপনি একটি ফাংশনের ভিতরে new Function(…) ( ফাংশন কন্সট্রাকটর ) ব্যবহার করেন, তখন এটি বন্ধ হয়ে যায় না। (নতুন ফাংশন বাইরের ফাংশনের স্থানীয় ভেরিয়েবলগুলি উল্লেখ করতে পারে না।)
  • জাভাস্ক্রিপ্টে একটি ক্লোজার সমস্ত স্থানীয় ভেরিয়েবলগুলির একটি অনুলিপি রাখার মতো, যেমন একটি ফাংশন বের হওয়ার পরেও।
  • এটি সম্ভবত ভাল মনে করা যে একটি বন্ধকরণ সবসময় একটি ফাংশন একটি এন্ট্রি তৈরি করা হয়, এবং স্থানীয় ভেরিয়েবল যে বন্ধ করার জন্য যোগ করা হয়।
  • স্থানীয় ভেরিয়েবলের একটি নতুন সেট প্রতিটি সময় বন্ধ করার সাথে একটি ফাংশন রাখা হয় (দেওয়া হয় যে ফাংশনটির ভিতরে একটি ফাংশন ঘোষণা রয়েছে এবং এর ভিতরে যে ফাংশনটির ভিতরের ফাংশনটি ফেরত দেওয়া হয় বা কোনও উপায়ে বাইরের রেফারেন্সটি রাখা হয় )।
  • দুটি ফাংশন তারা একই উত্স পাঠ্য আছে দেখতে পারে, কিন্তু তাদের 'লুকানো' বন্ধ করার কারণে সম্পূর্ণ ভিন্ন আচরণ আছে। আমি মনে করি না জাভাস্ক্রিপ্ট কোড আসলে কোনও ফাংশন রেফারেন্সটি বন্ধ আছে কিনা তা খুঁজে বের করতে পারে।
  • যদি আপনি কোন গতিশীল সোর্স কোড সংশোধন করার চেষ্টা করছেন (উদাহরণস্বরূপ: myFunction = Function(myFunction.toString().replace(/Hello/,'Hola')); ), যদি আমার myFunction বন্ধ থাকে তবে এটি কাজ করবে না ( অবশ্যই, আপনি রানটাইম এ সোর্স কোড স্ট্রিং প্রতিস্থাপন করছেন এমনকি চিন্তা করবে না, ...)।
  • ফাংশনগুলির মধ্যে ফাংশন ঘোষণাগুলির মধ্যে ফাংশন ঘোষণাগুলি পাওয়া সম্ভব এবং mdash, এবং আপনি একাধিক স্তরে ক্লোজার পেতে পারেন।
  • আমার মনে হয় সাধারণত বন্ধ হয়ে যাওয়া ফাংশনগুলির সাথে ফাংশন উভয়টির জন্য একটি শব্দ। মনে রাখবেন যে আমি এই প্রবন্ধে সেই সংজ্ঞাটি ব্যবহার করি না!
  • আমি জাভাস্ক্রিপ্ট মধ্যে বন্ধ সাধারণত কার্যকরী ভাষা পাওয়া যায় যে থেকে পৃথক।

লিংক

ধন্যবাদ

আপনি যদি কেবলমাত্র বন্ধের (এখানে বা অন্য কোথাও!) শিখেছেন তবে আমি আপনার কাছ থেকে যেকোন মতামত সম্পর্কে আগ্রহী যা এই নিবন্ধটিকে আরও পরিষ্কার করে তুলতে পারে। Morrisjohns.com একটি ইমেইল পাঠান (morris_closure @)। দয়া করে নোট করুন যে আমি জাভাস্ক্রিপ্টে কোন গুরু নই - না বন্ধেরও।

Morris দ্বারা মূল পোস্ট ইন্টারনেট আর্কাইভ পাওয়া যাবে।


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

জাভাস্ক্রিপ্ট ফাংশন জন্য গোপন ব্যক্তিগত ভেরিয়েবল হয়

var parent = function() {
 var name = "Mary"; // secret
}

প্রতিবার যখন আপনি এটি কল করেন, স্থানীয় পরিবর্তনশীল "নাম" তৈরি হয় এবং "মেরি" নাম দেওয়া হয়। এবং প্রতিটি সময় ফাংশন থেকে বেরিয়ে আসে পরিবর্তনশীল হারিয়ে এবং নাম ভুলে যাওয়া হয়।

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

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

var parent = function() {
  var name = "Mary";
  var child = function(childName) {
    // I can also see that "name" is "Mary"
  }
}

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

কিন্তু দু: খিত ব্যাপার হল, যদি শিশুটিও তার পিতামাতার ফাংশনটির ব্যক্তিগত পরিবর্তনশীল হয় তবে পিতা-মাতার শেষ হয়ে গেলেও মরতে হবে এবং গোপনগুলি তাদের সাথে মরে যাবে।

তাই বেঁচে থাকার জন্য, সন্তানের খুব দেরি হওয়ার আগেই চলে যেতে হবে

var parent = function() {
  var name = "Mary";
  var child = function(childName) {
    return "My name is " + childName  +", child of " + name; 
  }
  return child; // child leaves the parent ->
}
var child = parent(); // < - and here it is outside 

এবং এখন, যদিও মেরি "আর চলছে না", তবুও তার স্মৃতি হারিয়ে যায় না এবং তার সন্তান সবসময় তার নাম ও অন্যান্য গোপনীয়তাগুলি তাদের একসাথে সময় ভাগ করে নেবে।

তাই, যদি আপনি "এলিস" বাচ্চাকে কল করেন, সে সাড়া দেবে

child("Alice") => "My name is Alice, child of Mary"

যে সব বলতে আছে।


আপনি উপর একটি ঘুম হচ্ছে এবং আপনি দান আমন্ত্রণ। ড্যানকে এক এক্সবক্স কন্ট্রোলার আনতে বলুন।

ড্যান ড। ড্যান ড। দলের কতগুলো কন্ট্রোলার আনা হয়েছিল?

function sleepOver(howManyControllersToBring) {

    var numberOfDansControllers = howManyControllersToBring;

    return function danInvitedPaul(numberOfPaulsControllers) {
        var totalControllers = numberOfDansControllers + numberOfPaulsControllers;
        return totalControllers;
    }
}

var howManyControllersToBring = 1;

var inviteDan = sleepOver(howManyControllersToBring);

// The only reason Paul was invited is because Dan was invited. 
// So we set Paul's invitation = Dan's invitation.

var danInvitedPaul = inviteDan(howManyControllersToBring);

alert("There were " + danInvitedPaul + " controllers brought to the party.");

আমি জানি ইতিমধ্যে প্রচুর সমাধান আছে, কিন্তু আমি মনে করি এই ছোট এবং সহজ স্ক্রিপ্টটি ধারণাটি প্রদর্শন করতে উপকারী হতে পারে:

// makeSequencer will return a "sequencer" function
var makeSequencer = function() {
    var _count = 0; // not accessible outside this function
    var sequencer = function () {
        return _count++;
    }
    return sequencer;
}

var fnext = makeSequencer();
var v0 = fnext();     // v0 = 0;
var v1 = fnext();     // v1 = 1;
var vz = fnext._count // vz = undefined

একটি ছয় বছর বয়সী জন্য একটি উত্তর (তিনি একটি ফাংশন কি এবং একটি পরিবর্তনশীল কি, এবং কোন তথ্য আছে তা অনুমান):

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

function the_closure() {
  var x = 4;
  return function () {
    return x; // Here, we look back inside the_closure for the value of x
  }
}

var myFn = the_closure();
myFn(); //=> 4

এটি ব্যাখ্যা করার আরেকটি সহজ উপায় সুযোগের পরিপ্রেক্ষিতে:

যেকোন সময় আপনি একটি বৃহত্তর সুযোগের মধ্যে একটি ছোট সুযোগ তৈরি করেন, ছোট সুযোগ সর্বদা বৃহত্তর সুযোগের মধ্যে দেখতে সক্ষম হবে।


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

বন্ধ অধিকার অধিকার:

console.log('CLOSURES DONE RIGHT');

var arr = [];

function createClosure(n) {
    return function () {
        return 'n = ' + n;
    }
}

for (var index = 0; index < 10; index++) {
    arr[index] = createClosure(index);
}

for (var index in arr) {
    console.log(arr[index]());
}
  • উপরের কোড createClosure(n)লুপ প্রতি পুনরাবৃত্তি মধ্যে আহ্বান করা হয়। মনে রাখবেন যে, আমি পরিবর্তনশীল নামে nহাইলাইট করতে এটি একটি যে নতুন একটি নতুন ফাংশন সুযোগ সৃষ্টি পরিবর্তনশীল এবং একই পরিবর্তনশীল হিসাবে নয় indexযা বাইরের সুযোগ আবদ্ধ হয়।

  • এটি একটি নতুন সুযোগ তৈরি করে এবং nসেই সুযোগের সাথে আবদ্ধ হয়; এর মানে আমাদের 10 টি পৃথক স্কোপ রয়েছে, প্রতিটি পুনরাবৃত্তির জন্য একটি।

  • createClosure(n) যে সুযোগ মধ্যে এন ফিরে যে একটি ফাংশন ফেরত।

  • প্রতিটি সুযোগের মধ্যে nযখন createClosure(n)এটি আহ্বান করা হয়েছিল তখন যা মূল্য ছিল তার সাথে আবদ্ধ ছিল তাই যে নেস্টেড ফাংশনটি ফেরত পাওয়া যায় সেটি সর্বদা nযেটি যখন বলা createClosure(n)হয়েছিল তার মানটি ফেরত দেবে ।

বন্ধন ভুল হয়েছে:

console.log('CLOSURES DONE WRONG');

function createClosureArray() {
    var badArr = [];

    for (var index = 0; index < 10; index++) {
        badArr[index] = function () {
            return 'n = ' + index;
        };
    }
    return badArr;
}

var badArr = createClosureArray();

for (var index in badArr) {
    console.log(badArr[index]());
}
  • উপরের কোডে লুপটি createClosureArray()ফাংশনের মধ্যে সরানো হয়েছে এবং ফাংশনটি এখন সম্পন্ন হওয়া অ্যারেটি ফেরত দেয়, যা প্রথম নজরে আরো স্বজ্ঞাত মনে হয়।

  • কোনটি সুস্পষ্ট নাও হতে পারে যেহেতু createClosureArray()লুপের প্রতিটি পুনরাবৃত্তির জন্য একের পরিবর্তে এই ফাংশনের জন্য শুধুমাত্র একটি সুযোগ তৈরি করা হয়।

  • এই ফাংশনের মধ্যে একটি পরিবর্তনশীল নাম indexসংজ্ঞায়িত করা হয়। লুপ রান এবং অ্যারে ফাংশন যোগ করে যে index। নোট যে ফাংশন indexমধ্যে সংজ্ঞায়িত করা হয় createClosureArrayযা শুধুমাত্র একবার একবার আহ্বান পায়।

  • কারন createClosureArray()ফাংশনের মধ্যে শুধুমাত্র একটি সুযোগ ছিল, শুধুমাত্র সেই সুযোগের মধ্যে indexএকটি মানের সাথে আবদ্ধ। অন্য কথায়, প্রতিটি সময় লুপ মান পরিবর্তন করে index, এটি যে সুযোগের মধ্যে এটি উল্লেখ করে এমন সবকিছুর জন্য এটি পরিবর্তন করে।

  • অ্যারে যোগ করা সমস্ত ফাংশন indexমূল প্যারামিটার থেকে একই পরিবর্তনশীলটি ফেরত দেয় যেখানে এটি 10 ​​টি ভিন্ন পরিবর্তে 10 টি পৃথক স্কোপের উদাহরণ হিসাবে প্রথম সংজ্ঞায়িত করে। শেষ ফলাফল হল সমস্ত 10 ফাংশন একই সুযোগ থেকে একই পরিবর্তনশীল ফিরে।

  • লুপ শেষ হওয়ার পরে এবং indexশেষ মান পরিবর্তন করা হয় 10 হয়, তাই অ্যারে যোগ করা প্রতিটি ফাংশন একক indexপরিবর্তনশীলের মান প্রদান করে যা এখন 10 সেট করে।

ফল

CLOSURES DONE RIGHT
N = 0
এন = 1
এন = 2
এন = 3
এন = 4
এন = 5
এন = 6
এন = 7
এন = 8
এন = 9

CLOSURES DONE WRONG
N = 10
এন = 10
এন = 10
এন = 10
এন = 10
এন = 10
এন = 10
এন = 10
এন = 10
এন = 10


আপনি একটি 5 বছর বয়সী বন্ধ করার ব্যাখ্যা করতে পারেন? *

আমি এখনও গুগল এর ব্যাখ্যা খুব ভাল কাজ করে এবং সংক্ষিপ্ত হয় মনে হয়:

/*
*    When a function is defined in another function and it
*    has access to the outer function's context even after
*    the outer function returns.
*
* An important concept to learn in JavaScript.
*/

function outerFunction(someNum) {
    var someString = 'Hey!';
    var content = document.getElementById('content');
    function innerFunction() {
        content.innerHTML = someNum + ': ' + someString;
        content = null; // Internet Explorer memory leak for DOM reference
    }
    innerFunction();
}

outerFunction(1);​

* এসি # প্রশ্ন


সম্ভবত ছয় বছর বয়স্কদের মধ্যে সবচেয়ে বেশি আতঙ্কজনক তবে কিছুটা উদাহরণ যা আমাকে জাভাস্ক্রিপ্টে বন্ধ করার ধারণা তৈরি করতে সাহায্য করেছে।

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

function outerFunction() {
    var outerVar = "monkey";
    
    function innerFunction() {
        alert(outerVar);
    }
    
    innerFunction();
}

outerFunction();

ALERT: বানর

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

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

function outerFunction() {
    var outerVar = "monkey";
    
    function innerFunction() {
        return outerVar;
    }
    
    return innerFunction;
}

var referenceToInnerFunction = outerFunction();
alert(referenceToInnerFunction());

ALERT: বানর

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

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

function outerFunction() {
    var outerVar = "monkey";
    
    function innerFunction() {
        return outerVar;
    }
    
    return innerFunction;
}

var referenceToInnerFunction = outerFunction();
alert(referenceToInnerFunction());

outerFunction = null;
alert(referenceToInnerFunction());

ALERT: বানর ALERT: বানর

কিন্তু এভাবে কেমন হয়? কিভাবে referenceToInnerFunction এখনও outerVar এর মান জানাতে পারে যে outerFunction নিল সেট করা হয়েছে?

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

//////////

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

function outerFunction() {
    var outerVar = "monkey";
    
    function innerFunction() {
        alert(outerVar);
    }
    
    outerVar = "gorilla";

    innerFunction();
}

outerFunction();

ALERT: গরিলা

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


Dlaliberte দ্বারা প্রথম বিন্দু জন্য উদাহরণ:

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

var i;
function foo(x) {
    var tmp = 3;
    i = function (y) {
        console.log(x + y + (++tmp));
    }
}
foo(2);
i(3);

আচ্ছা, 6 বছর বয়সী সন্তানের সাথে কথা বলার জন্য, আমি সম্ভবত নিম্নলিখিত সংস্থার ব্যবহার করব।

কল্পনা করুন - আপনি পুরো বাড়িতে আপনার ছোট ভাই ও বোনদের সাথে খেলছেন, এবং আপনি আপনার খেলনা নিয়ে ঘুরে বেড়াচ্ছেন এবং তাদের কয়েকজনকে আপনার বড় ভাইয়ের ঘরে নিয়ে এসেছেন। কিছুদিন পরেই তোমার ভাই স্কুলে ফিরে এল এবং তার ঘরে ঢুকল, আর সে ভিতরে প্রবেশ করলো, তাই এখন তুমি সরাসরি সরাসরি সেখানে থাকা খেলনাগুলো অ্যাক্সেস করতে পারনি। কিন্তু আপনি দরজা খোঁচা এবং খেলনা জন্য আপনার ভাইয়ের জিজ্ঞাসা করতে পারে। এই খেলনা বন্ধ করা হয় ; আপনার ভাই এটা আপনার জন্য তৈরি, এবং তিনি বাইরের সুযোগ এখন হয় ।

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

একটি উন্নত সন্তানের জন্য আমি নিম্নলিখিত মত কিছু করা হবে। এটি নিখুঁত নয়, তবে এটি আপনাকে কী করে তা মনে করে:

function playingInBrothersRoom (withToys) {
  // We closure toys which we played in the brother's room. When he come back and lock the door
  // your brother is supposed to be into the outer [[scope]] object now. Thanks god you could communicate with him.
  var closureToys = withToys || [],
      returnToy, countIt, toy; // Just another closure helpers, for brother's inner use.

  var brotherGivesToyBack = function (toy) {
    // New request. There is not yet closureToys on brother's hand yet. Give him a time.
    returnToy = null;
    if (toy && closureToys.length > 0) { // If we ask for a specific toy, the brother is going to search for it.

      for ( countIt = closureToys.length; countIt; countIt--) {
        if (closureToys[countIt - 1] == toy) {
          returnToy = 'Take your ' + closureToys.splice(countIt - 1, 1) + ', little boy!';
          break;
        }
      }
      returnToy = returnToy || 'Hey, I could not find any ' + toy + ' here. Look for it in another room.';
    }
    else if (closureToys.length > 0) { // Otherwise, just give back everything he has in the room.
      returnToy = 'Behold! ' + closureToys.join(', ') + '.';
      closureToys = [];
    }
    else {
      returnToy = 'Hey, lil shrimp, I gave you everything!';
    }
    console.log(returnToy);
  }
  return brotherGivesToyBack;
}
// You are playing in the house, including the brother's room.
var toys = ['teddybear', 'car', 'jumpingrope'],
    askBrotherForClosuredToy = playingInBrothersRoom(toys);

// The door is locked, and the brother came from the school. You could not cheat and take it out directly.
console.log(askBrotherForClosuredToy.closureToys); // Undefined

// But you could ask your brother politely, to give it back.
askBrotherForClosuredToy('teddybear'); // Hooray, here it is, teddybear
askBrotherForClosuredToy('ball'); // The brother would not be able to find it.
askBrotherForClosuredToy(); // The brother gives you all the rest
askBrotherForClosuredToy(); // Nothing left in there

আপনি দেখতে পারেন যে, ঘরে থাকা খেলনাগুলি এখনও ভাইয়ের মাধ্যমে অ্যাক্সেসযোগ্য এবং রুম লক থাকলেও কোন ব্যাপার না। এখানে এটি সঙ্গে প্রায় খেলা একটি jsbin হয়।


আমি একটি ব্লগে পোস্ট বন্ধ ব্যাখ্যা কিছুক্ষণ আগে। আপনি চাইলে কেন বন্ধ থাকার বিষয়ে আমি এখানে বললাম ।

ক্লোজারগুলি একটি ফাংশনকে স্থায়ী, ব্যক্তিগত ভেরিয়েবলগুলির জন্য কার্যকর করার একটি উপায় - অর্থাৎ, কেবলমাত্র একটি ফাংশন যা জানে তার ভেরিয়েবলগুলি, যেখানে এটি চালানো হয়েছে এমন পূর্ববর্তী বার থেকে তথ্য ট্র্যাক রাখতে পারে।

যে অর্থে, তারা একটি ফাংশন ব্যক্তিগত বৈশিষ্ট্য সঙ্গে একটি বস্তুর মত একটি বিট কাজ করা যাক।

সম্পূর্ণ পোস্ট:

তাই এই বন্ধ জিনিস জিনিস কি?


আমি এখানে উত্তর এত জটিল কেন বুঝতে পারছি না।

এখানে একটি বন্ধ আছে:

var a = 42;

function b() { return a; }

হ্যাঁ। আপনি সম্ভবত একটি দিন যে অনেক বার ব্যবহার করুন।


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

এখন কি এটা করতে পারবেন আপনি, আরো দর্শনীয় হতে পারে না বলে অন্যের উত্তর দেখুন।


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

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

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

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

একটি উদাহরণ:

function foo (initValue) {
   //This variable is not destroyed when the foo function exits.
   //It is 'captured' by the two nested functions returned below.
   var value = initValue;

   //Note that the two returned functions are created right now.
   //If the foo function is called again, it will return
   //new functions referencing a different 'value' variable.
   return {
       getValue: function () { return value; },
       setValue: function (newValue) { value = newValue; }
   }
}

function bar () {
    //foo sets its local variable 'value' to 5 and returns an object with
    //two functions still referencing that local variable
    var obj = foo(5);

    //Extracting functions just to show that no 'this' is involved here
    var getValue = obj.getValue;
    var setValue = obj.setValue;

    alert(getValue()); //Displays 5
    setValue(10);
    alert(getValue()); //Displays 10

    //At this point getValue and setValue functions are destroyed
    //(in reality they are destroyed at the next iteration of the garbage collector).
    //The local variable 'value' in the foo is no longer referenced by
    //anything and is destroyed too.
}

bar();

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

function foo(x) {
  var tmp = 3;

  function bar(y) {
    console.log(x + y + (++tmp)); // will log 16
  }

  bar(10);
}

foo(2);

এটি সর্বদা 16 টি লগ ইন করবে, কারণ bar x অ্যাক্সেস করতে পারে যা foo একটি যুক্তি হিসাবে সংজ্ঞায়িত করা হয়েছে এবং এটি foo থেকে tmp অ্যাক্সেস করতে পারে।

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

function foo(x) {
  var tmp = 3;

  return function (y) {
    console.log(x + y + (++tmp)); // will also log 16
  }
}

var bar = foo(2); // bar is now a closure.
bar(10);

উপরের ফাংশনটি 16 টি লগ ইন করবে, কারণ bar এখনও x এবং tmp উল্লেখ করতে পারে, যদিও এটি সরাসরি সুযোগের ভিতরে আর নেই।

যাইহোক, যেহেতু tmp এখনও bar বন্ধের ভিতরে ঝুলছে, এটিও বাড়ছে। আপনি bar কল যখন এটি বৃদ্ধি করা হবে।

একটি বন্ধ করার সবচেয়ে সহজ উদাহরণ এই হল:

var a = 10;

function test() {
  console.log(a); // will output 10
  console.log(b); // will output 6
}
var b = 6;
test();

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

তাদের একটি তালিকা ফেরত বা গ্লোবাল ভেরিয়েবল সেট করে, একাধিক বন্ধকরণ ফাংশন তৈরি করা সম্ভব। এই সমস্ত একই x এবং একই tmp , তারা তাদের নিজস্ব কপি করবেন না।

এখানে সংখ্যা x একটি আক্ষরিক সংখ্যা। জাভাস্ক্রিপ্টে অন্যান্য অক্ষরগুলির মতো, যখন foo বলা হয়, সংখ্যা x foo তার যুক্তি x হিসাবে কপি করা হয়।

অন্যদিকে, বস্তুর সাথে আচরণ করার সময় জাভাস্ক্রিপ্ট সবসময় রেফারেন্স ব্যবহার করে। যদি বলা হয়, আপনি একটি বস্তুর সাথে foo ডেকেছেন, এটির বন্ধ হওয়াটি মূল বস্তুর উল্লেখ করবে!

function foo(x) {
  var tmp = 3;

  return function (y) {
    console.log(x + y + tmp);
    x.memb = x.memb ? x.memb + 1 : 1;
    console.log(x.memb);
  }
}

var age = new Number(2);
var bar = foo(age); // bar is now a closure referencing age.
bar(10);

প্রত্যাশিত হিসাবে, bar(10) প্রতিটি কল bar(10) x.memb বৃদ্ধি হবে। কি প্রত্যাশিত হতে পারে না, যে x কেবল ঐক্য হিসাবে একই বস্তুর উল্লেখ করা হয়! bar কল করলে ২ বছর age.memb হবে! এই রেফারেন্সিং এইচটিএমএল বস্তুর সাথে মেমরি লিক্স জন্য ভিত্তি।


একটি অন্তর্বর্তী ফাংশন যেখানে তার বাইরের ফাংশন ভেরিয়েবল অ্যাক্সেস আছে। এটি সম্ভবত সহজতম এক-লাইনের ব্যাখ্যা যা আপনি বন্ধ করার জন্য পেতে পারেন।


জাভাস্ক্রিপ্ট ফাংশন তাদের ব্যবহার করতে পারেন:

  1. আর্গুমেন্ট
  2. স্থানীয় (অর্থাৎ, তাদের স্থানীয় ভেরিয়েবল এবং স্থানীয় ফাংশন)
  3. পরিবেশ, যা অন্তর্ভুক্ত:
    • DOM সহ globals ,.
    • বাইরের ফাংশন কিছু

একটি ফাংশন তার পরিবেশ অ্যাক্সেস, তারপর ফাংশন একটি বন্ধ।

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

গ্লোবাল পরিবেশ ব্যবহার করে এমন একটি ক্লোজার উদাহরণ:

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

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

var isVotedUp = false;
var isVotedDown = false;

function voteUp_click() {
  if (isVotedUp)
    return;
  else if (isVotedDown)
    SetDownVote(false);
  else
    SetUpVote(true);
}

function voteDown_click() {
  if (isVotedDown)
    return;
  else if (isVotedUp)
    SetUpVote(false);
  else
    SetDownVote(true);
}

function SetUpVote(status) {
  isVotedUp = status;
  // Do some CSS stuff to Vote-Up button
}

function SetDownVote(status) {
  isVotedDown = status;
  // Do some CSS stuff to Vote-Down button
}

তারা সব তাদের পরিবেশ অ্যাক্সেস হিসাবে এই সমস্ত ফাংশন চার বন্ধ।


ঠিক আছে, 6 বছর বয়সী বন্ধন ফ্যান। আপনি বন্ধ করার সহজ উদাহরণ শুনতে চান?

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

এখানে আমি কিভাবে আমার সমতল গল্প কোড কোড রূপান্তর করতে পারেন।

var plane = function(defaultAirport) {

  var lastAirportLeft = defaultAirport;

  var car = {
    driver: {
      startAccessPlaneInfo: function() {
        setInterval(function() {
          console.log("Last airport was " + lastAirportLeft);
        }, 2000);
      }
    }
  };
  car.driver.startAccessPlaneInfo();

  return {
    leaveTheAirport: function(airPortName) {
      lastAirportLeft = airPortName;
    }
  }
}("Boryspil International Airport");

plane.leaveTheAirport("John F. Kennedy");


সবচেয়ে সহজ সমাধান হবে,

ব্যবহার করার পরিবর্তে:

var funcs = [];
for(var i =0; i<3; i++){
    funcs[i] = function(){
        alert(i);
    }
}

for(var j =0; j<3; j++){
    funcs[j]();
}

যা 3 বার জন্য, "2" সতর্কতা। এটি কারণ লুপের জন্য বেনামী ফাংশন তৈরি করা, একই বন্ধের ভাগ করে এবং সেই বন্ধনে, i মান একই। শেয়ার বন্ধ করার জন্য এটি ব্যবহার করুন:

var funcs = [];
for(var new_i =0; new_i<3; new_i++){
    (function(i){
        funcs[i] = function(){
            alert(i);
        }
    })(new_i);
}

for(var j =0; j<3; j++){
    funcs[j]();
}

এর পিছনে ধারণা, IIFE (অবিলম্বে-ইনভোকড ফাংশন এক্সপ্রেশন) সহ লুপের পুরো শরীরকে new_i করা এবং new_i প্যারামিটার হিসেবে প্রেরণ করা এবং এটির মতো ক্যাপচার করা। যেহেতু বেনামী ফাংশনটি অবিলম্বে কার্যকর করা হয়, তাই বেনামী ফাংশনের ভিতরে সংজ্ঞায়িত প্রতিটি ফাংশনের জন্য i মান ভিন্ন।

এই সমাধানটি এমন কোনও সমস্যার জন্য উপযুক্ত বলে মনে হচ্ছে কারণ এটিতে এই সমস্যাটির কারণে আসল কোডটিতে সর্বনিম্ন পরিবর্তনগুলি প্রয়োজন হবে। আসলে, এই নকশা দ্বারা, এটি একটি সমস্যা হতে পারে না!





javascript function variables scope closures