javascript - জাভাস্ক্রিপ্ট বই




কিভাবে জাভাস্ক্রিপ্ট কাজ বন্ধ করে? (20)

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

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

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"

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

https://code.i-harness.com

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

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


জাভাস্ক্রিপ্ট বন্ধ জন্য 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 দ্বারা মূল পোস্ট ইন্টারনেট আর্কাইভ পাওয়া যাবে।


আপনি একটি 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 make_calculator() {
  var n = 0; // this calculator stores a single number n
  return {
    add: function(a) {
      n += a;
      return n;
    },
    multiply: function(a) {
      n *= a;
      return n;
    }
  };
}

first_calculator = make_calculator();
second_calculator = make_calculator();

first_calculator.add(3); // returns 3
second_calculator.add(400); // returns 400

first_calculator.multiply(11); // returns 33
second_calculator.multiply(10); // returns 4000

মূল বিন্দু: প্রতিটি কল make_calculatorএকটি নতুন স্থানীয় পরিবর্তনশীল তৈরি করে n, যা যে ক্যালকুলেটর দ্বারা ব্যবহারযোগ্য addএবং অব্যবহৃত multiplyপরে দীর্ঘ কাজ করে চলতে থাকে make_calculator

আপনি যদি স্ট্যাক ফ্রেমের সাথে পরিচিত হন তবে এই ক্যালকুলেটরগুলি অদ্ভুত বলে মনে হয়: তারা কীভাবে আয় করার nপরে অ্যাক্সেস করতে পারেন make_calculator? উত্তর জাভাস্ক্রিপ্ট "স্ট্যাক ফ্রেম" ব্যবহার করে না কল্পনা করা হয়, তবে পরিবর্তে "হিপ ফ্রেমস" ব্যবহার করে, যা ফাংশন কলের পরেই চলতে পারে যা তাদের ফেরত দেয়।

অভ্যন্তরীণ ফাংশন addএবং multiply, যা একটি বহিরাগত ফাংশন ** অ্যাক্সেস ভেরিয়েবল ঘোষণা , বন্ধ করা হয়

যে বন্ধ অনেক আছে অনেক সুন্দর।


* উদাহরণস্বরূপ, এটি " উত্তরপত্রের জন্য বন্ধন" প্রবন্ধের অন্য কোনও প্রবন্ধে দেওয়া সমস্ত বিন্দুকে অন্তর্ভুক্ত করে , উদাহরণস্বরূপ 6, যা কেবলমাত্র দেখায় যে ভেরিয়েবলগুলি ঘোষিত হওয়ার আগেই ব্যবহার করা যেতে পারে, এটি জানার জন্য একটি চমৎকার সত্য কিন্তু সম্পূর্ণভাবে বন্ধ হওয়ার সাথে সম্পর্কিত নয়। এটি গৃহীত উত্তরগুলির সমস্ত পয়েন্টকেও অন্তর্ভুক্ত করে (1) পয়েন্টগুলি (1) যা তাদের আর্গুমেন্টগুলিকে স্থানীয় ভেরিয়েবলগুলিতে (নামযুক্ত ফাংশন আর্গুমেন্ট) অনুলিপি করে এবং (2) যে সংখ্যাগুলি অনুলিপি করে একটি নতুন সংখ্যা তৈরি করে তবে একটি বস্তু রেফারেন্স অনুলিপি করে একই বস্তুর আরেকটি রেফারেন্স দেয়। এই জানতে ভাল কিন্তু আবার সম্পূর্ণরূপে বন্ধ সম্পর্কহীন। এটিও এই উত্তরের উদাহরণের অনুরূপ কিন্তু একটু সংক্ষিপ্ত এবং কম বিমূর্ত। এটা পয়েন্ট আবরণ করা হয় নাএই উত্তর বা এই মন্তব্য , যা জাভাস্ক্রিপ্ট বর্তমান প্লাগ করা কঠিন করে তোলেআপনার অভ্যন্তরীণ ফাংশনে একটি লুপ ভেরিয়েবলের মান: "প্লাগ ইন ইন" ধাপ শুধুমাত্র একটি সহায়ক ফাংশন দ্বারা সম্পন্ন করা যেতে পারে যা আপনার অভ্যন্তরীণ ফাংশনকে ঘিরে রাখে এবং প্রতিটি লুপ পুনরাবৃত্তি উপর আহ্বান করা হয়। (কঠোরভাবে বলার অপেক্ষা রাখে না, অভ্যন্তরীণ ফাংশন কোনও প্লাগ ইন করার পরিবর্তে পরিবর্তনশীলের সহায়কের ফাংশনটির অনুলিপি অ্যাক্সেস করে।) আবার, বন্ধ করার সময় খুব দরকারী, তবে কোনও বন্ধকরণ বা এটি কীভাবে কাজ করে তা অংশ নয়। এমএল মত কার্যকরী ভাষাগুলিতে ভিন্নভাবে কাজ বন্ধ থাকার কারণে অতিরিক্ত বিভ্রান্তি রয়েছে, যেখানে ভেরিয়েবলগুলি স্টোরেজ স্পেসের পরিবর্তে মূল্যের সাথে আবদ্ধ থাকে, যাতে কোনওভাবে বন্ধ হয়ে যাওয়া বোঝার (যথা "প্লাগ ইন ইন") জাভাস্ক্রিপ্ট জন্য সহজভাবে ভুল, যেখানে ভেরিয়েবল সবসময় স্টোরেজ স্পেস আবদ্ধ হয়, এবং মান না।

