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




ফাংশন কোড (25)

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 ব্যাখ্যা করা কঠিন কারণ তারা কিছু আচরণ কাজ করার জন্য ব্যবহার করা হয় যে সবাই 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 থেকে আবদ্ধ।


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


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

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

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

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

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

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

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

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

  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

প্রশ্নটি গুরুত্ব সহকারে গ্রহণ করা উচিত, আমরা 6-বছর-বয়সী একজন জ্ঞানীয়ভাবে সক্ষম কি তা খুঁজে বের করতে পারি, যদিও স্বীকার্যক্রমে, জাভাস্ক্রিপ্টে আগ্রহী এমন ব্যক্তিটি এত আদর্শ নয়।

শৈশব উন্নয়ন: 5 থেকে 7 বছর এটি বলে:

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

আমরা এই উদাহরণটি বন্ধ করার ব্যাখ্যা হিসাবে ব্যবহার করতে পারি:

রান্নাঘরটি একটি ক্লোজার যা একটি স্থানীয় পরিবর্তনশীল, trashBags নামে trashBagsgetTrashBag নামক রান্নাঘরে একটি ফাংশন রয়েছে যা একটি ট্র্যাশ ব্যাগ পায় এবং এটি ফেরত দেয়।

আমরা এই মত জাভাস্ক্রিপ্ট এই কোড করতে পারেন:

function makeKitchen() {
  var trashBags = ['A', 'B', 'C']; // only 3 at first

  return {
    getTrashBag: function() {
      return trashBags.pop();
    }
  };
}

var kitchen = makeKitchen();

console.log(kitchen.getTrashBag()); // returns trash bag C
console.log(kitchen.getTrashBag()); // returns trash bag B
console.log(kitchen.getTrashBag()); // returns trash bag A

বন্ধ পয়েন্ট আকর্ষণীয় কারণ ব্যাখ্যা আরও পয়েন্ট:

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

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

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

var a = 42;

function b() { return a; }

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


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

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


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

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


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

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


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

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


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

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

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

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


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

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

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

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

একটি উদাহরণ:

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

আমি ভাল / খারাপ তুলনা দ্বারা ভাল শিখতে ঝোঁক। আমি কর্মক্ষেত্রের কোডটি অনুসরণ করতে চাই যা অননুমোদিত কোডটি অনুসরণ করে যা কেউ সম্মুখীন হতে পারে। আমি একটি 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


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


ক্লোজার সহজ:

নিম্নলিখিত সহজ উদাহরণ জাভাস্ক্রিপ্ট বন্ধ সব প্রধান পয়েন্ট জুড়ে। *

এখানে এমন একটি কারখানা রয়েছে যা ক্যালকুলেটর তৈরি করে যা যোগ এবং গুণমান করতে পারে:

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

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


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

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

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


আমি কিভাবে ছয় বছর বয়সী এটা ব্যাখ্যা করতে হবে:

আপনি জানেন কিভাবে বড় বড় বাড়ি মালিকের মালিক হতে পারে এবং তারা এটিকে বাড়ি বলে ডাকে? যখন একটি মায়ের বাচ্চা থাকে, তখন বাচ্চাটির কোন কিছুই ঠিক থাকে না, তাই না? কিন্তু তার বাবা-মায়ের একটি বাড়ি আছে, তাই যখনই কেউ আপনার সন্তানকে জিজ্ঞেস করে "আপনার বাড়ি কোথায়?", সে "সেই বাড়ির" উত্তর দিতে পারে এবং তার পিতামাতার বাড়িতে নির্দেশ করে। একটি "ক্লোজার" বাচ্চাটির ক্ষমতা সবসময় (এমনকি যদি বিদেশে থাকে) বলার ক্ষমতা থাকে যে এটি একটি বাড়ি আছে, যদিও এটি প্রকৃতপক্ষে পিতামাতার বাড়ির মালিক।


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

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

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

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

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


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

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

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

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

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

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

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


স্ট্রো ম্যান

আমাকে জানতে হবে কত বার একটি বোতাম ক্লিক করা হয়েছে এবং প্রতিটি তৃতীয় ক্লিকে কিছু করতে হবে ...

মোটামুটি স্পষ্ট সমাধান

// Declare counter outside event handler's scope
var counter = 0;
var element = document.getElementById('button');

