পরিশিষ্ট

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

উদাহরণস্বরূপ, একটি স্ট্রিং লিটারেলের নিজস্ব কোনো পদ্ধতি নেই, তবে আপনি এটিতে .toUpperCase() পদ্ধতিটিকে কল করতে পারেন সংশ্লিষ্ট String অবজেক্ট র্যাপারকে ধন্যবাদ:

"this is a string literal".toUpperCase();
> THIS IS A STRING LITERAL

একে বলা হয় প্রোটোটাইপল ইনহেরিটেন্স —একটি মানের সংশ্লিষ্ট কনস্ট্রাক্টর থেকে বৈশিষ্ট্য এবং পদ্ধতির উত্তরাধিকার।

Number.prototype
> Number { 0 }
>  constructor: function Number()
>  toExponential: function toExponential()
>  toFixed: function toFixed()
>  toLocaleString: function toLocaleString()
>  toPrecision: function toPrecision()
>  toString: function toString()
>  valueOf: function valueOf()
>  <prototype>: Object {  }

আপনি শুধুমাত্র তাদের মান দ্বারা সংজ্ঞায়িত করার পরিবর্তে এই কন্সট্রাক্টরগুলি ব্যবহার করে আদিম তৈরি করতে পারেন। উদাহরণস্বরূপ, String কনস্ট্রাক্টর ব্যবহার করে একটি স্ট্রিং অবজেক্ট তৈরি করে, স্ট্রিং লিটারাল নয়: একটি অবজেক্ট যা শুধুমাত্র আমাদের স্ট্রিং মান ধারণ করে না, কিন্তু কনস্ট্রাক্টরের সমস্ত উত্তরাধিকারী বৈশিষ্ট্য এবং পদ্ধতিগুলিকে ধারণ করে।

const myString = new String( "I'm a string." );

myString;
> String { "I'm a string." }

typeof myString;
> "object"

myString.valueOf();
> "I'm a string."

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

const numberOne = new Number(1);
const numberTwo = new Number(2);

numberOne;
> Number { 1 }

typeof numberOne;
> "object"

numberTwo;
> Number { 2 }

typeof numberTwo;
> "object"

numberOne + numberTwo;
> 3

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

let stringLiteral = "String literal."

typeof stringLiteral;
> "string"

let stringObject = new String( "String object." );

stringObject
> "object"

এটি কঠোর তুলনা অপারেটরদের ব্যবহারকে জটিল করতে পারে:

const myStringLiteral = "My string";
const myStringObject = new String( "My string" );

myStringLiteral === "My string";
> true

myStringObject === "My string";
> false

স্বয়ংক্রিয় সেমিকোলন সন্নিবেশ (ASI)

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

  • সেই টোকেনটি একটি লাইন বিরতির মাধ্যমে আগের টোকেন থেকে আলাদা করা হয়।
  • সেই টোকেনটি হল }
  • আগের টোকেনটি হল ) , এবং সন্নিবেশিত সেমিকোলন হবে a dowhile স্টেটমেন্টের শেষ সেমিকোলন।

আরও তথ্যের জন্য, ASI নিয়মগুলি পড়ুন।

উদাহরণস্বরূপ, নিম্নলিখিত বিবৃতিগুলির পরে সেমিকোলন বাদ দিলে ASI-এর কারণে সিনট্যাক্স ত্রুটি হবে না:

const myVariable = 2
myVariable + 3
> 5

যাইহোক, ASI একই লাইনে একাধিক বিবৃতির জন্য অ্যাকাউন্ট করতে পারে না। আপনি যদি একই লাইনে একাধিক বিবৃতি লেখেন, সেমিকোলন দিয়ে আলাদা করতে ভুলবেন না:

const myVariable = 2 myVariable + 3
> Uncaught SyntaxError: unexpected token: identifier

const myVariable = 2; myVariable + 3;
> 5

ASI হল ত্রুটি সংশোধনের একটি প্রয়াস, জাভাস্ক্রিপ্টে নির্মিত এক ধরনের সিনট্যাকটিক নমনীয়তা নয়। যেখানে উপযুক্ত সেমিকোলন ব্যবহার করা নিশ্চিত করুন যাতে আপনি সঠিক কোড তৈরি করতে এটির উপর নির্ভর না করেন।

কঠোর মোড

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

ES5 জাভাস্ক্রিপ্ট শব্দার্থবিদ্যার সাথে কিছু দীর্ঘস্থায়ী সমস্যা সমাধান করে "কঠোর মোড" প্রবর্তন করে বিদ্যমান বাস্তবায়নকে না ভেঙে, একটি সম্পূর্ণ স্ক্রিপ্ট বা একটি পৃথক ফাংশনের জন্য ভাষা নিয়মের আরও সীমাবদ্ধ সেট বেছে নেওয়ার একটি উপায়। কঠোর মোড সক্ষম করতে, একটি স্ক্রিপ্ট বা ফাংশনের প্রথম লাইনে একটি সেমিকোলন দ্বারা অনুসরণ করে স্ট্রিং আক্ষরিক "use strict" ব্যবহার করুন:

