লেক্সিকাল স্কোপিংয়ের সংক্ষিপ্ত পরিচিতি কী?
লেক্সিকাল স্কোপিংয়ের সংক্ষিপ্ত পরিচিতি কী?
উত্তর:
আমি উদাহরণের মাধ্যমে তাদের বুঝতে। :)
প্রথমত, সি-এর মতো সিনট্যাক্সে লেজিকাল স্কোপ (এটি স্ট্যাটিক স্কোপ নামেও পরিচিত ):
void fun()
{
int x = 5;
void fun2()
{
printf("%d", x);
}
}
প্রতিটি অভ্যন্তরীণ স্তর এর বাইরের স্তরগুলিতে অ্যাক্সেস করতে পারে।
লিস্পের প্রথম বাস্তবায়নের মাধ্যমে গতিশীল স্কোপ নামে একটি অন্য উপায় রয়েছে যা আবার সি-এর মতো বাক্য গঠনতে ব্যবহৃত হয় :
void fun()
{
printf("%d", x);
}
void dummy1()
{
int x = 5;
fun();
}
void dummy2()
{
int x = 10;
fun();
}
এখানে fun
পারেন অ্যাক্সেস করা যাবে x
মধ্যে dummy1
বা dummy2
, বা কোনো x
যে কলে যেকোনো ফাংশনে fun
সঙ্গে x
এটা ঘোষিত।
dummy1();
5 মুদ্রণ করবে,
dummy2();
10 মুদ্রণ করবে।
প্রথমটিকে স্থিতিক বলা হয় কারণ এটি সংকলন-সময়ে নির্ধারণ করা যেতে পারে, এবং দ্বিতীয়টিকে ডায়নামিক বলা হয় কারণ বাইরের স্কোপটি গতিশীল এবং ফাংশনগুলির চেইন কলের উপর নির্ভর করে।
আমি চোখের জন্য স্থির স্কোপিংকে আরও সহজ মনে করি। বেশিরভাগ ভাষা শেষ পর্যন্ত এইভাবে চলে গেছে, এমনকি লিস্প (উভয়ই করতে পারে, তাই না?) ডায়নামিক স্কোপিং হ'ল ফাংশনে সমস্ত ভেরিয়েবলের রেফারেন্স দেওয়ার মতো।
সংকলক কেন কোনও ফাংশনের বাইরের গতিশীল সুযোগকে কমিয়ে দিতে পারে না তার একটি উদাহরণ হিসাবে, আমাদের শেষ উদাহরণটি বিবেচনা করুন। আমরা যদি এরকম কিছু লিখি:
if(/* some condition */)
dummy1();
else
dummy2();
কল চেইন রান টাইম শর্তের উপর নির্ভর করে। যদি এটি সত্য হয়, তবে কল চেইনটি এমন দেখাচ্ছে:
dummy1 --> fun()
শর্তটি মিথ্যা হলে:
dummy2 --> fun()
fun
উভয় ক্ষেত্রেই বাহ্যিক সুযোগ হ'ল কলার প্লাস কলারের কলস এবং আরও অনেক কিছু ।
কেবল উল্লেখ করার জন্য যে সি ভাষা নেস্টেড ফাংশন বা গতিশীল স্কোপিংয়ের অনুমতি দেয় না।
JavaScript
। অতএব আমি মনে করি এটি গ্রহণযোগ্য উত্তর হিসাবে চিহ্নিত করা উচিত নয়। জেএসে বিশেষত লেক্সিকাল স্কোপটি আলাদা
for
লুপের অভ্যন্তরে সাধারণ সমস্যা। ES6 let
বা const
ব্যবহৃত না হলে জাভাস্ক্রিপ্টের জন্য লেজিকাল স্কোপটি কেবলমাত্র ফাংশন স্তরে থাকে ।
সংক্ষিপ্ততম সংজ্ঞাটি চেষ্টা করতে দিন:
লেক্সিকাল স্কোপিং সংজ্ঞায়িত করে যে কীভাবে ভেরিয়েবলের নামগুলি নেস্টেড ফাংশনগুলিতে সমাধান করা হয়: অভ্যন্তরীণ ফাংশনগুলিতে প্যারেন্ট ফাংশনগুলি ফিরে আসে এমনকি পিতামাতার ফাংশনগুলির সুযোগ থাকে ।
এটাই তো আছে!
var scope = "I am global";
function whatismyscope(){
var scope = "I am just a local";
function func() {return scope;}
return func;
}
whatismyscope()()
উপরের কোডটি "আমি কেবল স্থানীয়" ফিরে আসবে। এটি "আমি একটি বিশ্বব্যাপী" ফিরে আসবে না। কারণ ফাংশন ফানক () গণনা করে যেখানে মূলত সংজ্ঞা দেওয়া হয়েছিল যা ফাংশন হোয়াটিসিস্কোপের আওতায় রয়েছে।
এটি যাকে বলা হচ্ছে তা থেকে বিরত হবে না (বৈশ্বিক স্কোপ / এমনকি অন্য কোনও ফাংশনের মধ্যে থেকে), সে কারণেই আমি বিশ্বব্যাপী স্কোপ মানটি মুদ্রিত হবে না।
এটিকে লেক্সিকাল স্কোপিং বলা হয় যেখানে " স্কোপ চেইন ব্যবহার করে ফাংশনগুলি কার্যকর করা হয়েছিল যা তাদের সংজ্ঞায়িত করার সময় কার্যকর হয়েছিল " - জাভাস্ক্রিপ্ট সংজ্ঞা গাইড অনুসারে।
লেক্সিকাল স্কোপ একটি খুব শক্তিশালী ধারণা।
আশাকরি এটা সাহায্য করবে..:)
লেক্সিকাল (একেএ স্ট্যাটিক) স্কোপিং বলতে কোডের টেক্সচুয়াল কর্পাসের মধ্যে কেবল তার অবস্থানের ভিত্তিতে ভেরিয়েবলের স্কোপ নির্ধারণকে বোঝায়। একটি পরিবর্তনশীল সর্বদা এর শীর্ষ স্তরের পরিবেশকে বোঝায়। এটি ডায়নামিক স্কোপের সাথে বোঝা ভাল।
স্কোপটি অঞ্চলটি নির্দিষ্ট করে যেখানে ফাংশন, ভেরিয়েবল এবং এগুলি উপলভ্য। উদাহরণস্বরূপ একটি ভেরিয়েবলের প্রাপ্যতা তার প্রসঙ্গেই সংজ্ঞায়িত করা হয়, আসুন ফাংশন, ফাইল বা বস্তুর মধ্যে সেগুলি সংজ্ঞায়িত করা হয় We আমরা সাধারণত এই স্থানীয় ভেরিয়েবলগুলি কল করি।
লেজিকাল অংশটির অর্থ আপনি উত্স কোডটি পড়া থেকে সুযোগটি অর্জন করতে পারেন।
লেক্সিকাল স্কোপ স্ট্যাটিক স্কোপ হিসাবেও পরিচিত।
ডায়নামিক স্কোপ গ্লোবাল ভেরিয়েবলগুলি সংজ্ঞায়িত করে যা সংজ্ঞায়িত হওয়ার পরে যেকোন স্থান থেকে কল বা রেফারেন্স করা যায়। অনেক সময় এগুলিকে বৈশ্বিক চলক বলা হয়, যদিও বেশিরভাগ প্রোগ্রামিন ভাষাগুলিতে বৈশ্বিক ভেরিয়েবল লেক্সিকাল স্কোপযুক্ত। এর অর্থ, কোডটি পড়ার মাধ্যমে এটি প্রাপ্ত হতে পারে যে এই প্রসঙ্গে ভেরিয়েবলটি উপলব্ধ। তাত্ক্ষণিক সংজ্ঞা বা সংজ্ঞা সন্ধান করতে হতে পারে একটির ব্যবহার অনুসরণ করতে হবে বা ক্লজ অন্তর্ভুক্ত থাকতে পারে, তবে কোড / সংকলকটি এই জায়গায় পরিবর্তনশীল সম্পর্কে জানে।
গতিশীল স্কোপিং এর বিপরীতে, আপনি প্রথমে স্থানীয় ফাংশনটি অনুসন্ধান করেন, তারপরে আপনি সেই ফাংশনটি সন্ধান করেন যা লোকাল ফাংশন বলে, তারপরে আপনি সেই ফাংশনটি সন্ধান করেন যা সেই ফাংশনটিকে ডাকে এবং এইভাবে, কল স্ট্যাক আপ করে। "ডায়নামিক" পরিবর্তনকে বোঝায়, এতে প্রদত্ত ফাংশনটি যতবার বলা হয় ততবার কল স্ট্যাকটি আলাদা হতে পারে এবং তাই ফাংশনটি কোথা থেকে ডাকা হয়েছে তার উপর নির্ভর করে বিভিন্ন চলকগুলিতে আঘাত করতে পারে। ( এখানে দেখুন) )
গতিশীল সুযোগের জন্য একটি আকর্ষণীয় উদাহরণ দেখতে এখানে দেখুন ।
আরও তথ্যের জন্য এখানে এবং এখানে দেখুন ।
ডেলফি / অবজেক্ট পাসকালের কয়েকটি উদাহরণ
ডেলফির লেক্সিকাল স্কোপ রয়েছে।
unit Main;
uses aUnit; // makes available all variables in interface section of aUnit
interface
var aGlobal: string; // global in the scope of all units that use Main;
type
TmyClass = class
strict private aPrivateVar: Integer; // only known by objects of this class type
// lexical: within class definition,
// reserved word private
public aPublicVar: double; // known to everyboday that has access to a
// object of this class type
end;
implementation
var aLocalGlobal: string; // known to all functions following
// the definition in this unit
end.
গতিশীল স্কোপে সবচেয়ে কাছের ডেল্ফিটি হ'ল রেজিস্টারক্লাস () / গেটক্লাস () ফাংশন জুটি। এর ব্যবহারের জন্য এখানে দেখুন ।
ধরা যাক যে রেজিস্টারক্লাস ([TmyClass]) একটি নির্দিষ্ট শ্রেণীর নিবন্ধনের জন্য আহ্বান জানানো হয়েছে কোড পড়ার মাধ্যমে ভবিষ্যদ্বাণী করা যায় না (এটি ব্যবহারকারী দ্বারা বোতাম ক্লিক করার পদ্ধতিতে কল করা হয়), গেটক্লাস ('TmyClass') কলিং কোডটি পাবেন একটি ফলাফল বা না। রেজিস্টারক্লাস () এ কল করা গেটক্লাস () ব্যবহার করে ইউনিটের লেজিকাল স্কোপে থাকতে হবে না;
গতিশীল সুযোগের জন্য আর একটি সম্ভাবনা হ'ল ডেলফি ২০০৯ এ বেনামে পদ্ধতি (ক্লোজার), কারণ তারা তাদের কলিংয়ের ফাংশনের পরিবর্তনশীলগুলি জানেন। এটি পুনরাবৃত্তভাবে সেখান থেকে কলিংয়ের পথ অনুসরণ করে না এবং তাই সম্পূর্ণ গতিশীল নয়।
আমি @ আরকের মতো লোকের কাছ থেকে সম্পূর্ণ বৈশিষ্ট্যযুক্ত, ভাষা-অজ্ঞাত উত্তরগুলি পছন্দ করি। যেহেতু এই প্রশ্নটি জাভাস্ক্রিপ্ট ট্যাগ হয়েছিল যদিও , তাই আমি এই ভাষার সাথে খুব নির্দিষ্ট কিছু নোটে চিপ করতে চাই।
জাভাস্ক্রিপ্টে স্কোপিংয়ের জন্য আমাদের পছন্দগুলি হ'ল:
var _this = this; function callback(){ console.log(_this); }
callback.bind(this)
আমি মনে করি, জাভাস্ক্রিপ্টের আসলে গতিশীল স্কোপিং নেই । কীওয়ার্ডটি .bind
সামঞ্জস্য করে this
এবং এটি নিকটবর্তী, তবে প্রযুক্তিগতভাবে একই নয়।
উভয় পন্থা প্রদর্শন এখানে একটি উদাহরণ। স্কপ কলব্যাক কীভাবে করবেন সে সম্পর্কে আপনি যখনই সিদ্ধান্ত নেবেন প্রত্যেক বার আপনি এটি করেন যাতে এটি প্রতিশ্রুতি, ইভেন্ট হ্যান্ডলার এবং আরও অনেক কিছুর ক্ষেত্রে প্রযোজ্য।
এখানে Lexical Scoping
আপনি জাভাস্ক্রিপ্টে কলব্যাকের শব্দটি বলতে পারেন :
var downloadManager = {
initialize: function() {
var _this = this; // Set up `_this` for lexical access
$('.downloadLink').on('click', function () {
_this.startDownload();
});
},
startDownload: function(){
this.thinking = true;
// Request the file from the server and bind more callbacks for when it returns success or failure
}
//...
};
সুযোগের অন্য উপায়টি হ'ল Function.prototype.bind
:
var downloadManager = {
initialize: function() {
$('.downloadLink').on('click', function () {
this.startDownload();
}.bind(this)); // Create a function object bound to `this`
}
//...
এই পদ্ধতিগুলি যতদূর আমি জানি, আচরণগতভাবে সমতুল্য।
bind
সুযোগটি প্রভাবিত করে না।
আইবিএম এটিকে সংজ্ঞায়িত করে:
কোনও প্রোগ্রাম বা সেগমেন্ট ইউনিটের অংশ যেখানে একটি ঘোষণাপত্র প্রযোজ্য। একটি রুটিনে ঘোষিত একটি সনাক্তকারী সেই রুটিনের মধ্যে এবং সমস্ত নেস্টেড রুটিনগুলির মধ্যে পরিচিত known যদি কোনও নেস্টেড রুটিন একই নামের সাথে কোনও আইটেম ঘোষণা করে তবে বাইরের আইটেমটি নেস্টেড রুটিনে পাওয়া যায় না।
উদাহরণ 1:
function x() {
/*
Variable 'a' is only available to function 'x' and function 'y'.
In other words the area defined by 'x' is the lexical scope of
variable 'a'
*/
var a = "I am a";
function y() {
console.log( a )
}
y();
}
// outputs 'I am a'
x();
উদাহরণ 2:
function x() {
var a = "I am a";
function y() {
/*
If a nested routine declares an item with the same name,
the outer item is not available in the nested routine.
*/
var a = 'I am inner a';
console.log( a )
}
y();
}
// outputs 'I am inner a'
x();
লেক্সিকাল স্কোপ বলতে বোঝায় যে ফাংশনগুলির একটি নেস্টেড গ্রুপে, অভ্যন্তরীণ ফাংশনগুলিতে তাদের প্যারেন্ট স্কোপের ভেরিয়েবল এবং অন্যান্য সংস্থানগুলিতে অ্যাক্সেস থাকে । এর অর্থ হ'ল সন্তানের ক্রিয়াকলাপগুলি তাদের পিতামাতার মৃত্যুদন্ড কার্যকর করার প্রসঙ্গে লিখিতভাবে আবদ্ধ। লেজিকাল স্কোপটিকে কখনও কখনও স্থির সুযোগ হিসাবেও চিহ্নিত করা হয় ।
function grandfather() {
var name = 'Hammad';
// 'likes' is not accessible here
function parent() {
// 'name' is accessible here
// 'likes' is not accessible here
function child() {
// Innermost level of the scope chain
// 'name' is also accessible here
var likes = 'Coding';
}
}
}
লেজিকাল স্কোপ সম্পর্কে আপনি যে জিনিসটি লক্ষ্য করবেন সেটি হ'ল এটি এগিয়ে চলেছে, যার অর্থ নামটি বাচ্চাদের মৃত্যুদন্ড প্রসঙ্গ দ্বারা অ্যাক্সেস করা যেতে পারে। তবে এটি তার পিতামাতার পিছনে কাজ করে না, এর অর্থ হল likes
এর পিতামাতার দ্বারা পরিবর্তনশীল অ্যাক্সেস করা যায় না।
এটি আমাদের আরও জানায় যে বিভিন্ন কার্যকরকরণ প্রসঙ্গে একই নামযুক্ত ভেরিয়েবলগুলি এক্সিকিউশন স্ট্যাকের শীর্ষ থেকে নীচে অগ্রাধিকার অর্জন করে। অভ্যন্তরীণ ফাংশনে (চলমান স্ট্যাকের শীর্ষতম প্রেক্ষাপটে) অন্য ভেরিয়েবলের মতো একই নামের একটি ভেরিয়েবলের অগ্রাধিকার থাকবে।
সহজ ভাষায়, লেক্সিকাল স্কোপটি আপনার স্কোপের বাইরে সংজ্ঞায়িত একটি পরিবর্তনশীল বা উপরের স্কোপটি স্বয়ংক্রিয়ভাবে আপনার স্কোপের অভ্যন্তরে উপলব্ধ হয় যার অর্থ এটি আপনাকে সেখানে পাস করার দরকার নেই।
উদাহরণ:
let str="JavaScript";
const myFun = () => {
console.log(str);
}
myFun();
// আউটপুট: জাভাস্ক্রিপ্ট
bind
। তাদের সাথে, bind
এখন আর দরকার নেই। এই পরিবর্তন সম্পর্কে আরও তথ্যের জন্য stackoverflow.com/a/34361380/11127383
সেখানে পার্শ্ববর্তী কথোপকথনের একটি গুরুত্বপূর্ণ অংশ আভিধানিক এবং গতিশীল scoping একটি প্লেইন ব্যাখ্যা: যে অনুপস্থিত জীবনকাল - বা বিশ্লেষণ করা ভেরিয়েবলের যখন পরিবর্তনশীল অ্যাক্সেস করতে পারবেন।
ডায়নামিক স্কোপিং কেবলমাত্র "গ্লোবাল" স্কোপিংয়ের সাথে সামঞ্জস্যপূর্ণ যেভাবে আমরা traditionতিহ্যগতভাবে এটি সম্পর্কে চিন্তা করি (যে কারণে আমি দুজনের মধ্যে তুলনা এনেছি তা ইতিমধ্যে উল্লেখ করা হয়েছে - এবং আমি বিশেষত লিঙ্কযুক্ত নিবন্ধের ব্যাখ্যা পছন্দ করি না ); এটি সম্ভবত সর্বোত্তম যে আমরা বৈশ্বিক এবং গতিশীলদের মধ্যে তুলনা করি না - যদিও অনুমিতভাবে, লিঙ্কযুক্ত নিবন্ধ অনুযায়ী, "... [এটি] বিশ্বব্যাপী স্কোপড ভেরিয়েবলের বিকল্প হিসাবে দরকারী" "
সুতরাং, সরল ইংরেজিতে, দুটি স্কোপিং প্রক্রিয়ার মধ্যে গুরুত্বপূর্ণ পার্থক্য কী?
উপরের উত্তরগুলিতে লেক্সিকাল স্কোপিংটি খুব ভালভাবে সংজ্ঞায়িত করা হয়েছে: লাক্ষিকভাবে স্কোপযুক্ত ভেরিয়েবলগুলি পাওয়া যায় - বা, অ্যাক্সেসযোগ্য - ফাংশনের স্থানীয় স্তরে যেখানে এটি সংজ্ঞায়িত হয়েছিল।
তবে - যেহেতু এটি ওপিটির কেন্দ্রবিন্দু নয় - গতিশীল স্কোপিং খুব বেশি মনোযোগ পায়নি এবং এটি যে মনোযোগ পেয়েছে তার অর্থ সম্ভবত আরও কিছুটা প্রয়োজন (এটি অন্যান্য উত্তরের সমালোচনা নয়, বরং "ওহ, এই উত্তরটি তৈরি করে আমরা আশা করি কিছুটা বেশি থাকত ")। সুতরাং, এখানে আরও কিছু:
ডায়নামিক স্কোপিং মানে ফাংশন কলের জীবদ্দশায় বা একটি ক্রিয়াকলাপ চালিত হওয়ার সময় কোনও চলক বৃহত্তর প্রোগ্রামে অ্যাক্সেসযোগ্য। সত্যই, উইকিপিডিয়া আসলে দুজনের মধ্যে পার্থক্যের ব্যাখ্যা দিয়ে একটি দুর্দান্ত কাজ করে। যাতে এটি অবরুদ্ধ না হয়, এখানে পাঠ্যটি গতিশীল স্কোপিংয়ের বর্ণনা দেয়:
... [আমি] এন ডায়নামিক স্কোপিং (বা ডায়নামিক স্কোপ), যদি কোনও ভেরিয়েবল নামের স্কোপ একটি নির্দিষ্ট ফাংশন হয়, তবে এর সুযোগটি সময়-সময় যা চলাকালীন সঞ্চালিত হয়: ফাংশনটি চলমান অবস্থায়, ভেরিয়েবলের নামটি বিদ্যমান , এবং তার ভেরিয়েবলের সাথে আবদ্ধ, তবে ফাংশনটি ফিরে আসার পরে, ভেরিয়েবলের নামটি বিদ্যমান নেই।
লেক্সিকাল স্কোপটির অর্থ হল যে কোনও ফাংশনটি প্রাসঙ্গিকভাবে যেখানে সংজ্ঞায়িত হয়েছিল তার প্রকারে ভেরিয়েবলগুলি সন্ধান করে এবং তার আশেপাশের সুযোগে তা অবিলম্বে নয়।
আপনি আরও বিশদ জানতে চাইলে লিস্পে কীভাবে লেজিকাল স্কোপ কাজ করে তা দেখুন। ডায়নামিক এবং কমন লিস্পে লেক্সিকাল ভেরিয়েবলগুলিতে কাইল ক্রোনিনের নির্বাচিত উত্তর উত্তরগুলি এখানে উত্তরগুলির চেয়ে অনেক পরিষ্কার are
কাকতালীয়ভাবে আমি এই সম্পর্কে শুধুমাত্র একটি লিস্প ক্লাসে শিখেছি এবং এটি জাভাস্ক্রিপ্টে প্রয়োগ করার ক্ষেত্রেও ঘটে।
আমি এই কোডটি ক্রোমের কনসোলে চালিয়েছি।
// JavaScript Equivalent Lisp
var x = 5; //(setf x 5)
console.debug(x); //(print x)
function print_x(){ //(defun print-x ()
console.debug(x); // (print x)
} //)
(function(){ //(let
var x = 10; // ((x 10))
console.debug(x); // (print x)
print_x(); // (print-x)
})(); //)
আউটপুট:
5
10
5
জাভাস্ক্রিপ্টে একটি লেজিকাল স্কোপ মানে যে কোনও ফাংশনের বাইরে সংজ্ঞায়িত একটি ভেরিয়েবল ভেরিয়েবল ঘোষণার পরে সংজ্ঞায়িত অন্য ফাংশনের অভ্যন্তরে অ্যাক্সেসযোগ্য হতে পারে। তবে বিপরীতটি সত্য নয়; একটি ফাংশনের ভিতরে সংজ্ঞায়িত ভেরিয়েবলগুলি সেই ফাংশনের বাইরে অ্যাক্সেসযোগ্য হবে না।
এই ধারণাটি জাভাস্ক্রিপ্টে ক্লোজারগুলিতে ভারী ব্যবহৃত হয়।
ধরা যাক আমাদের নীচের কোড রয়েছে।
var x = 2;
var add = function() {
var y = 1;
return x + y;
};
এখন, আপনি যখন অ্যাড () -> কল করবেন তখন এটি 3 মুদ্রণ করবে।
সুতরাং, অ্যাড () ফাংশনটি গ্লোবাল ভেরিয়েবল অ্যাক্সেস করছে x
যা পদ্ধতি ফাংশন অ্যাডের আগে সংজ্ঞায়িত হয়েছে। এটি জাভাস্ক্রিপ্টে লেক্সিকাল স্কোপিংয়ের কারণে বলা হয়।
add()
প্রদত্ত কোড স্নিপেটের সাথে সাথেই যদি ফাংশনটি তত্ক্ষণাত ডাকা হয় তবে এটি 3 প্রিন্টও করে। সুতরাং উদাহরণস্বরূপ কোডটি লেক্সিকাল স্কোপিংয়ের অর্থ কী তা বোঝাতে সত্যিই সহায়তা করে না। কোডে লেজিকাল স্কোপিং দেখানোর জন্য সত্যই একটি পাল্টা উদাহরণ বা কোডটির অন্যান্য সম্ভাব্য ব্যাখ্যার কমপক্ষে ব্যাখ্যা দরকার।
লেজিকাল স্কোপটি এক্সিকিউশন স্ট্যাকের বর্তমান অবস্থান থেকে দৃশ্যমান শনাক্তকারীদের (যেমন, ভেরিয়েবল, ফাংশন, ইত্যাদি) এর অভিধানকে বোঝায়।
- global execution context
- foo
- bar
- function1 execution context
- foo2
- bar2
- function2 execution context
- foo3
- bar3
foo
এবং bar
সর্বদা উপলব্ধ শনাক্তকারীদের অভিধানের মধ্যে থাকে কারণ তারা বিশ্বব্যাপী।
যখন function1
মৃত্যুদন্ড কার্যকর করা হয়, এটি একটি শব্দকোষ অ্যাক্সেস আছে foo2
, bar2
, foo
, এবং bar
।
যখন function2
মৃত্যুদন্ড কার্যকর করা হয়, এটি একটি শব্দকোষ অ্যাক্সেস আছে foo3
, bar3
, foo2
, bar2
, foo
, এবং bar
।
কোনও অভ্যন্তরীণ ফাংশন শনাক্তকারীগুলিতে গ্লোবাল এবং / বা বাহ্যিক ক্রিয়াকলাপগুলির অ্যাক্সেস না থাকার কারণ হ'ল এই ফাংশনটির কার্যকরকরণ এখনও ঘটেনি এবং তাই এর সনাক্তকারীদের কোনওটিকেই মেমোরির জন্য বরাদ্দ করা হয়নি। আরও কী, একবার যখন অভ্যন্তরীণ প্রসঙ্গটি কার্যকর হয়, তখন এটি কার্যকর করা স্ট্যাক থেকে সরিয়ে ফেলা হয়, যার অর্থ এটির সমস্ত সনাক্তকারীকে আবর্জনা সংগ্রহ করা হয়েছে এবং এটি আর উপলব্ধ নেই।
অবশেষে, এ কারণেই কোনও নেস্টেড এক্সিকিউশন প্রসঙ্গটি তার পূর্বপুরুষদের সম্পাদন প্রসঙ্গে সর্বদা অ্যাক্সেস করতে পারে এবং সুতরাং এটির কেন শনাক্তকারীদের বৃহত্তর অভিধানে অ্যাক্সেস থাকতে পারে।
দেখা:
উপরোক্ত সংজ্ঞাটি সরলকরণে সহায়তার জন্য @ রবার3rd কে বিশেষ ধন্যবাদ
এই প্রশ্নের একটি আলাদা কোণ এখানে আমরা একটি পদক্ষেপ ফিরে নিয়ে এবং ব্যাখ্যার বৃহত্তর কাঠামোতে স্কোপিংয়ের ভূমিকা দেখে (একটি প্রোগ্রাম চালিয়ে) পেতে পারি। অন্য কথায়, কল্পনা করুন যে আপনি কোনও ভাষার জন্য একটি দোভাষী (বা সংকলক) তৈরি করছিলেন এবং কোনও প্রোগ্রাম এবং এতে কিছু ইনপুট দিয়ে আউটপুট গণনার জন্য দায়বদ্ধ ছিলেন।
ব্যাখ্যার মধ্যে তিনটি বিষয়ের উপর নজর রাখা জড়িত:
স্টেট - যথা, ভেরিয়েবল এবং রেফারেন্সযুক্ত মেমরি লোকেশন হ্যাপ এবং স্ট্যাকের উপর।
এই রাজ্যে অপারেশন - যথা আপনার প্রোগ্রামে কোডের প্রতিটি লাইন
যে পরিবেশে প্রদত্ত অপারেশনটি চালিত হয় - যথা, কোনও অপারেশনে রাষ্ট্রের অভিক্ষেপ ।
একটি দোভাষী একটি প্রোগ্রামের কোডের প্রথম লাইনে শুরু করে, তার পরিবেশের গণনা করে, সেই পরিবেশে লাইনটি চালান এবং প্রোগ্রামের স্থিতিতে এর প্রভাব ক্যাপচার করেন। এরপরে কোডটির পরবর্তী লাইনটি কার্যকর করতে প্রোগ্রামটির নিয়ন্ত্রণ প্রবাহ অনুসরণ করে এবং প্রোগ্রাম শেষ না হওয়া পর্যন্ত প্রক্রিয়াটি পুনরাবৃত্তি করে।
যে কোনও অপারেশনের জন্য আপনি পরিবেশকে কীভাবে গণনা করছেন তা হ'ল প্রোগ্রামিং ভাষা দ্বারা নির্ধারিত নিয়মের একটি আনুষ্ঠানিক সেট। "বাইন্ডিং" শব্দটি প্রায়শই প্রোগ্রামের সামগ্রিক অবস্থার ম্যাপিংটিকে পরিবেশের একটি মান হিসাবে বর্ণনা করতে ব্যবহৃত হয়। নোট করুন যে "সামগ্রিক রাষ্ট্র" দ্বারা আমরা বিশ্বব্যাপী রাষ্ট্রকে বোঝায় না, বরং মৃত্যুদন্ড কার্যকর করার যে কোনও সময়ে প্রতিটি পৌঁছনীয় সংজ্ঞাটির যোগফল)।
এটি সেই কাঠামো যেখানে স্কোপিং সমস্যা সংজ্ঞায়িত করা হয়। এখন আমাদের বিকল্পগুলি কি তার পরবর্তী অংশে।
এটি গতিশীল স্কোপিংয়ের সংক্ষিপ্তসার , এর মধ্যে যে কোনও পরিবেশে যে পরিবেশটি চালিত হয় তা প্রোগ্রামের রাজ্যটির সাথে আবদ্ধ হয় যার প্রয়োগের প্রসঙ্গ দ্বারা নির্ধারিত হয়।
অন্য কথায়, লেজিকাল স্কোপ সহ যে কোনও পরিবেশ দেখতে পাবে এমন পরিবেশটি একটি স্পষ্টরূপে ভাষাতে যেমন একটি ব্লক বা কোনও ফাংশন দ্বারা সংজ্ঞায়িত একটি স্কোপের সাথে যুক্ত রাষ্ট্রের সাথে আবদ্ধ।
প্রাচীন প্রশ্ন, তবে এখানে এটি গ্রহণ করা আমার।
লেক্সিকাল (স্ট্যাটিক) স্কোপটি উত্স কোডের একটি ভেরিয়েবলের সুযোগকে বোঝায় ।
জাভাস্ক্রিপ্টের মতো ভাষায় যেখানে ফাংশনগুলি চারপাশে পাস করা যায় এবং বিবিধ বস্তুগুলির সাথে সংযুক্ত এবং পুনরায় সংযুক্ত করা যেতে পারে, আপনার সেই সুযোগটি এই সময়ে ফাংশনটি কাকে ডেকেছিল তার উপর নির্ভর করবে, তবে তা তা নয়। স্কোপটি সেভাবে পরিবর্তন করা গতিশীল সুযোগ হবে এবং জাভাস্ক্রিপ্ট এটি করবে না, সম্ভবত this
অবজেক্ট রেফারেন্স ছাড়া with
বিষয়টি বর্ণনা করার জন্য:
var a='apple';
function doit() {
var a='aardvark';
return function() {
alert(a);
}
}
var test=doit();
test();
উদাহরণস্বরূপ, চলকটি a
বিশ্বব্যাপী সংজ্ঞায়িত করা হয় তবে ফাংশনটিতে ছায়া গোছানো হয় doit()
। এই ফাংশনটি আবার একটি ফাংশন প্রদান করে যা আপনি দেখতে পাচ্ছেন, a
তার নিজস্ব ক্ষেত্রের বাইরে চলকটির উপর নির্ভর করে ।
আপনি যদি এটি চালান, আপনি দেখতে পাবেন যে ব্যবহৃত মানটি এটি aardvark
নয় apple
, যদিও এটি test()
ফাংশনের আওতায় রয়েছে, মূল ফাংশনের লেজিকাল স্কোপে নেই। এটি হ'ল ব্যবহৃত স্কোপটি হ'ল সুযোগটি যেমন উত্স কোডে প্রদর্শিত হয়, যেখানে কর্মটি আসলে ব্যবহৃত হয় এমন সুযোগ নয়।
এই সত্যের বিরক্তিকর পরিণতি হতে পারে। উদাহরণস্বরূপ, আপনি সিদ্ধান্ত নিতে পারেন যে আপনার ফাংশনগুলি পৃথকভাবে সংগঠিত করা আরও সহজ এবং সময় আসার পরে সেগুলি ব্যবহার করুন যেমন ইভেন্ট হ্যান্ডলারের মতো:
var a='apple',b='banana';
function init() {
var a='aardvark',b='bandicoot';
document.querySelector('button#a').onclick=function(event) {
alert(a);
}
document.querySelector('button#b').onclick=doB;
}
function doB(event) {
alert(b);
}
init();
<button id="a">A</button>
<button id="b">B</button>
এই কোড নমুনা প্রতিটি এক করে। আপনি দেখতে পাচ্ছেন যে লেজিকাল স্কোপিংয়ের কারণে, বোতামটি A
অভ্যন্তরীণ ভেরিয়েবল ব্যবহার করে, যখন বোতামটি B
দেয় না। আপনি পছন্দ করেছেন তার চেয়ে বেশি বাসা বাঁধার কাজ শেষ করতে পারেন।
যাইহোক, উভয় উদাহরণে, আপনি আরও খেয়াল করবেন যে অভ্যন্তরীণ লেক্সিকালি স্কোপড ভেরিয়েবলগুলি বজায় রয়েছে যদিও এতে থাকা ফাংশনটি তার কোর্সটি চালিয়ে গেছে। এটাকে ক্লোজার বলা হয় এবং বাইরের ফাংশন শেষ হয়ে গেলেও বাইরের ভেরিয়েবলগুলিতে নেস্টেড ফাংশনটির অ্যাক্সেস বোঝায়। জাভাস্ক্রিপ্টের যথেষ্ট পরিমাণে স্মার্ট হওয়া দরকার যা নির্ধারণ করতে those ভেরিয়েবলগুলির আর প্রয়োজন নেই কিনা, এবং যদি না হয় তবে আবর্জনা সেগুলি সংগ্রহ করতে পারে।
আমি সাধারণত উদাহরণ দিয়ে শিখি, এবং এখানে একটি সামান্য কিছু:
const lives = 0;
function catCircus () {
this.lives = 1;
const lives = 2;
const cat1 = {
lives: 5,
jumps: () => {
console.log(this.lives);
}
};
cat1.jumps(); // 1
console.log(cat1); // { lives: 5, jumps: [Function: jumps] }
const cat2 = {
lives: 5,
jumps: () => {
console.log(lives);
}
};
cat2.jumps(); // 2
console.log(cat2); // { lives: 5, jumps: [Function: jumps] }
const cat3 = {
lives: 5,
jumps: () => {
const lives = 3;
console.log(lives);
}
};
cat3.jumps(); // 3
console.log(cat3); // { lives: 5, jumps: [Function: jumps] }
const cat4 = {
lives: 5,
jumps: function () {
console.log(lives);
}
};
cat4.jumps(); // 2
console.log(cat4); // { lives: 5, jumps: [Function: jumps] }
const cat5 = {
lives: 5,
jumps: function () {
var lives = 4;
console.log(lives);
}
};
cat5.jumps(); // 4
console.log(cat5); // { lives: 5, jumps: [Function: jumps] }
const cat6 = {
lives: 5,
jumps: function () {
console.log(this.lives);
}
};
cat6.jumps(); // 5
console.log(cat6); // { lives: 5, jumps: [Function: jumps] }
const cat7 = {
lives: 5,
jumps: function thrownOutOfWindow () {
console.log(this.lives);
}
};
cat7.jumps(); // 5
console.log(cat7); // { lives: 5, jumps: [Function: thrownOutOfWindow] }
}
catCircus();
এই বিষয়টি অন্তর্নির্মিত bind
ফাংশনটির সাথে দৃ strongly়ভাবে সম্পর্কিত এবং ECMAScript 6 তীর ফাংশনে প্রবর্তিত । এটি সত্যিই বিরক্তিকর ছিল, কারণ প্রতিটি নতুন "শ্রেণি" (ফাংশন আসলে) পদ্ধতির জন্য আমরা ব্যবহার করতে চেয়েছিলাম, bind
সুযোগটির অ্যাক্সেস পাওয়ার জন্য আমাদের এটি করতে হয়েছিল।
জাভাস্ক্রিপ্ট ডিফল্টরূপে তার সুযোগ সেট করেনি this
ফাংশন উপর (এটা সেট করেনি প্রসঙ্গ উপর this
)। ডিফল্টরূপে আপনি কোন প্রসঙ্গে থাকতে চান তা স্পষ্ট করে বলতে হবে।
তীর ফাংশন স্বয়ংক্রিয়ভাবে তথাকথিত পরার আভিধানিক সুযোগ (তার ধারণকারী ব্লক মধ্যে পরিবর্তনশীল সংজ্ঞা এক্সেস আছে)। তীর ফাংশনগুলি ব্যবহার this
করার সময় এটি স্বয়ংক্রিয়ভাবে সেই স্থানে আবদ্ধ হয় যেখানে প্রথম স্থানে তীর ফাংশনটি সংজ্ঞায়িত করা হয়েছিল, এবং এই তীর ফাংশনগুলির প্রসঙ্গটি এটির সাথে থাকা ব্লক।
নীচের সহজ উদাহরণগুলিতে এটি বাস্তবে কীভাবে কাজ করে তা দেখুন।
তীর ফাংশনগুলির পূর্বে (ডিফল্টরূপে কোনও যৌক্তিক সুযোগ নেই):
const programming = {
language: "JavaScript",
getLanguage: function() {
return this.language;
}
}
const globalScope = programming.getLanguage;
console.log(globalScope()); // Output: undefined
const localScope = programming.getLanguage.bind(programming);
console.log(localScope()); // Output: "JavaScript"
তীর ফাংশন সহ (ডিফল্টরূপে লেজিকাল স্কোপ):
const programming = {
language: "JavaScript",
getLanguage: function() {
return this.language;
}
}
const arrowFunction = () => {
console.log(programming.getLanguage());
}
arrowFunction(); // Output: "JavaScript"