পার্টিতে দেরি হয়ে গেলেও আমি আজ এই সমস্যাটি ঘুরে দেখছিলাম এবং লক্ষ্য করেছি যে উত্তরগুলির অনেকগুলি পুরোপুরি জাভাস্ক্রিপ্ট কীভাবে স্কোপের সাথে আচরণ করে তা পুরোপুরিভাবে মোকাবেলা করে না, যা মূলত এইটিকে উত্সাহিত করে।
সুতরাং অন্য অনেকে উল্লিখিত হিসাবে, সমস্যাটি হ'ল অভ্যন্তরীণ ফাংশনটি একই i
ভেরিয়েবলটি উল্লেখ করে । সুতরাং কেন আমরা কেবল প্রতিটি পুনরাবৃত্তির জন্য একটি নতুন স্থানীয় পরিবর্তনশীল তৈরি করি না, এবং এর পরিবর্তে অভ্যন্তরীণ ফাংশন রেফারেন্স রাখি?
//overwrite console.log() so you can see the console output
console.log = function(msg) {document.body.innerHTML += '<p>' + msg + '</p>';};
var funcs = {};
for (var i = 0; i < 3; i++) {
var ilocal = i; //create a new local variable
funcs[i] = function() {
console.log("My value: " + ilocal); //each should reference its own local variable
};
}
for (var j = 0; j < 3; j++) {
funcs[j]();
}
ঠিক আগের মতোই, যেখানে প্রতিটি অভ্যন্তরীণ ফাংশন নির্ধারিত শেষের মানকে i
আউটপুট করে, এখন প্রতিটি অভ্যন্তরীণ ফাংশন কেবলমাত্র নির্ধারিত শেষের মানকে আউটপুট করে ilocal
। তবে প্রতিটি পুনরাবৃত্তির নিজস্ব হওয়া উচিত নয় ilocal
?
দেখা যাচ্ছে, এটাই সমস্যা। প্রতিটি পুনরাবৃত্তি একই সুযোগ ভাগ করে নিচ্ছে, তাই প্রথমটির পরে প্রতিটি পুনরাবৃত্তি কেবল ওভাররাইট করা ilocal
। এমডিএন থেকে :
গুরুত্বপূর্ণ: জাভাস্ক্রিপ্টের ব্লক স্কোপ নেই। একটি ব্লকের সাথে প্রবর্তিত ভেরিয়েবলগুলি সমন্বিত ফাংশন বা স্ক্রিপ্টের জন্য স্কোপ করা হয় এবং সেগুলি নির্ধারণের প্রভাবগুলি ব্লকের বাইরেও বহাল থাকে। অন্য কথায়, ব্লক স্টেটমেন্টগুলি কোনও সুযোগ প্রবর্তন করে না। যদিও "স্ট্যান্ডেলোন" ব্লকগুলি বৈধ বাক্য গঠন, তবে আপনি জাভাস্ক্রিপ্টে স্ট্যান্ডেলোন ব্লক ব্যবহার করতে চান না, কারণ তারা সি বা জাভাতে এই জাতীয় ব্লকের মতো কিছু করেন বলে আপনি মনে করেন তারা যা করেন তা তারা করেন না।
জোর দেওয়ার জন্য পুনরাবৃত্তি:
জাভাস্ক্রিপ্টের ব্লক স্কোপ নেই। একটি ব্লকের সাথে প্রবর্তিত ভেরিয়েবলগুলি সমন্বিত ফাংশন বা স্ক্রিপ্টের জন্য স্কোপ করা হয়
আমরা ilocal
প্রতিটি পুনরাবৃত্তিতে এটি ঘোষণার আগে এটি পরীক্ষা করে দেখতে পারি:
//overwrite console.log() so you can see the console output
console.log = function(msg) {document.body.innerHTML += '<p>' + msg + '</p>';};
var funcs = {};
for (var i = 0; i < 3; i++) {
console.log(ilocal);
var ilocal = i;
}
এই বাগটি ঠিক ততটাই কৌশলযুক্ত। যদিও আপনি কোনও ভেরিয়েবলটিকে পুনরায় বিবরণ দিচ্ছেন, জাভাস্ক্রিপ্ট কোনও ত্রুটি ফেলবে না এবং জেএসলিন্ট এমনকি কোনও সতর্কতাও ছুঁড়বে না। এ কারণেই এটি সমাধানের সর্বোত্তম উপায়টি ক্লোজারগুলির সুবিধা গ্রহণ করা, যা মূলত এই ধারণাটি যে জাভাস্ক্রিপ্টে অভ্যন্তরীণ ফাংশনগুলিতে বাইরের ভেরিয়েবলগুলি অ্যাক্সেস রয়েছে কারণ অভ্যন্তরীণ স্কোপগুলি বহিরাগত স্কোপগুলিকে "বন্ধ" করে।
এর অর্থ হ'ল অভ্যন্তরীণ ফাংশনগুলি বাইরের ভেরিয়েবলগুলিকে "ধরে" রাখে এবং তাদের জীবিত রাখবে, এমনকি যদি বাহ্যিক ক্রিয়াটি ফিরে আসে। এটি ব্যবহার করতে, আমরা একটি নতুন সুযোগ তৈরি করতে, নতুন স্কোপে ঘোষণা করতে ilocal
এবং একটি অভ্যন্তরীণ ফাংশন যা ব্যবহার করে ilocal
(নীচে আরও ব্যাখ্যা) ফিরিয়ে আনতে খাঁটিভাবে একটি মোড়ক ফাংশন তৈরি এবং কল করি
//overwrite console.log() so you can see the console output
console.log = function(msg) {document.body.innerHTML += '<p>' + msg + '</p>';};
var funcs = {};
for (var i = 0; i < 3; i++) {
funcs[i] = (function() { //create a new scope using a wrapper function
var ilocal = i; //capture i into a local var
return function() { //return the inner function
console.log("My value: " + ilocal);
};
})(); //remember to run the wrapper function
}
for (var j = 0; j < 3; j++) {
funcs[j]();
}
একটি মোড়ক ফাংশনের অভ্যন্তরীণ ফাংশন তৈরি করা অভ্যন্তরীণ ফাংশনটিকে একটি ব্যক্তিগত পরিবেশ দেয় যা কেবল এটি "অ্যাক্সেস" অ্যাক্সেস করতে পারে। সুতরাং, প্রতিবার আমরা যখন র্যাপার ফাংশনটি বলি তখন আমরা তার নিজস্ব পৃথক পরিবেশের সাথে একটি নতুন অভ্যন্তরীণ ফাংশন তৈরি করি, এটি নিশ্চিত করে যে ilocal
ভেরিয়েবলগুলি একে অপরের সাথে সংঘর্ষ না হয় এবং এটি ওভাররাইট করে। কয়েকটি অন্যান্য ছোট্ট অপ্টিমাইজেশন চূড়ান্ত উত্তর দেয় যা অন্য অনেক এসও ব্যবহারকারীরা দিয়েছেন:
//overwrite console.log() so you can see the console output
console.log = function(msg) {document.body.innerHTML += '<p>' + msg + '</p>';};
var funcs = {};
for (var i = 0; i < 3; i++) {
funcs[i] = wrapper(i);
}
for (var j = 0; j < 3; j++) {
funcs[j]();
}
//creates a separate environment for the inner function
function wrapper(ilocal) {
return function() { //return the inner function
console.log("My value: " + ilocal);
};
}
হালনাগাদ
ES6 এখন মূলধারার সাথে, আমরা এখন let
ব্লক-স্কোপড ভেরিয়েবলগুলি তৈরি করতে নতুন কীওয়ার্ডটি ব্যবহার করতে পারি :
//overwrite console.log() so you can see the console output
console.log = function(msg) {document.body.innerHTML += '<p>' + msg + '</p>';};
var funcs = {};
for (let i = 0; i < 3; i++) { // use "let" to declare "i"
funcs[i] = function() {
console.log("My value: " + i); //each should reference its own local variable
};
}
for (var j = 0; j < 3; j++) { // we can use "var" here without issue
funcs[j]();
}
দেখুন এখন কত সহজ! আরও তথ্যের জন্য এই উত্তরটি দেখুন , যা আমার তথ্য ভিত্তিক।
funcs
কোনও অ্যারে হতে চান না , আপনি যদি সংখ্যার সূচকগুলি ব্যবহার করেন? শুধু একটি মাথা আপ.