element.addEventListener("click", function() {
  // Increment outside counter
  counter++;

  if (counter === 3) {
    // Do something every third time
    console.log("Third time's the charm!");

    // Reset counter
    counter = 0;
  }
});
<button id="button">Click Me!</button>

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

এই বিকল্প বিবেচনা করুন

var element = document.getElementById('button');

element.addEventListener("click", (function() {
  // init the count to 0
  var count = 0;

  return function(e) { // <- This function becomes the click handler
    count++; //    and will retain access to the above `count`

    if (count === 3) {
      // Do something every third time
      console.log("Third time's the charm!");

      //Reset counter
      count = 0;
    }
  };
})());
<button id="button">Click Me!</button>

এখানে কিছু জিনিস লক্ষ্য করুন।

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

একটি সহজ এক লাইন বন্ধ

//          _______________________Immediately invoked______________________
//         |                                                                |
//         |        Scope retained for use      ___Returned as the____      |
//         |       only by returned function   |    value of func     |     |
//         |             |            |        |                      |     |
//         v             v            v        v                      v     v
var func = (function() { var a = 'val'; return function() { alert(a); }; })();

ফিরতি ফাংশনের বাইরে সমস্ত ভেরিয়েবল ফিরতি ফাংশনে উপলব্ধ, তবে তারা ফাংশন অবজেক্টে সরাসরি উপলব্ধ নয় ...

func();  // Alerts "val"
func.a;  // Undefined

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

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

এই নাও; আপনি এখন সম্পূর্ণরূপে এই আচরণ encapsulating করছি।

সম্পূর্ণ ব্লগ পোস্ট (jQuery বিবেচনার সহ)


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

  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
}

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


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

প্রথম বিকল্প: Lodash ব্যবহার করুন: এতে একটি পদ্ধতি includes :

_.includes('foobar', 'ob');
// → true

লোড্যাশ এনপিএম এর জন্য সবচেয়ে জনপ্রিয় জাভাস্ক্রিপ্ট লাইব্রেরি নির্ভরতা এবং সহজে জাভাস্ক্রিপ্ট ইউটিলিটি পদ্ধতির লোড রয়েছে। তাই অনেক প্রকল্পের জন্য আপনি এই যাই হোক না কেন চাই ;-)

দ্বিতীয় বিকল্প: অথবা Underscore.string ব্যবহার করুন: এটি একটি include পদ্ধতি আছে:

_.str.include('foobar', 'ob');
// → true

এখানে আন্ডারস্কোর.স্ট্রিংয়ের বিবরণ রয়েছে, এটি কেবল 9 কেবি যোগ করে তবে এটি আপনাকে সমস্ত সুবিধাদি দেয় যা একটি ভাল-পরীক্ষিত এবং নথিবদ্ধ লাইব্রেরি অনুলিপি কোড স্ন্যিপেটগুলিতে আছে:

Underscore.string স্ট্রিং সহ আরামদায়ক ম্যানিপুলেশনের জন্য জাভাস্ক্রিপ্ট লাইব্রেরি, প্রোটোটাইপ.জেএস, রাইট.জেএস, আন্ডারস্কোর এবং সুন্দর রুবি ভাষা দ্বারা অনুপ্রাণিত Underscore.js এর জন্য এক্সটেনশান।

Underscore.string আপনাকে অনেকগুলি কার্যকর ফাংশন সরবরাহ করে: মূলধন, পরিষ্কার, অন্তর্ভুক্ত, গণনা, পাল্টা HTML, unescapeHTML, সন্নিবেশ, splice, শুরু, সহ, শেষ, শিরোনাম, শিরোনাম, ছিনতাই এবং ইত্যাদি।

ভাল মনে রাখবেন, Underscore.string আন্ডারস্কোর.জেএস দ্বারা প্রভাবিত কিন্তু এটি ছাড়া ব্যবহার করা যেতে পারে।

শেষ না অন্তত: জাভাস্ক্রিপ্ট সংস্করণ ES6 আসে একটি অন্তর্নির্মিত পদ্ধতি includes :

'foobar'.includes('ob');
// → true

বেশিরভাগ আধুনিক ব্রাউজার ইতিমধ্যে এটি সমর্থন করে, ES6 সামঞ্জস্যপূর্ণ টেবিলে নজর রাখুন।





javascript function variables scope closures