** কোন বাহ্যিক ফাংশন, যদি কয়েকটি নেস্টেড হয়, এমনকি বিশ্বব্যাপী প্রসঙ্গে, এই উত্তরটি স্পষ্টভাবে নির্দেশ করে।


FOREWORD: প্রশ্নটি যখন এই প্রশ্নটি লিখিত হয়েছিল:

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

কেউ কি ভাবতে পারে যে আমি 6 বছর এবং সেই বিষয়ে অদ্ভুত আগ্রহী?

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

আমি কঠিন ধারণা ব্যাখ্যা করার সময় উপমা এবং রূপক একটি বড় ফ্যান, তাই আমাকে একটি গল্প সঙ্গে আমার হাত চেষ্টা করা।

একদা:

একটি রাজকুমারী ছিল ...

function princess() {

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

    var adventures = [];

    function princeCharming() { /* ... */ }

    var unicorn = { /* ... */ },
        dragons = [ /* ... */ ],
        squirrel = "Hello!";

    /* ... */

কিন্তু তিনি সবসময় chores এবং উত্থাপিত আপ তার নিস্তেজ বিশ্বের ফিরে আসতে হবে।

    return {

এবং তিনি প্রায়ই একটি রাজকুমারী হিসাবে তার সর্বশেষ আশ্চর্যজনক দু: সাহসিক কাজ তাদের বলতে হবে।

        story: function() {
            return adventures[adventures.length - 1];
        }
    };
}

কিন্তু তারা সবাই দেখতে পাবে একটি ছোট মেয়ে ...

var littleGirl = princess();

... জাদু এবং কল্পনা সম্পর্কে গল্প বলছে।

littleGirl.story();

এবং যদিও প্রাপ্তবয়স্করা সত্যিকারের রাজকুমারীদের জানত, তারা কখনোই ঐক্যজোট বা ড্রাগনগুলিতে বিশ্বাস করবে না কারণ তারা তাদের দেখতে পারে না। প্রাপ্তবয়স্করা বলেছিল যে তারা কেবলমাত্র ছোট মেয়েটির কল্পনার মধ্যেই বিদ্যমান ছিল।

কিন্তু আমরা সত্য সত্য জানি; যে রাজকুমারী সঙ্গে সামান্য মেয়ে ভিতরে ...

... সত্যিই ভিতরে একটি ছোট মেয়ে সঙ্গে একটি রাজকুমারী।


এটি অন্য কিছু উত্তরগুলির মধ্যে প্রদর্শিত ক্লোজগুলি সম্পর্কে বেশ কয়েকটি (সম্ভাব্য) ভুল বোঝাবুঝি মুছে ফেলার একটি প্রচেষ্টা।

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

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

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 হবে! এই রেফারেন্সিং এইচটিএমএল বস্তুর সাথে মেমরি লিক্স জন্য ভিত্তি।


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

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

টেকনিক্যালি, 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) এবং পরে মৃত্যুদন্ড কার্যকর করা, প্রতিটি সময় এটি একটি ডাটাবেস ফাংশন উত্পন্ন করা হয়। প্রতিটি উত্পন্ন ফাংশন তার নিজস্ব লুকানো ডাটাবেস বস্তু থাকবে। ক্লোজারগুলির আরেকটি ব্যবহার উদাহরণ যখন আমরা কোনও ফাংশন ফিরিয়ে না দিলেও বিভিন্ন বস্তুর জন্য একাধিক ফাংশন থাকে, প্রতিটি ফাংশন একই ডাটা অ্যাক্সেস করে থাকে।


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 হয়।


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

// 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

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

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


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

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

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: গরিলা

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


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();

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


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

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

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

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

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


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

এবং হ্যাঁ, আমি এমনকি এটি 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

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


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

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

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

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

একটি উদাহরণ:

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();

ঠিক আছে, 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");






closures