ইসমাস্ক্রিপ্ট বিবৃতি উপস্থাপন করেছেlet ।
আমি শুনেছি এটি একটি "স্থানীয়" ভেরিয়েবল হিসাবে বর্ণনা করা হয়েছে তবে varকীওয়ার্ডের চেয়ে এটি কীভাবে আলাদা আচরণ করে তা এখনও আমি নিশ্চিত নই ।
পার্থক্য কি? কখন letব্যবহার করা উচিত var?
ইসমাস্ক্রিপ্ট বিবৃতি উপস্থাপন করেছেlet ।
আমি শুনেছি এটি একটি "স্থানীয়" ভেরিয়েবল হিসাবে বর্ণনা করা হয়েছে তবে varকীওয়ার্ডের চেয়ে এটি কীভাবে আলাদা আচরণ করে তা এখনও আমি নিশ্চিত নই ।
পার্থক্য কি? কখন letব্যবহার করা উচিত var?
উত্তর:
মূল পার্থক্য হ'ল স্কোপিংয়ের নিয়ম। মূলশব্দ দ্বারা ঘোষিত ভেরিয়েবলগুলি varতাত্ক্ষণিক ফাংশন বডি (তাই ফাংশন স্কোপ) এ স্কোপ করা হয় যখন letভেরিয়েবলগুলি তত্ক্ষণাত বন্ধ করা ব্লক { }(যার ফলে ব্লক স্কোপ) দ্বারা চিহ্নিত হয় sc
function run() {
var foo = "Foo";
let bar = "Bar";
console.log(foo, bar);
{
let baz = "Bazz";
console.log(baz);
}
console.log(baz); // ReferenceError
}
run();
letকীওয়ার্ডটি ভাষাতে চালু করার কারণটি ছিল ফাংশন স্কোপটি বিভ্রান্তিকর এবং জাভাস্ক্রিপ্টের বাগগুলির অন্যতম প্রধান উত্স ছিল।
অন্য স্ট্যাকওভারফ্লো প্রশ্ন থেকে এই উদাহরণটি একবার দেখুন :
var funcs = [];
// let's create 3 functions
for (var i = 0; i < 3; i++) {
// and store them in funcs
funcs[i] = function() {
// each should log its value.
console.log("My value: " + i);
};
}
for (var j = 0; j < 3; j++) {
// and now let's run each one to see
funcs[j]();
}
My value: 3funcs[j]();বেনাম ফাংশনগুলি একই ভেরিয়েবলের সাথে আবদ্ধ থাকায় প্রতিবার কনসোল আউটপুট আনা হয়েছিল।
লুপগুলি থেকে সঠিক মান কমাতে লোকদের তাত্ক্ষণিকভাবে অনুরোধ করা ফাংশন তৈরি করতে হয়েছিল তবে তা লোমশও ছিল।
varকীওয়ার্ড সহ ঘোষিত ভেরিয়েবলগুলি উত্তোলন করা হয় ( undefinedকোড চালুর আগেই আরম্ভ করা হয় ) যার অর্থ তারা ঘোষণার আগেই তাদের ঘেরের সুযোগে অ্যাক্সেসযোগ্য:
function run() {
console.log(foo); // undefined
var foo = "Foo";
console.log(foo); // Foo
}
run();
letভেরিয়েবলগুলি তাদের সংজ্ঞাটি মূল্যায়ন না করা পর্যন্ত শুরু করা হয় না। প্রারম্ভিককরণের আগে তাদের অ্যাক্সেস করা ফলাফল এ ReferenceError। চলকটি প্রাথমিকভাবে প্রক্রিয়াজাত না হওয়া অবধি ব্লকের শুরু থেকে "অস্থায়ী ডেড জোনে" থাকতে বলেছিলেন।
function checkHoisting() {
console.log(foo); // ReferenceError
let foo = "Foo";
console.log(foo); // Foo
}
checkHoisting();
শীর্ষ স্তরে, letবৈসাদৃশ্য var, বৈশ্বিক বস্তুতে কোনও সম্পত্তি তৈরি করে না:
var foo = "Foo"; // globally scoped
let bar = "Bar"; // globally scoped
console.log(window.foo); // Foo
console.log(window.bar); // undefined
কড়া মোডে, সিন্ট্যাক্সেরর উত্থাপন করার varসময় আপনাকে একই সুযোগে একই পরিবর্তনশীলটিকে পুনরায় ঘোষণা করতে দেওয়া হবে let।
'use strict';
var foo = "foo1";
var foo = "foo2"; // No problem, 'foo' is replaced.
let bar = "bar1";
let bar = "bar2"; // SyntaxError: Identifier 'bar' has already been declared
letব্লক এক্সপ্রেশনটি মানহীনlet (variable declaration) statement এবং ভবিষ্যতে bugzilla.mozilla.org/show_bug.cgi?id=1023609 মুছে ফেলা হবে ।
letক্লোজারে সমস্যা এড়াতেও ব্যবহার করা যেতে পারে। এটি নীচের উদাহরণগুলিতে যেমন পুরানো রেফারেন্স রাখার চেয়ে তাজা মানকে আবদ্ধ করে।
for(var i=1; i<6; i++) {
$("#div" + i).click(function () { console.log(i); });
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<p>Clicking on each number will log to console:</p>
<div id="div1">1</div>
<div id="div2">2</div>
<div id="div3">3</div>
<div id="div4">4</div>
<div id="div5">5</div>
উপরের কোডটি ক্লাসিক জাভাস্ক্রিপ্ট বন্ধ করার সমস্যাটি দেখায়। iভেরিয়েবলের রেফারেন্সটি আসল মানটির চেয়ে ক্লিক হ্যান্ডলার বন্ধে সংরক্ষণ করা হচ্ছে i।
প্রতিটি একক ক্লিক হ্যান্ডলার একই বস্তুকে উল্লেখ করবে কারণ সেখানে কেবলমাত্র একটি কাউন্টার অবজেক্ট রয়েছে যা 6 রাখে যাতে আপনি প্রতিটি ক্লিকে ছয়টি পান।
একটি সাধারণ কর্মসীমা হ'ল এটি একটি বেনামি ফাংশনে আবদ্ধ করা iএবং একটি আর্গুমেন্ট হিসাবে পাস করা। নীচের কোডে বর্ণিত letপরিবর্তে এখন ব্যবহার করে এ জাতীয় সমস্যাগুলি এড়ানো যায় var।
(ক্রোম এবং ফায়ারফক্স 50 এ পরীক্ষিত)
for(let i=1; i<6; i++) {
$("#div" + i).click(function () { console.log(i); });
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<p>Clicking on each number will log to console:</p>
<div id="div1">1</div>
<div id="div2">2</div>
<div id="div3">3</div>
<div id="div4">4</div>
<div id="div5">5</div>
letতবে এটি সমস্ত বোতামের জন্য "6" কে সতর্ক করে। আপনার letআচরণের কথা বলে এমন কোনও উত্স আছে ?
letসত্যই কার্যকর হবে। ইভেন্ট শ্রোতাদের একটি লুপে সেট করার জন্য iপ্রতিটি পুনরাবৃত্তির জন্য স্থানীয়ভাবে স্কোপিংয়ের জন্য তাত্ক্ষণিকভাবে অনুরোধ করা ফাংশন এক্সপ্রেশন প্রয়োজন হয় না ।
letএবং var?varবিবৃতি ব্যবহার করে সংজ্ঞায়িত একটি পরিবর্তনশীল ফাংশনটির শুরু থেকেই এটি সংজ্ঞায়িত ফাংশন জুড়েই পরিচিত । (*)letবিবৃতি ব্যবহার করে সংজ্ঞায়িত একটি পরিবর্তনশীল কেবল এটির মধ্যে সংজ্ঞায়িত ব্লকের মধ্যেই এটির সংজ্ঞা দেওয়া মুহুর্ত থেকেই। (**)পার্থক্যটি বুঝতে, নিম্নলিখিত কোডটি বিবেচনা করুন:
// i IS NOT known here
// j IS NOT known here
// k IS known here, but undefined
// l IS NOT known here
function loop(arr) {
// i IS known here, but undefined
// j IS NOT known here
// k IS known here, but has a value only the second time loop is called
// l IS NOT known here
for( var i = 0; i < arr.length; i++ ) {
// i IS known here, and has a value
// j IS NOT known here
// k IS known here, but has a value only the second time loop is called
// l IS NOT known here
};
// i IS known here, and has a value
// j IS NOT known here
// k IS known here, but has a value only the second time loop is called
// l IS NOT known here
for( let j = 0; j < arr.length; j++ ) {
// i IS known here, and has a value
// j IS known here, and has a value
// k IS known here, but has a value only the second time loop is called
// l IS NOT known here
};
// i IS known here, and has a value
// j IS NOT known here
// k IS known here, but has a value only the second time loop is called
// l IS NOT known here
}
loop([1,2,3,4]);
for( var k = 0; k < arr.length; k++ ) {
// i IS NOT known here
// j IS NOT known here
// k IS known here, and has a value
// l IS NOT known here
};
for( let l = 0; l < arr.length; l++ ) {
// i IS NOT known here
// j IS NOT known here
// k IS known here, and has a value
// l IS known here, and has a value
};
loop([1,2,3,4]);
// i IS NOT known here
// j IS NOT known here
// k IS known here, and has a value
// l IS NOT known here
এখানে, আমরা দেখতে পারি যে আমাদের চলকটি jকেবল লুপের জন্য প্রথমটিতে পরিচিত তবে আগে এবং পরে নয়। তবুও, আমাদের ভেরিয়েবল iপুরো ফাংশনে পরিচিত।
এছাড়াও, বিবেচনা করুন যে ব্লক স্কোপযুক্ত ভেরিয়েবলগুলি ঘোষণার আগে তাদের জানা নেই কারণ সেগুলি তোলা হয় না। আপনাকে একই ব্লকের মধ্যে একই ব্লকের স্কোপড ভেরিয়েবলটি পুনরায় ঘোষণার অনুমতি নেই। এটি ব্লক স্কোপড ভেরিয়েবলকে বিশ্বব্যাপী বা কার্যকরীভাবে স্কোপযুক্ত ভেরিয়েবলগুলির তুলনায় কম ত্রুটি প্রবণ করে তোলে, যা উত্তোলন করা হয় এবং যা একাধিক ঘোষণার ক্ষেত্রে কোনও ত্রুটি তৈরি করে না।
letআজ ব্যবহার করা নিরাপদ ?কিছু লোক যুক্তি দেখান যে ভবিষ্যতে আমরা কেবলমাত্র বিবৃতিগুলি ব্যবহার করব এবং সেই বর্ণনামূলক বিবৃতিগুলি অচল হয়ে যাবে। জাভাস্ক্রিপ্ট গুরু কাইল সিম্পসন কেন তিনি বিশ্বাস করেন যে এটি হবে না তা নিয়ে একটি বিস্তৃত প্রবন্ধ লিখেছিলেন ।
আজ, অবশ্যই, এটি হয় না। প্রকৃতপক্ষে, letবিবৃতিটি ব্যবহার করা নিরাপদ কিনা তা আমাদের নিজেদের জিজ্ঞাসা করতে হবে । এই প্রশ্নের উত্তর আপনার পরিবেশের উপর নির্ভর করে:
আপনি যদি সার্ভার-সাইড জাভাস্ক্রিপ্ট কোড ( নোড.জেএস ) লিখছেন তবে আপনি নিরাপদে letবিবৃতিটি ব্যবহার করতে পারেন ।
আপনি যদি ক্লায়েন্ট-সাইড জাভাস্ক্রিপ্ট কোড লিখছেন এবং ব্রাউজার ভিত্তিক ট্রান্সপ্লেলার (যেমন ট্রেসুর বা ব্যাবেল-স্ট্যান্ডেলোন ) ব্যবহার করেন letতবে আপনি নিরাপদে বিবৃতিটি ব্যবহার করতে পারেন তবে আপনার কোডটি পারফরম্যান্সের ক্ষেত্রে সর্বোত্তম কিছু হতে পারে।
তুমি লেখা ক্লায়েন্ট-সাইড জাভাস্ক্রিপ্ট কোড এবং একটি নোড ভিত্তিক transpiler (যেমন ব্যবহার করেন, তাহলে traceur শেল স্ক্রিপ্ট বা হট্টগোল ), আপনি নিরাপদে ব্যবহার করতে পারেন letবিবৃতি। এবং যেহেতু আপনার ব্রাউজারটি কেবল স্থানান্তরিত কোড সম্পর্কে জানবে, পারফরম্যান্সের অপূর্ণতা সীমাবদ্ধ করা উচিত।
আপনি যদি ক্লায়েন্ট-সাইড জাভাস্ক্রিপ্ট কোড লিখছেন এবং ট্রান্সপ্লার ব্যবহার না করেন, আপনাকে ব্রাউজার সমর্থন বিবেচনা করা উচিত।
এখনও কিছু ব্রাউজার রয়েছে যা একেবারেই সমর্থন letকরে না:
letআপনার উত্তরটি পড়ার সময় কোন ব্রাউজারগুলি বিবৃতিটিকে সমর্থন করে তার একটি আপ-টু-ডেট ওভিউর জন্য , এই Can I Useপৃষ্ঠাটি দেখুন ।
(*) বিশ্বব্যাপী এবং কার্যকরীভাবে স্কোপযুক্ত ভেরিয়েবলগুলি জাভাস্ক্রিপ্ট ভেরিয়েবলগুলি উত্তোলন করার কারণে তাদের ঘোষণার আগেই তা আরম্ভ করা যেতে পারে এবং ব্যবহার করা যেতে পারে । এর অর্থ হল যে ঘোষণাগুলি সর্বদা সুযোগের শীর্ষে থাকে to
(**) ব্লক স্কোপড ভেরিয়েবলগুলি উত্তোলন করা হয় না
iফাংশন-ব্লকের সর্বত্র পরিচিত! undefinedআপনি কোনও মান নির্ধারণ না করা পর্যন্ত এটি (উত্তোলনের কারণে) হিসাবে শুরু হয়! পিএস: letএছাড়াও উত্তোলন করা হয় (এটিতে ব্লকযুক্ত শীর্ষের অংশে), তবে ReferenceErrorপ্রথম কার্যভারের আগে ব্লকে রেফারেন্স দেওয়া হবে। (পিএস 2: আমি একজন আধিকারিক সেমিকোলন কিন্ডা লোক কিন্তু সত্যিকার অর্থে আপনার কোনও ব্লকের পরে সেমিকোলনের দরকার নেই)। বলা হচ্ছে, সমর্থন সম্পর্কিত বাস্তবতা-চেক যোগ করার জন্য ধন্যবাদ!
letও উত্তোলনের আচরণের পার্থক্য স্পষ্ট করে var!
letএবং কেবলমাত্র যখন তাদের অতিরিক্ত কার্যকারিতা প্রয়োজন হয় কেবল তখনই ব্যবহার করার পরামর্শ দেওয়াconst হয়েছিল , কারণ এই অতিরিক্ত বৈশিষ্ট্যগুলি প্রয়োগ করা / চেক করা (কেবল লেখার জন্য কেবল লেখার মতো) আরও কাজ করে '(এবং স্কোপ-ট্রি-তে অতিরিক্ত স্কোপ-নোড) প্রয়োগ করে (বর্তমান) ইঞ্জিন (গুলি) প্রয়োগ / পরীক্ষা / যাচাই / সেটআপ স্থাপন করতে।
কিছু উদাহরণ সহ কীওয়ার্ডটির ব্যাখ্যাlet এখানে দেওয়া হল ।
letখুব পছন্দ মত কাজ করেvar। মূল পার্থক্য হ'ল একটিvarভেরিয়েবলের সুযোগ হ'ল সম্পূর্ণ এনক্লোজিং ফাংশন
উইকিপিডিয়ায় এই টেবিলটি দেখায় যে কোন ব্রাউজারগুলি জাভাস্ক্রিপ্ট ১.7 সমর্থন করে।
মনে রাখবেন যে কেবল মজিলা এবং ক্রোম ব্রাউজারগুলি এটি সমর্থন করে। আইই, সাফারি এবং সম্ভবত অন্যরা তা করে না।
let msdn.microsoft.com/en-us/library/ie/dn342892%28v=vs.85%29.aspx
গৃহীত উত্তর একটি পয়েন্ট অনুপস্থিত:
{
let a = 123;
};
console.log(a); // ReferenceError: a is not defined
forলুপ ইনিশিয়ালাইজারে এটি প্রদর্শিত হয়েছিল , এর সীমাবদ্ধতার প্রয়োগের সুযোগকে নাটকীয়ভাবে সংকুচিত করে let। সম্মত।
letমূলশব্দ ব্যবহার করে ঘোষিত letচলকগুলি হ'ল ব্লক-স্কোপড, যার অর্থ তারা যে ব্লকটিতে ঘোষিত হয়েছিল কেবল সেগুলিতে এটি উপলব্ধ।
শীর্ষ স্তরে, ভেরিয়েবলগুলি ঘোষিত letবিশ্বব্যাপী বস্তুতে বৈশিষ্ট্য তৈরি করে না using
var globalVariable = 42;
let blockScopedVariable = 43;
console.log(globalVariable); // 42
console.log(blockScopedVariable); // 43
console.log(this.globalVariable); // 42
console.log(this.blockScopedVariable); // undefined
কোনও ফাংশনের অভ্যন্তরে (তবে কোনও ব্লকের বাইরে) letএর মতোই সুযোগ রয়েছে var।
(() => {
var functionScopedVariable = 42;
let blockScopedVariable = 43;
console.log(functionScopedVariable); // 42
console.log(blockScopedVariable); // 43
})();
console.log(functionScopedVariable); // ReferenceError: functionScopedVariable is not defined
console.log(blockScopedVariable); // ReferenceError: blockScopedVariable is not defined
letকোনও ব্লকের অভ্যন্তরে ঘোষিত ভেরিয়েবলগুলি সেই ব্লকের বাইরে অ্যাক্সেস করা যায় না।
{
var globalVariable = 42;
let blockScopedVariable = 43;
console.log(globalVariable); // 42
console.log(blockScopedVariable); // 43
}
console.log(globalVariable); // 42
console.log(blockScopedVariable); // ReferenceError: blockScopedVariable is not defined
letইন লুপগুলির সাথে ঘোষিত চলকগুলি কেবল সেই লুপের অভ্যন্তরেই উল্লেখ করা যেতে পারে।
for (var i = 0; i < 3; i++) {
var j = i * 2;
}
console.log(i); // 3
console.log(j); // 4
for (let k = 0; k < 3; k++) {
let l = k * 2;
}
console.log(typeof k); // undefined
console.log(typeof l); // undefined
// Trying to do console.log(k) or console.log(l) here would throw a ReferenceError.
আপনি যদি কোনও লুপের letপরিবর্তে varপ্রতিটি পুনরাবৃত্তির সাথে ব্যবহার করেন তবে আপনি একটি নতুন ভেরিয়েবল পাবেন। এর অর্থ হ'ল আপনি নিরাপদে একটি লুপের অভ্যন্তরে একটি বন্ধ ব্যবহার করতে পারেন।
// Logs 3 thrice, not what we meant.
for (var i = 0; i < 3; i++) {
setTimeout(() => console.log(i), 0);
}
// Logs 0, 1 and 2, as expected.
for (let j = 0; j < 3; j++) {
setTimeout(() => console.log(j), 0);
}
কারণ সময়গত মৃত জোন , ভেরিয়েবল ব্যবহার ঘোষিত letআগে তারা ঘোষণা করা অ্যাক্সেস করা যাবে না। এটি করার চেষ্টা করা একটি ত্রুটি ছুড়ে দেয়।
console.log(noTDZ); // undefined
var noTDZ = 43;
console.log(hasTDZ); // ReferenceError: hasTDZ is not defined
let hasTDZ = 42;
আপনি একাধিকবার একই পরিবর্তনশীল ঘোষণা করতে পারবেন না let। আপনি letঅন্য ভেরিয়েবলের মতো একই সনাক্তকারী ব্যবহার করে কোনও ভেরিয়েবল ঘোষণা করতে পারবেন না যা ব্যবহারের ঘোষণা দেওয়া হয়েছিল var।
var a;
var a; // Works fine.
let b;
let b; // SyntaxError: Identifier 'b' has already been declared
var c;
let c; // SyntaxError: Identifier 'c' has already been declared
constconstletএটির ব্লক-স্কোপডের সাথে বেশ মিল এবং এতে টিডিজেড রয়েছে। তবে দুটি জিনিস আলাদা different
পরিবর্তনশীল ঘোষিত আবার ব্যবহার করা constযাবে না।
const a = 42;
a = 43; // TypeError: Assignment to constant variable.
মনে রাখবেন যে এর অর্থ এই নয় যে মানটি পরিবর্তনযোগ্য। এর বৈশিষ্ট্যগুলি এখনও পরিবর্তন করা যেতে পারে।
const obj = {};
obj.a = 42;
console.log(obj.a); // 42
আপনি যদি একটি অপরিবর্তনীয় বস্তু রাখতে চান তবে আপনার ব্যবহার করা উচিত Object.freeze()।
ভেরিয়েবলটি ব্যবহার করার সময় আপনাকে সর্বদা একটি মান নির্দিষ্ট করতে হবে const।
const a; // SyntaxError: Missing initializer in const declaration
এখানে উভয়ের মধ্যে পার্থক্যের একটি উদাহরণ রয়েছে (ক্রোমের জন্য সমর্থনটি শুরু হয়েছে):

আপনি দেখতে পাচ্ছেন যে var jভেরিয়েবলটির এখনও লুপ স্কোপ (ব্লক স্কোপ) এর বাইরে একটি মান রয়েছে তবে let iভেরিয়েবলটি লুপ স্কোপের বাইরে অপরিজ্ঞাত।
"use strict";
console.log("var:");
for (var j = 0; j < 2; j++) {
console.log(j);
}
console.log(j);
console.log("let:");
for (let i = 0; i < 2; i++) {
console.log(i);
}
console.log(i);
কিছু সূক্ষ্ম পার্থক্য রয়েছে - letস্কোপিং আরও বেশি বা অন্য যে কোনও ভাষায় ভেরিয়েবল স্কোপিংয়ের মতো আচরণ করে।
উদাহরণস্বরূপ এটি ঘেরটি বন্ধ করে দেওয়া হয়েছে, তারা ঘোষণার আগে এগুলির অস্তিত্ব নেই etc.
তবে এটি লক্ষণীয় যে letএটি কেবলমাত্র নতুন জাভাস্ক্রিপ্ট বাস্তবায়নের একটি অংশ এবং এতে ব্রাউজার সমর্থনের বিভিন্ন ডিগ্রি রয়েছে ।
letএটি 6th ষ্ঠ সংস্করণের খসড়ার অন্তর্ভুক্ত এবং সম্ভবত চূড়ান্ত স্পেসিফিকেশনে থাকবে।
let। সাফারি, আইই এবং চোম সকলেই তা করেন না।
letসংজ্ঞায়িত একটি ভেরিয়েবল ব্যবহার করার জন্য একটি ভাল পয়েন্ট, সতর্ক হওয়া, উত্তোলন করা নয় let। আপনার যদি কোনও ifবিবৃতি থাকে যা কোডের কয়েকটি লাইন এর চেয়ে বেশি থাকে তবে আপনি ভুলে যেতে পারেন যে সংজ্ঞাটি নির্ধারণ না করা পর্যন্ত আপনি সেই পরিবর্তনশীলটি ব্যবহার করতে পারবেন না। মহান পয়েন্ট !!!
let উত্তোলন করবে However তবে, পরিবর্তনশীল ঘোষণার আগে একটি রেফারেন্স এরিয়ারের আগে ব্লকের মধ্যে পরিবর্তনশীল উল্লেখ করা (আমার নোট: ভাল পুরানো পরিবর্তে undefined)) ভেরিয়েবলটি ব্লক শুরু থেকে ঘোষণা প্রক্রিয়া না করা অবধি 'অস্থায়ী ডেড জোনে' থাকে "" একই "সুইটমেন্ট স্টেটমেন্টগুলির জন্য যায় কারণ সেখানে কেবলমাত্র একটি অন্তর্নিহিত ব্লক আছে"। সূত্র: ডেভেলপার.মোজিলা.আর.ইন-
মূল পার্থক্য হ'ল স্কোপ পার্থক্য, যখন আসুন কেবলমাত্র ঘোষিত স্কোপের ভিতরেই এটি উপলব্ধ থাকে , যেমন লুপের জন্য, ভের উদাহরণস্বরূপ লুপের বাইরেও অ্যাক্সেস করা যায়। এমডিএন-তে ডকুমেন্টেশন থেকে ( এমডিএন থেকেও উদাহরণ):
আসুন আপনাকে এমন ভেরিয়েবলগুলি ঘোষিত করার অনুমতি দিন যা ব্লক, বিবৃতি, বা অভিব্যক্তি যা এটি ব্যবহৃত হয় তার সীমাবদ্ধ। এই অসদৃশ হয় Var কীওয়ার্ডটি যা একটি পরিবর্তনশীল ব্লক সুযোগ নির্বিশেষে একটি সম্পূর্ণ ফাংশন বিশ্বব্যাপী, অথবা স্থানীয় ভাবে সংজ্ঞায়িত করে।
চলুন ঘোষিত ভেরিয়েবলগুলি তাদের সুযোগ হিসাবে তাদের যে ব্লকটি সংজ্ঞায়িত করা হয়েছে, সেইসাথে যে কোনও উপ-ব্লক রয়েছে have এইভাবে, ভেরের মতো খুব বেশি কাজ করা যাক । মূল পার্থক্য করে একটি সুযোগ হয় Var পরিবর্তনশীল সমগ্র এনক্লোজিং ফাংশন:
function varTest() {
var x = 1;
if (true) {
var x = 2; // same variable!
console.log(x); // 2
}
console.log(x); // 2
}
function letTest() {
let x = 1;
if (true) {
let x = 2; // different variable
console.log(x); // 2
}
console.log(x); // 1
}`
প্রোগ্রাম এবং ফাংশন উপরের স্তরে, দিন মতো Var , গ্লোবাল বস্তুর উপর একটি সম্পত্তি তৈরি করে না। উদাহরণ স্বরূপ:
var x = 'global';
let y = 'global';
console.log(this.x); // "global"
console.log(this.y); // undefined
যখন কোনও ব্লকের অভ্যন্তরে ব্যবহৃত হয়, চলকের ভেরিয়েবলটিকে সেই ব্লকের মধ্যে সীমাবদ্ধ করি। যেখানে ঘোষিত হয়েছে সেই ফাংশনের অভ্যন্তরের ভেরের মধ্যে পার্থক্যটি নোট করুন ।
var a = 1;
var b = 2;
if (a === 1) {
var a = 11; // the scope is global
let b = 22; // the scope is inside the if-block
console.log(a); // 11
console.log(b); // 22
}
console.log(a); // 11
console.log(b); // 2
এছাড়াও এটি ECMA6 বৈশিষ্ট্যটি ভুলে যাবেন না, তাই এটি এখনও সম্পূর্ণ সমর্থনযোগ্য নয়, তাই এটি সর্বদা ব্যাবেল ইত্যাদি ব্যবহার করে এটি ECMA5 এ স্থানান্তর করে ... ভিজিট বেবেল ওয়েবসাইট সম্পর্কে আরও তথ্যের জন্য
চলক নয় উত্তোলন
letহবে না উত্তোলন ব্লক তারা প্রদর্শিত সমস্ত সুযোগ কাজে করতে। বিপরীতে varনীচের হিসাবে উত্তোলন পারে।
{
console.log(cc); // undefined. Caused by hoisting
var cc = 23;
}
{
console.log(bb); // ReferenceError: bb is not defined
let bb = 23;
}
আসলে, প্রতি @ বার্গী, উভয় varএবং letউত্তোলন করা হয়েছে ।
আবর্জনা সংগ্রহ
ব্লক স্কোপ letমেমরির পুনরায় দাবি করতে ক্লোজার এবং আবর্জনা সংগ্রহের সাথে সম্পর্কিত। বিবেচনা,
function process(data) {
//...
}
var hugeData = { .. };
process(hugeData);
var btn = document.getElementById("mybutton");
btn.addEventListener( "click", function click(evt){
//....
});
clickহ্যান্ডলার কলব্যাক দরকার নেই hugeDataএ সব পরিবর্তনশীল। তাত্ত্বিকভাবে, process(..)রান করার পরে , বিশাল ডেটা কাঠামো hugeDataআবর্জনা সংগ্রহ করা যেতে পারে। যাইহোক, এটি সম্ভব যে কিছু জেএস ইঞ্জিনকে এখনও এই বিশাল কাঠামোটি রাখতে হবে, যেহেতু clickফাংশনটির পুরো ব্যাপ্তিটি বন্ধ রয়েছে।
যাইহোক, ব্লক স্কোপ সংগ্রহ করা আবর্জনা থেকে এই বিশাল ডেটা কাঠামো তৈরি করতে পারে।
function process(data) {
//...
}
{ // anything declared inside this block can be garbage collected
let hugeData = { .. };
process(hugeData);
}
var btn = document.getElementById("mybutton");
btn.addEventListener( "click", function click(evt){
//....
});let লুপ
letলুপ করতে -শুশ্রূষা পুনরায় এটা লুপ প্রতিটি পুনরাবৃত্তির, এর নিশ্চিত করার জন্য এটি পূর্ববর্তী লুপ পুনরাবৃত্তির শেষে থেকে মান পুনরায় নির্ধারণ করুন। বিবেচনা,
// print '5' 5 times
for (var i = 0; i < 5; ++i) {
setTimeout(function () {
console.log(i);
}, 1000);
}
তবে এর varসাথে প্রতিস্থাপন করুনlet
// print 1, 2, 3, 4, 5. now
for (let i = 0; i < 5; ++i) {
setTimeout(function () {
console.log(i);
}, 1000);
}
যেহেতু letএগুলির সাথে একটি নামের সাথে একটি নতুন লেজিকাল পরিবেশ তৈরি করুন) ক) প্রারম্ভিক অভিব্যক্তি খ) প্রতিটি পুনরাবৃত্তি (বর্ধিত অভিব্যক্তি মূল্যায়নের প্রাকদর্শন), আরও বিশদ এখানে রয়েছে ।
অন্যরা ইতিমধ্যে যা লিখেছিল তাতে যুক্ত করার জন্য এখানে একটি উদাহরণ। ধরুন আপনি ফাংশনগুলির একটি অ্যারে তৈরি করতে চান adderFunctions, যেখানে প্রতিটি ফাংশন একটি একক সংখ্যা আর্গুমেন্ট নেয় এবং অ্যারের মধ্যে যুক্তির যোগফল এবং ফাংশনের সূচকটি প্রদান করে। কীওয়ার্ডটি adderFunctionsব্যবহার করে একটি লুপের সাহায্যে উত্পন্ন করার চেষ্টা varকারওভাবে নির্লিপ্তভাবে প্রত্যাশার উপায়টির সাথে কাজ করবে না:
// An array of adder functions.
var adderFunctions = [];
for (var i = 0; i < 1000; i++) {
// We want the function at index i to add the index to its argument.
adderFunctions[i] = function(x) {
// What is i bound to here?
return x + i;
};
}
var add12 = adderFunctions[12];
// Uh oh. The function is bound to i in the outer scope, which is currently 1000.
console.log(add12(8) === 20); // => false
console.log(add12(8) === 1008); // => true
console.log(i); // => 1000
// It gets worse.
i = -8;
console.log(add12(8) === 0); // => true
উপরের প্রক্রিয়াটি ফাংশনগুলির কাঙ্ক্ষিত অ্যারে তৈরি করে না কারণ এর কার্যকারিতা ব্লকটির iপুনরাবৃত্তির বাইরে প্রসারিত forযেখানে প্রতিটি ফাংশন তৈরি হয়েছিল। পরিবর্তে, লুপের শেষে, iপ্রতিটি ফাংশনটির সমাপ্তিতে iপ্রতিটি অনামী ফাংশনের জন্য লুপের শেষে (1000) এর মান বোঝায় adderFunctions। এটি আমরা যা চেয়েছিলাম তা নয়: আমাদের কাছে এখন একই আচরণের সাথে মেমরিতে 1000 টি বিভিন্ন ফাংশন রয়েছে। এবং যদি আমরা পরবর্তীকালে এর মান আপডেট করি iতবে মিউটেশনটি সমস্তগুলিকে প্রভাবিত করে adderFunctions।
তবে আমরা letকীওয়ার্ডটি ব্যবহার করে আবার চেষ্টা করতে পারি :
// Let's try this again.
// NOTE: We're using another ES6 keyword, const, for values that won't
// be reassigned. const and let have similar scoping behavior.
const adderFunctions = [];
for (let i = 0; i < 1000; i++) {
// NOTE: We're using the newer arrow function syntax this time, but
// using the "function(x) { ..." syntax from the previous example
// here would not change the behavior shown.
adderFunctions[i] = x => x + i;
}
const add12 = adderFunctions[12];
// Yay! The behavior is as expected.
console.log(add12(8) === 20); // => true
// i's scope doesn't extend outside the for loop.
console.log(i); // => ReferenceError: i is not defined
এবার লুপের iপ্রতিটি পুনরাবৃত্তিতে রিবাউন্ড করা হবে for। প্রতিটি ফাংশন এখন iফাংশনটি তৈরির সময় এর মান রাখে এবং adderFunctionsপ্রত্যাশার মতো আচরণ করে।
এখন, চিত্র দুটি আচরণের মিশ্রণ করছে এবং আপনি সম্ভবত এটি একই স্ক্রিপ্টে আরও নতুন letএবং constআরও পুরানোগুলির সাথে মেশার প্রস্তাব দেওয়া হয়নি কেন not varএটি করার ফলে কিছু দর্শনীয় বিভ্রান্তিকর কোড হতে পারে।
const doubleAdderFunctions = [];
for (var i = 0; i < 1000; i++) {
const j = i;
doubleAdderFunctions[i] = x => x + i + j;
}
const add18 = doubleAdderFunctions[9];
const add24 = doubleAdderFunctions[12];
// It's not fun debugging situations like this, especially when the
// code is more complex than in this example.
console.log(add18(24) === 42); // => false
console.log(add24(18) === 42); // => false
console.log(add18(24) === add24(18)); // => false
console.log(add18(24) === 2018); // => false
console.log(add24(18) === 2018); // => false
console.log(add18(24) === 1033); // => true
console.log(add24(18) === 1030); // => true
এটি আপনার হতে দেবেন না। একটি লিটার ব্যবহার করুন।
দ্রষ্টব্য: এটি এমন একটি শিক্ষণ উদাহরণ যা লুপগুলিতে
var/letফাংশন ক্লোজারের সাথে এবং আচরণটি বোঝাও সহজ to এটি সংখ্যার যোগ করার এক ভয়ঙ্কর উপায়। তবে বেনামে ফাংশন ক্লোজারে ডেটা ক্যাপচারের সাধারণ কৌশলটি অন্যান্য প্রসঙ্গে প্রকৃত বিশ্বে সম্মুখীন হতে পারে। YMMV।
let value = i;। forবক্তব্য আভিধানিক ব্লক তৈরি করে।
পার্থক্যটি প্রতিটি দ্বারা ঘোষিত ভেরিয়েবলের সুযোগে ।
অনুশীলনে, সুযোগের পার্থক্যের বেশ কয়েকটি দরকারী পরিণতি রয়েছে:
letভেরিয়েবলগুলি কেবল তাদের নিকটস্থ এনক্লোজিং ব্লক ( { ... }) এ দৃশ্যমান ।letভেরিয়েবলগুলি কেবল কোডের লাইনে ব্যবহারযোগ্য হয় যা ভেরিয়েবল ঘোষণার পরে ঘটে (যদিও তারা উত্তোলন করা হয় !)।letভেরিয়েবলগুলি পরবর্তী varবা দ্বারা পুনরায় ঘোষিত হতে পারে না let।letভেরিয়েবল যুক্ত হয় না window।letভেরিয়েবলগুলি ক্লোজারগুলির সাথে ব্যবহার করা সহজ (তারা জাতিগুলির শর্ত সৃষ্টি করে না )।letভেরিয়েবলের দৃশ্যমানতা হ্রাস করার ফলে আরোপিত বিধিনিষেধগুলি এবং অপ্রত্যাশিত নামের সংঘর্ষগুলি খুব শীঘ্রই পাওয়া যাওয়ার সম্ভাবনা বাড়িয়ে তোলে। এটি ভেরিয়েবলগুলির সাথে তার পুনঃব্যবহারযোগ্যতা (অব্যবহৃত স্মৃতি পুনরুদ্ধার করতে সহায়তা) সহ ট্র্যাক করা এবং যুক্তি করা সহজ করে তোলে ।
ফলস্বরূপ, letবড় প্রোগ্রামগুলিতে ব্যবহার করার সময় বা স্বতঃ-বিকাশযুক্ত ফ্রেমওয়ার্কগুলি যখন নতুন এবং অপ্রত্যাশিত উপায়ে সংযুক্ত করা হয় তখন ভেরিয়েবলগুলি সমস্যা হওয়ার সম্ভাবনা কম থাকে।
varলুপ (# 5) এ ক্লোজার ব্যবহার করার সময় বা আপনার কোডে (# 4) বাহ্যিকভাবে দৃশ্যমান গ্লোবাল ভেরিয়েবলগুলি ঘোষণার জন্য আপনি যদি একক-বাঁধাইয়ের প্রভাবটি নিশ্চিত করতে চান তবে এখনও দরকারী হতে পারে। ট্রান্সপনার স্থানের বাইরে এবং মূল ভাষায় স্থানান্তরিত varহলে রফতানির জন্য ব্যবহারের প্রয়োজন পড়তে পারে export।
১. নিকটতম এনকোলেজিং ব্লকের বাইরে কোনও ব্যবহার নেই:
কোডের এই ব্লকটি একটি রেফারেন্স ত্রুটি ছুঁড়ে দেবে কারণ এর দ্বিতীয় ব্যবহারটি xযেখানে ব্লকটির বাইরে ঘোষণা করা হয় তার বাইরে ঘটে let:
{
let x = 1;
}
console.log(`x is ${x}`); // ReferenceError during parsing: "x is not defined".
বিপরীতে, varকাজ সঙ্গে একই উদাহরণ ।
২. ঘোষণার আগে কোনও ব্যবহার নেই: কোডটি চালানোর আগে
এই ব্লকটি কোডটি ReferenceErrorচালিত হওয়ার আগে এটি নিক্ষেপ করবে কারণ xএটি ঘোষণার আগে ব্যবহার করা হয়েছে:
{
x = x + 1; // ReferenceError during parsing: "x is not defined".
let x;
console.log(`x is ${x}`); // Never runs.
}
বিপরীতে, varপার্স এবং একই ব্যতিক্রম ব্যতীত কোনও উদাহরণ ছাড়াই চলে।
৩. কোনও পুনঃসংশোধন নয়:
নিম্নলিখিত কোডটি দেখায় যে ঘোষিত একটি চলক letপরে পুনরায় ঘোষিত হতে পারে না:
let x = 1;
let x = 2; // SyntaxError: Identifier 'x' has already been declared
৪) গ্লোবালগুলির সাথে সংযুক্ত নেই window:
var button = "I cause accidents because my name is too common.";
let link = "Though my name is common, I am harder to access from other JS files.";
console.log(link); // OK
console.log(window.link); // undefined (GOOD!)
console.log(window.button); // OK
৫. ক্লোজারগুলির সাথে সহজে ব্যবহার:
ভেরিয়েবলগুলি varলুপের অভ্যন্তরে বন্ধ হওয়ার সাথে ভাল কাজ করে না বলে ঘোষিত হয় । এখানে একটি সরল লুপ যা ভেরিয়েবলের iবিভিন্ন বিন্দুতে বিভিন্ন মানের ক্রমকে ছাড়িয়ে যায় :
for (let i = 0; i < 5; i++) {
console.log(`i is ${i}`), 125/*ms*/);
}
বিশেষত, এই ফলাফলগুলি:
i is 0
i is 1
i is 2
i is 3
i is 4
জাভাস্ক্রিপ্টে আমরা প্রায়শই ভেরিয়েবলগুলি তৈরি হওয়ার চেয়ে পরবর্তী সময়ে উল্লেখ করি। আমরা যখন বন্ধ হয়ে যাওয়ার সাথে সাথে আউটপুটটি বিলম্ব করে এটি প্রদর্শিত করিsetTimeout :
for (let i = 0; i < 5; i++) {
setTimeout(_ => console.log(`i is ${i}`), 125/*ms*/);
}
... যতক্ষণ না আমরা আটকে থাকি আউটপুট অপরিবর্তিত থাকে let। বিপরীতে, যদি আমরা ব্যবহার করতামvar i পরিবর্তে :
for (var i = 0; i < 5; i++) {
setTimeout(_ => console.log(`i is ${i}`), 125/*ms*/);
}
... লুপটি অপ্রত্যাশিতভাবে পাঁচবার "আমি 5" আউটপুট করে:
i is 5
i is 5
i is 5
i is 5
i is 5
varপরিবর্তে ব্যবহার করে let, কোডটি সমান: var i = 0; while (i < 5) { doSomethingLater(); i++; } iসমাপ্তির বাইরে এবং doSomethingLater()কার্যকর হওয়ার সময় iইতিমধ্যে 5 বার বৃদ্ধি করা হয়েছে, সুতরাং আউটপুট i is 5পাঁচগুণ। ব্যবহার করে let, ভেরিয়েবলটি iবন্ধের মধ্যেই থাকে, সুতরাং প্রতিটি অ্যাসিঙ্ক কল তার iসাথে তৈরি 'গ্লোবাল' ব্যবহারের পরিবর্তে তার নিজস্ব অনুলিপি পায় var।
for। আরও জটিল রূপান্তর, যদিও আরও জটিল, তবে ধ্রুপদী for (var i = 0; i < 5; i++) { (function(j) { setTimeout(_ => console.log(i is {j} ), 125/*ms*/); })(i); }যা ফাংশনের অভ্যন্তরের iনামের সাথে প্রতিটি মান সংরক্ষণ করতে একটি "ফাংশন-অ্যাক্টিভেশন রেকর্ড" প্রবর্তন jকরে।
নিম্নলিখিত দুটি ফাংশন পার্থক্য প্রদর্শন করতে পারে:
function varTest() {
var x = 31;
if (true) {
var x = 71; // Same variable!
console.log(x); // 71
}
console.log(x); // 71
}
function letTest() {
let x = 31;
if (true) {
let x = 71; // Different variable
console.log(x); // 71
}
console.log(x); // 31
}
let আকর্ষণীয়, কারণ এটি আমাদের এর মতো কিছু করতে দেয়:
(() => {
var count = 0;
for (let i = 0; i < 2; ++i) {
for (let i = 0; i < 2; ++i) {
for (let i = 0; i < 2; ++i) {
console.log(count++);
}
}
}
})();
ফলাফল গণনা [0, 7]।
যেহেতু
(() => {
var count = 0;
for (var i = 0; i < 2; ++i) {
for (var i = 0; i < 2; ++i) {
for (var i = 0; i < 2; ++i) {
console.log(count++);
}
}
}
})();
কেবল গণনা করা হয় [0, 1]
মধ্যে মূল পার্থক্য varএবং letযে ভেরিয়েবল ঘোষিত হয় varহয় ফাংশন scoped । যেখানে ফাংশন ঘোষিত letহয় ব্লক scoped । উদাহরণ স্বরূপ:
function testVar () {
if(true) {
var foo = 'foo';
}
console.log(foo);
}
testVar();
// logs 'foo'
function testLet () {
if(true) {
let bar = 'bar';
}
console.log(bar);
}
testLet();
// reference error
// bar is scoped to the block of the if statement
এর সাথে ভেরিয়েবল var:
যখন প্রথম ফাংশনটি testVarভেরিয়েবল ফু হিসাবে ডাকা হয়, ঘোষিত varহয় তখনও ifস্টেটমেন্টের বাইরে অ্যাক্সেসযোগ্য । এই পরিবর্তনশীল ফাংশনের সুযোগের মধ্যে সর্বত্রfoo উপলব্ধ ।testVar
এর সাথে ভেরিয়েবল let:
দ্বিতীয় ফাংশনটি যখন testLetভেরিয়েবল বার নামে ডাকা হয়, তখন ঘোষিত হয় let, কেবলমাত্র ifস্টেটমেন্টের ভিতরেই অ্যাক্সেসযোগ্য । কারণ ভেরিয়েবল ঘোষিত letহয় ব্লক scoped (যেখানে একটি ব্লক কোঁকড়া বন্ধনী মধ্যে কোড উদাঃ if{}, for{}, function{})।
let ভেরিয়েবলগুলি উত্তোলন করা হবে না:মধ্যে আরেকটি পার্থক্য varএবং letসঙ্গে ঘোষিত ভেরিয়েবল হল let উত্তোলন পেতে না । এই আচরণটি চিত্রিত করার সর্বোত্তম উপায় উদাহরণ:
ভেরিয়েবলগুলি উত্তোলন let করবেন না :
console.log(letVar);
let letVar = 10;
// referenceError, the variable doesn't get hoisted
সঙ্গে ভেরিয়েবল var Do পেতে উত্তোলন:
console.log(varVar);
var varVar = 10;
// logs undefined, the variable gets hoisted
letসাথে যুক্ত হয় না window:letগ্লোবাল স্কোপের সাথে ঘোষিত একটি পরিবর্তনশীল (যা কোড যা কোনও ফাংশনে নেই) বৈশ্বিক windowঅবজেক্টে সম্পত্তি হিসাবে যুক্ত হয় না । উদাহরণস্বরূপ (এই কোডটি বিশ্বব্যাপী সুযোগে রয়েছে):
var bar = 5;
let foo = 10;
console.log(bar); // logs 5
console.log(foo); // logs 10
console.log(window.bar);
// logs 5, variable added to window object
console.log(window.foo);
// logs undefined, variable not added to window object
কখন
letব্যবহার করা উচিতvar?
ব্যবহার করুন letউপর varযখনই আপনি কারণ এটি সহজভাবে আরও নির্দিষ্ট scoped হয় পারবেন না। এটি সম্ভাব্য নামকরণের বিরোধগুলি হ্রাস করে যা প্রচুর পরিমাণে ভেরিয়েবলের সাথে ডিল করার সময় ঘটতে পারে। varআপনি যখন বিশ্বব্যাপী পরিবর্তনশীলটি স্পষ্টভাবে windowঅবজেক্টটিতে থাকতে চান তখন ব্যবহার করা যেতে পারে (এটি সত্যই প্রয়োজনীয় কিনা সর্বদা সাবধানতার সাথে বিবেচনা করুন)।
var বিশ্বব্যাপী সুযোগ (উত্তোলন-সক্ষম) পরিবর্তনশীল।
letএবং constব্লক সুযোগ।
test.js
{
let l = 'let';
const c = 'const';
var v = 'var';
v2 = 'var 2';
}
console.log(v, this.v);
console.log(v2, this.v2);
console.log(l); // ReferenceError: l is not defined
console.log(c); // ReferenceError: c is not defined
ব্যবহার করার সময় let
letশব্দ যাই হোক না কেন ব্লক (সাধারণত একটি সুযোগ পরিবর্তনশীল ঘোষণা সংযুক্ত { .. }জোড়া) এটি অন্তর্ভুক্ত হচ্ছে। অন্য কথায়, letপরোক্ষভাবে তার পরিবর্তনশীল ঘোষণা কোনো ব্লক এর সুযোগ hijacks।
letভেরিয়েবলগুলি windowবস্তুটিতে অ্যাক্সেস করা যায় না কারণ তারা বিশ্বব্যাপী অ্যাক্সেস করতে পারে না।
function a(){
{ // this is the Max Scope for let variable
let x = 12;
}
console.log(x);
}
a(); // Uncaught ReferenceError: x is not defined
ব্যবহার করার সময় var
var এবং ES5 এর ভেরিয়েবলগুলির ফাংশনগুলিতে স্কোপ রয়েছে যার অর্থ ভেরিয়েবলগুলি ফাংশনের মধ্যে বৈধ হয় এবং এটি ফাংশনের বাইরে নয় outside
varভেরিয়েবলগুলি windowঅবজেক্টে অ্যাক্সেস করা যায় কারণ তারা বিশ্বব্যাপী অ্যাক্সেস করতে পারে না।
function a(){ // this is the Max Scope for var variable
{
var x = 12;
}
console.log(x);
}
a(); // 12
আপনি জানতে চাইলে নীচে পড়া চালিয়ে যান
স্কোপে সবচেয়ে বিখ্যাত একটি সাক্ষাত্কারের প্রশ্নগুলির যথাযথ ব্যবহার letএবং varনীচে হিসাবে যথেষ্ট হতে পারে ;
ব্যবহার করার সময় let
for (let i = 0; i < 10 ; i++) {
setTimeout(
function a() {
console.log(i); //print 0 to 9, that is literally AWW!!!
},
100 * i);
}
এটি কারণ letপ্রতিটি লুপ পুনরাবৃত্তির জন্য ব্যবহার করার সময় ভেরিয়েবলটি স্কোপ করা হয় এবং এর নিজস্ব অনুলিপি রয়েছে।
ব্যবহার করার সময় var
for (var i = 0; i < 10 ; i++) {
setTimeout(
function a() {
console.log(i); //print 10 times 10
},
100 * i);
}
এটি কারণ varপ্রতিটি লুপ পুনরাবৃত্তির জন্য ব্যবহার করার সময় ভেরিয়েবলটি স্কোপ করা হয় এবং ভাগ করা অনুলিপি থাকে।
আমি যদি চশমাটি ঠিক তখনই পড়ে থাকি তবে let কৃতজ্ঞতাপূর্ণভাবে কেবল ব্যক্তিগত সদস্যদের অনুকরণ করার জন্য ব্যবহৃত স্ব-অনুরোধমূলক ক্রিয়াগুলি এড়াতেও উপকার করা যেতে পারে - একটি জনপ্রিয় ডিজাইনের প্যাটার্ন যা কোড পাঠযোগ্যতা হ্রাস করে, ডিবাগিংকে জটিল করে তোলে, এতে কোনও আসল কোড সুরক্ষা বা অন্যান্য সুবিধা যুক্ত হয় না - সম্ভবত কারও সন্তুষ্টি ছাড়া শব্দার্থবিজ্ঞানের জন্য আকাঙ্ক্ষা, সুতরাং এটি ব্যবহার বন্ধ করুন। / গলাবাজি
var SomeConstructor;
{
let privateScope = {};
SomeConstructor = function SomeConstructor () {
this.someProperty = "foo";
privateScope.hiddenProperty = "bar";
}
SomeConstructor.prototype.showPublic = function () {
console.log(this.someProperty); // foo
}
SomeConstructor.prototype.showPrivate = function () {
console.log(privateScope.hiddenProperty); // bar
}
}
var myInstance = new SomeConstructor();
myInstance.showPublic();
myInstance.showPrivate();
console.log(privateScope.hiddenProperty); // error
'দেখুন ব্যক্তিগত ইন্টারফেসগুলি এমুলেট '
let? (আমি ধরে নিলাম "স্ব-আহ্বানকারী ফাংশন" দিয়ে আপনার অর্থ IIFE mean)
hiddenPropertyকনস্ট্রাক্টরে সেট করবেন ? hiddenPropertyআপনার "শ্রেণিতে" সমস্ত দৃষ্টান্তের জন্য কেবল একটিই রয়েছে ।
for (let i = 0; i < 5; i++) {
// i accessible ✔️
}
// i not accessible ❌
for (var i = 0; i < 5; i++) {
// i accessible ✔️
}
// i accessible ✔️
Around স্যান্ডবক্স প্রায় খেলা ↓
কিছু হ্যাক সঙ্গে let :
1।
let statistics = [16, 170, 10];
let [age, height, grade] = statistics;
console.log(height)
2।
let x = 120,
y = 12;
[x, y] = [y, x];
console.log(`x: ${x} y: ${y}`);
3।
let node = {
type: "Identifier",
name: "foo"
};
let { type, name, value } = node;
console.log(type); // "Identifier"
console.log(name); // "foo"
console.log(value); // undefined
let node = {
type: "Identifier"
};
let { type: localType, name: localName = "bar" } = node;
console.log(localType); // "Identifier"
console.log(localName); // "bar"
let:let jar = {
numberOfCookies: 10,
get cookies() {
return this.numberOfCookies;
},
set cookies(value) {
this.numberOfCookies = value;
}
};
console.log(jar.cookies)
jar.cookies = 7;
console.log(jar.cookies)
let { type, name, value } = node; ? আপনি 3 টি বৈশিষ্ট্য / নাম / মান দিয়ে একটি নতুন অবজেক্ট তৈরি করেন এবং নোড থেকে বৈশিষ্ট্যগুলির মান দিয়ে তাদের সূচনা করেন?
varখুব নিখুঁতভাবে কাজ করে।
চলুন বনাম। এটা সব সুযোগ সম্পর্কে ।
ভেরিয়েবলগুলি বিশ্বব্যাপী এবং মূলত সর্বত্র অ্যাক্সেস করা যায়, তবে চলকগুলি বৈশ্বিক নয় এবং কেবলমাত্র বন্ধ হওয়া বন্ধনী তাদের হত্যা না করা পর্যন্ত উপস্থিত থাকে exist
নীচে আমার উদাহরণটি দেখুন এবং লক্ষ করুন যে সিংহ (চলুন) পরিবর্তনশীল দুটি কনসোল.লগগুলিতে কীভাবে ভিন্নভাবে কাজ করে; এটি ২ য় কনসোল.লগের বাইরে চলে যায়।
var cat = "cat";
let dog = "dog";
var animals = () => {
var giraffe = "giraffe";
let lion = "lion";
console.log(cat); //will print 'cat'.
console.log(dog); //will print 'dog', because dog was declared outside this function (like var cat).
console.log(giraffe); //will print 'giraffe'.
console.log(lion); //will print 'lion', as lion is within scope.
}
console.log(giraffe); //will print 'giraffe', as giraffe is a global variable (var).
console.log(lion); //will print UNDEFINED, as lion is a 'let' variable and is now out of scope.
ES6 দুটি নতুন শব্দ (চালু দিন এবং const ) এর বিকল্প Var ।
যখন আপনার ব্লক স্তরের হ্রাস প্রয়োজন তখন আপনি বর্ণের পরিবর্তে লেট এবং কনস্টের সাথে যেতে পারেন।
নীচের সারণিতে বর্ণ, লে এবং কনস্টের মধ্যে পার্থক্যটির সংক্ষিপ্তসার জানানো হয়েছে
আসুন এস 6 এর একটি অংশ is এই ফাংশনগুলি সহজ উপায়ে পার্থক্যটি ব্যাখ্যা করবে।
function varTest() {
var x = 1;
if (true) {
var x = 2; // same variable!
console.log(x); // 2
}
console.log(x); // 2
}
function letTest() {
let x = 1;
if (true) {
let x = 2; // different variable
console.log(x); // 2
}
console.log(x); // 1
}
নীচে দেখায় যে কীভাবে 'লেট' এবং 'ভ্যার' সুযোগটি আলাদা different
let gfoo = 123;
if (true) {
let gfoo = 456;
}
console.log(gfoo); // 123
var hfoo = 123;
if (true) {
var hfoo = 456;
}
console.log(hfoo); // 456
gfoo, দ্বারা সংজ্ঞায়িত letপ্রাথমিকভাবে রয়েছে বিশ্বব্যাপী সুযোগ , এবং যখন আমরা ঘোষণা gfooভিতরে আবার if clauseতার সুযোগ পরিবর্তিত এবং একটি নতুন মান সুযোগ ভিতরে পরিবর্তনশীল নির্ধারিত হয় এটা কোনো প্রভাব পড়ে না বিশ্বব্যাপী সুযোগ।
অন্যদিকে hfoo, সংজ্ঞায়িতটি varপ্রথমদিকে বিশ্বব্যাপী স্কোপে রয়েছে তবে আবার যখন আমরা এটিকে এর অভ্যন্তরে ঘোষণা করি তখন if clauseএটি বিশ্বব্যাপী স্কোপ hfoo বিবেচনা করে, যদিও এটি আবার ঘোষণার জন্য var ব্যবহার করা হয়েছে। এবং যখন আমরা এর মানটি পুনরায় বরাদ্দ করি তখন আমরা দেখতে পাই যে বিশ্বব্যাপী স্কোপ hfoo প্রভাবিত হয়েছে। এটি প্রাথমিক পার্থক্য।
উপরে উল্লিখিত:
পার্থক্যটি স্কোপিংয়ের।
varনিকটতম করার scoped হয় ফাংশন ব্লক এবংletকরতে scoped হয় নিকটতম এনক্লোজিং ব্লক , যা একটি ফাংশন ব্লক চেয়ে ছোট হতে পারে। যে কোনও ব্লকের বাইরে থাকলে উভয়ই বিশ্বব্যাপী L একটি উদাহরণ দেখুন:
Example1:
আমার উভয় উদাহরণে আমার একটি ফাংশন রয়েছে myfunc। 10 এর সমান myfuncএকটি ভেরিয়েবল থাকে myvar। আমার প্রথম উদাহরণে আমি myvar10 ( myvar==10) এর সমান কিনা তা পরীক্ষা করে দেখি । যদি হ্যাঁ, আমি এগ্রিয়ান কীওয়ার্ডটি myvarব্যবহার করে একটি ভেরিয়েবল (এখন আমার কাছে দুটি মাইভার ভেরিয়েবল রয়েছে) ঘোষণা করে varএটি একটি নতুন মান (20) নির্ধারণ করে। পরের লাইনে আমি এর কনসোলটিতে এর মানটি মুদ্রণ করি। শর্তাধীন ব্লকের পরে আমি আবার myvarআমার কনসোলের মানটি মুদ্রণ করি। যদি আপনি এর আউটপুট তাকান myfunc, myvarমান 20 সমান হয়।
Example2:
পরিবর্তে ব্যবহার করার আমার দ্বিতীয় উদাহরণে varআমার শর্তাধীন ব্লক আমি ঘোষণা মধ্যে শব্দ myvarব্যবহার letশব্দ। এখন যখন আমি কল myfunc করি তখন আমি দুটি ভিন্ন আউটপুট পাই: myvar=20এবং myvar=10।
সুতরাং পার্থক্যটি খুব সহজ অর্থাত্ এর স্কোপ।
আমি এই কীওয়ার্ডগুলিকে এক্সিকিউশন কনটেক্সট-এর সাথে লিঙ্ক করতে চাই, কারণ এগুলির মধ্যে এক্সিকিউশন কনটেক্সটটি গুরুত্বপূর্ণ। এক্সিকিউশন কনটেক্সটে দুটি পর্যায় রয়েছে: একটি ক্রেশন ফেজ এবং এক্সিকিউশন ফেজ। এছাড়াও, প্রতিটি নির্বাহ প্রসঙ্গে একটি চলক পরিবেশ এবং বহিরাগত পরিবেশ (এর লেক্সিকাল পরিবেশ) থাকে।
একটি এক্সিকিউশন কনটেক্সট এর ক্রেশন ফেজ চলাকালীন, চলুন এবং কনট এখনও প্রদত্ত এক্সিকিউশন কনটেক্সটের ভেরিয়েবল এনভায়রনমেন্টে একটি অপরিবর্তিত মান সহ স্মৃতিতে এর পরিবর্তনশীল সংরক্ষণ করবে। পার্থক্যটি এক্সিকিউশন পর্বে। কোনও মান নির্ধারিত হওয়ার আগে আপনি যদি ভেরিয়েবলের সাথে ভ্যারিয়েবলের সংজ্ঞা দেওয়া হয় তবে এটি কেবল অপরিজ্ঞাত হবে। কোন ব্যতিক্রম উত্থাপিত হবে না।
যাইহোক, আপনি ঘোষিত পরিবর্তন বা রেট না দেওয়া পর্যন্ত কনস্টের সাথে উল্লেখ করতে পারবেন না যতক্ষণ না এটি ঘোষিত হয়। যদি আপনি এটি ঘোষণার আগে এটি ব্যবহার করার চেষ্টা করেন, তবে এক্সিকিউশন কনটেক্সটের এক্সিকিউশন পর্বের সময় একটি ব্যতিক্রম উত্থাপিত হবে। এখন পরিবর্তনশীলটি এখনও মেমোরিতে থাকবে, এক্সিকিউশন কনটেক্সটের ক্রিয়েশন ফেজের সৌজন্যে, তবে ইঞ্জিন আপনাকে এটি ব্যবহার করতে দেয় না:
function a(){
b;
let b;
}
a();
> Uncaught ReferenceError: b is not defined
ভেরিয়েবলের সাথে সংজ্ঞায়িত ভেরিয়েবলের সাথে ইঞ্জিন যদি বর্তমান এক্সিকিউশন কনটেক্সট এর ভেরিয়েবল পরিবেশে পরিবর্তনশীলটি খুঁজে না পায়, তবে এটি স্কোপ চেইন (আউটার এনভায়রনমেন্ট) এ যাবে এবং ভেরিয়েবলের জন্য আউটরের পরিবেশের পরিবর্তনশীল পরিবেশ পরীক্ষা করবে। এটি যদি এটি সেখানে না খুঁজে পায় তবে এটি স্কোপ চেইন অনুসন্ধান চালিয়ে যাবে। লেট এবং কনস্টের ক্ষেত্রে এটি হয় না।
আসুন দ্বিতীয় বৈশিষ্ট্য এটি ব্লক সুযোগ প্রবর্তন করে। ব্লকগুলি কোঁকড়া ধনুর্বন্ধনী দ্বারা সংজ্ঞায়িত করা হয়। উদাহরণগুলির মধ্যে ফাংশন ব্লকগুলি অন্তর্ভুক্ত থাকে, যদি ব্লকগুলি, ব্লকের জন্য ইত্যাদি a প্রকৃতপক্ষে, প্রতিটি সময় ব্লকটি চালানো হয়, যেমন একটি লুপের মধ্যে, এটি মেমরিতে একটি নতুন পরিবর্তনশীল তৈরি করে।
ES6 ভেরিয়েবলগুলি ঘোষণার জন্য কনস্ট কীওয়ার্ডটিও উপস্থাপন করে। কনস্টও ব্লক স্কোপড। লেট এবং কনস্টের মধ্যে পার্থক্য হ'ল কনস্টেন্ট ভেরিয়েবলগুলি ইনিশিয়ালাইজার ব্যবহার করে ঘোষণা করা দরকার, অথবা এটি একটি ত্রুটি তৈরি করবে।
এবং অবশেষে, যখন এটি এক্সিকিউশন প্রসঙ্গে আসে, var এর সাথে সংজ্ঞায়িত ভেরিয়েবলগুলি 'এই' বস্তুর সাথে সংযুক্ত করা হবে। গ্লোবাল এক্সিকিউশন প্রসঙ্গে, এটি ব্রাউজারগুলিতে উইন্ডো অবজেক্ট হবে। এটি লেট বা কনস্টের ক্ষেত্রে নয়।
আমি মনে করি শর্তাদি এবং বেশিরভাগ উদাহরণগুলি কিছুটা অপ্রতিরোধ্য, আমি ব্যক্তিগতভাবে পার্থক্যটির সাথে মূল বিষয়টিটি "ব্লক" কী তা বোঝা। এক পর্যায়ে আমি বুঝতে পারি, একটি ব্লক IFবিবৃতি ব্যতীত কোনও কোঁকড়ানো বন্ধনী হবে । একটি {ফাংশন বা লুপের একটি খোলার ব্র্যাকেট একটি নতুন ব্লককে সংজ্ঞায়িত letকরবে, এর মধ্যে যা কিছু সংজ্ঞায়িত করা হবে, }একই জিনিস (ফাংশন বা লুপ) বন্ধ করার বন্ধনী পরে পাওয়া যাবে না ; এটি মনে রেখে, এটি বোঝা সহজ ছিল:
let msg = "Hello World";
function doWork() { // msg will be available since it was defined above this opening bracket!
let friends = 0;
console.log(msg);
// with VAR though:
for (var iCount2 = 0; iCount2 < 5; iCount2++) {} // iCount2 will be available after this closing bracket!
console.log(iCount2);
for (let iCount1 = 0; iCount1 < 5; iCount1++) {} // iCount1 will not be available behind this closing bracket, it will return undefined
console.log(iCount1);
} // friends will no be available after this closing bracket!
doWork();
console.log(friends);
এখন আমি মনে করি এটি ব্যবহার করে স্টেটমেন্টগুলির একটি ব্লকে ভেরিয়েবলের আরও ভাল স্কোপিং রয়েছে let:
function printnums()
{
// i is not accessible here
for(let i = 0; i <10; i+=)
{
console.log(i);
}
// i is not accessible here
// j is accessible here
for(var j = 0; j <10; j++)
{
console.log(j);
}
// j is accessible here
}
আমি মনে করি লোকেরা এখানে এর পরে ব্যবহার শুরু করবে যাতে তাদের অন্যান্য জাভা, জাভা, সি # ইত্যাদি ইত্যাদির মতো জাভাস্ক্রিপ্টে একই রকম স্কোপিং থাকবে I
জাভাস্ক্রিপ্টে স্কোপিং সম্পর্কে স্পষ্ট বোঝা নেই এমন লোকেরা আগে ভুলটি করত।
উত্তোলন ব্যবহার করে সমর্থিত নয় let।
এই পদ্ধতির সাথে জাভাস্ক্রিপ্টে উপস্থিত ত্রুটিগুলি মুছে ফেলা হচ্ছে।
পড়ুন ES6 ইন গভীরতা: দিন const এটা আরও ভাল বুঝতে।
এই নিবন্ধটি স্পষ্টভাবে বর্ণ, লে এবং কনস্টের মধ্যে পার্থক্য নির্ধারণ করে
constএটি একটি সংকেত যা সনাক্তকারীকে পুনরায় নিয়োগ দেওয়া হবে না।
let, এমন একটি সংকেত যা ভেরিয়েবলটি পুনরায় বরাদ্দ করা যেতে পারে যেমন লুপের কাউন্টার বা একটি অ্যালগরিদমে মান অদলবদল। এটি এটিও ইঙ্গিত দেয় যে ভেরিয়েবলটি কেবলমাত্র সেই ব্লকটিতে ব্যবহার করা হবে যা এটি সংজ্ঞায়িত করা হয়েছে, যা সর্বদা পুরো ধারণক্ষম ক্রিয়া নয়।
varআপনি জাভাস্ক্রিপ্টে কোনও ভেরিয়েবল সংজ্ঞায়িত করার সময় এখন দুর্বলতম সিগন্যাল। ভেরিয়েবলটি পুনঃসাইন করা হতে পারে এবং নাও হতে পারে এবং ভেরিয়েবলটি পুরো ফাংশনের জন্য বা কেবল একটি ব্লক বা লুপের উদ্দেশ্যে ব্যবহার করা যেতে পারে।
https://medium.com/javascript-scene/javascript-es6-var-let-or-const-ba58b8dcde75#.esmkpbg9b
letএটি 6th ষ্ঠ সংস্করণের খসড়া অন্তর্ভুক্ত এবং সম্ভবত চূড়ান্ত স্পেসিফিকেশন হবে।