"use strict";
function myFunction() {
  "use strict";
}

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

(function() {
  mySloppyGlobal = true;
}());

mySloppyGlobal;
> true

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

(function() {
    "use strict";
    mySloppyGlobal = true;
}());
> Uncaught ReferenceError: assignment to undeclared variable mySloppyGlobal

আপনাকে অবশ্যই একটি স্ট্রিং আক্ষরিক হিসাবে "use strict" লিখতে হবে। একটি টেমপ্লেট আক্ষরিক ( use strict ) কাজ করবে না। আপনাকে অবশ্যই তার উদ্দেশ্য প্রেক্ষাপটে যেকোনো এক্সিকিউটেবল কোডের আগে "use strict" অন্তর্ভুক্ত করতে হবে। অন্যথায়, দোভাষী এটি উপেক্ষা করে।

(function() {
    "use strict";
    let myVariable = "String.";
    console.log( myVariable );
    sloppyGlobal = true;
}());
> "String."
> Uncaught ReferenceError: assignment to undeclared variable sloppyGlobal

(function() {
    let myVariable = "String.";
    "use strict";
    console.log( myVariable );
    sloppyGlobal = true;
}());
> "String." // Because there was code prior to "use strict", this variable still pollutes the global scope

বাই-রেফারেন্স, বাই- ভ্যালু

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

যখন একটি আদিম মান একটি ভেরিয়েবল থেকে অন্য ভেরিয়েবলে বরাদ্দ করা হয়, তখন জাভাস্ক্রিপ্ট ইঞ্জিন সেই মানের একটি অনুলিপি তৈরি করে এবং এটি ভেরিয়েবলে বরাদ্দ করে।

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

const myObject = {};
const myObjectReference = myObject;

myObjectReference.myProperty = true;

myObject;
> Object { myProperty: true }

এটি শুধুমাত্র বস্তুর পরিবর্তনের জন্যই নয়, বরং কঠোর তুলনা করার জন্যও গুরুত্বপূর্ণ, কারণ বস্তুর মধ্যে কঠোর সমতার জন্য উভয় ভেরিয়েবলকে true মূল্যায়ন করার জন্য একই বস্তুর উল্লেখ করতে হবে। তারা বিভিন্ন বস্তুর উল্লেখ করতে পারে না, এমনকি যদি সেই বস্তুগুলি কাঠামোগতভাবে অভিন্ন হয়:

const myObject = {};
const myReferencedObject = myObject;
const myNewObject = {};

myObject === myNewObject;
> false

myObject === myReferencedObject;
> true

মেমরি বরাদ্দ

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

মেমরিতে দুটি "ক্ষেত্র" রয়েছে: "স্ট্যাক" এবং "হিপ।" স্ট্যাক স্ট্যাটিক ডেটা সঞ্চয় করে—আদিম মান এবং অবজেক্টের রেফারেন্স—কারণ স্ক্রিপ্ট চালানোর আগে এই ডেটা সঞ্চয় করার জন্য নির্দিষ্ট পরিমাণ জায়গা বরাদ্দ করা যেতে পারে। হিপ বস্তুগুলি সঞ্চয় করে, যার জন্য গতিশীল-বরাদ্দ স্থান প্রয়োজন কারণ তাদের আকার কার্যকর করার সময় পরিবর্তিত হতে পারে। মেমরি "আবর্জনা সংগ্রহ" নামক একটি প্রক্রিয়া দ্বারা মুক্ত করা হয়, যা মেমরি থেকে কোনো রেফারেন্স ছাড়াই বস্তুগুলিকে সরিয়ে দেয়।

মূল থ্রেড

জাভাস্ক্রিপ্ট একটি "সিঙ্ক্রোনাস" এক্সিকিউশন মডেল সহ একটি মৌলিকভাবে একক-থ্রেডেড ভাষা, যার অর্থ এটি একবারে শুধুমাত্র একটি কাজ সম্পাদন করতে পারে। এই ক্রমিক নির্বাহের প্রসঙ্গটিকে প্রধান থ্রেড বলা হয়।

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

কিছু কাজ কিছু সীমাবদ্ধতা সহ ওয়েব ওয়ার্কার্স নামক ব্যাকগ্রাউন্ড থ্রেডে চালানো যেতে পারে:

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

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

কল স্ট্যাক

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

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

এই মৃত্যুদন্ডের প্রেক্ষাপটগুলি তাদের কার্যকর করার জন্য প্রয়োজনীয় যেকোন মান ক্যাপচার করে। তারা এর মূল প্রেক্ষাপটের উপর ভিত্তি করে ফাংশনের সুযোগের মধ্যে উপলব্ধ ভেরিয়েবল এবং ফাংশনগুলিও স্থাপন করে এবং ফাংশনের প্রসঙ্গে this কীওয়ার্ডের মান নির্ধারণ করে এবং সেট করে।

ইভেন্ট লুপ এবং কলব্যাক সারি

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

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