JavaScript

ইভেন্ট ডেলিগেশন ব্যাখ্যা করুন

ইভেন্ট ডেলিগেশন হল একটি কৌশল যেখানে সন্তান উপাদানগুলিতে ইভেন্ট লিসেনার যোগ না করে একটি প্যারেন্ট উপাদানে ইভেন্ট লিসেনার যোগ করা হয়। ইভেন্টটি DOM-এর মাধ্যমে বাবল আপ হওয়ার কারণে যখনই সন্তান উপাদানগুলিতে ইভেন্ট ট্রিগার হবে তখনই লিসেনারটি কাজ করবে। এই কৌশলের সুবিধাগুলি হল:

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

জাভাস্ক্রিপ্টে `this` কীভাবে কাজ করে তা ব্যাখ্যা করুন

this-এর জন্য কোনো সহজ ব্যাখ্যা নেই; এটি জাভাস্ক্রিপ্টের সবচেয়ে বিভ্রান্তিকর ধারণাগুলির মধ্যে একটি। একটি হাত-নাড়ার ব্যাখ্যা হল যে this-এর মান ফাংশনটি কীভাবে কল করা হয় তার উপর নির্ভর করে। আমি অনলাইনে this সম্পর্কে অনেক ব্যাখ্যা পড়েছি, এবং আমি [Arnav Aggrawal] এর ব্যাখ্যাটি সবচেয়ে স্পষ্ট পেয়েছি। নিম্নলিখিত নিয়মগুলি প্রয়োগ করা হয়:

  1. ফাংশন কল করার সময় যদি new কীওয়ার্ড ব্যবহার করা হয়, তবে ফাংশনের ভিতরে this একটি নতুন অবজেক্ট।
  2. যদি একটি ফাংশন কল/তৈরি করতে apply, call, বা bind ব্যবহার করা হয়, তবে ফাংশনের ভিতরে this হল সেই অবজেক্ট যা আর্গুমেন্ট হিসাবে পাস করা হয়।
  3. যদি একটি ফাংশন একটি পদ্ধতি হিসাবে কল করা হয়, যেমন obj.method()this হল সেই অবজেক্ট যার একটি বৈশিষ্ট্য ফাংশনটি।
  4. যদি একটি ফাংশন একটি ফ্রি ফাংশন ইনভোকেশন হিসাবে আহ্বান করা হয়, যার অর্থ এটি উপরের কোনও শর্ত ছাড়াই আহ্বান করা হয়েছিল, তবে this হল গ্লোবাল অবজেক্ট। একটি ব্রাউজারে, এটি window অবজেক্ট। যদি কঠোর মোডে ('use strict') থাকে, তবে this গ্লোবাল অবজেক্টের পরিবর্তে undefined হবে।
  5. যদি উপরের একাধিক নিয়ম প্রযোজ্য হয়, তবে উচ্চতর নিয়মটি জয়ী হবে এবং this মান সেট করবে।
  6. যদি ফাংশনটি একটি ES2015 অ্যারো ফাংশন হয়, তবে এটি উপরের সমস্ত নিয়ম উপেক্ষা করে এবং এটি তৈরি করার সময় তার চারপাশের স্কোপের this মান গ্রহণ করে।

বিস্তারিত ব্যাখ্যার জন্য, তার [Medium-এর নিবন্ধটি] দেখুন।

ES6-এ this-এর সাথে কাজ করার একটি উপায় উদাহরণ দিতে পারেন যা পরিবর্তিত হয়েছে?

ES6 আপনাকে [অ্যারো ফাংশন] ব্যবহার করার অনুমতি দেয় যা [enclosing lexical scope] ব্যবহার করে। এটি সাধারণত সুবিধাজনক, তবে এটি কলারকে .call বা .apply-এর মাধ্যমে প্রসঙ্গ নিয়ন্ত্রণ করতে বাধা দেয় — যার ফলে jQuery-এর মতো একটি লাইব্রেরি আপনার ইভেন্ট হ্যান্ডলার ফাংশনে this সঠিকভাবে বাইন্ড করবে না। সুতরাং, বড় লিগ্যাসি অ্যাপ্লিকেশনগুলি রিফ্যাক্টর করার সময় এটি মনে রাখা গুরুত্বপূর্ণ।

প্রোটোটাইপাল ইনহেরিটেন্স কীভাবে কাজ করে তা ব্যাখ্যা করুন

Object.create(null) দিয়ে তৈরি অবজেক্টগুলি ব্যতীত সমস্ত জাভাস্ক্রিপ্ট অবজেক্টের একটি __proto__ বৈশিষ্ট্য থাকে, যা অন্য একটি অবজেক্টের রেফারেন্স, যাকে অবজেক্টের 'প্রোটোটাইপ' বলা হয়। যখন একটি অবজেক্টে একটি বৈশিষ্ট্য অ্যাক্সেস করা হয় এবং যদি সেই বৈশিষ্ট্যটি সেই অবজেক্টে না পাওয়া যায়, তখন জাভাস্ক্রিপ্ট ইঞ্জিন অবজেক্টের __proto__, এবং __proto__-এর __proto__ ইত্যাদি দেখে, যতক্ষণ না এটি __proto__গুলির মধ্যে একটিতে সংজ্ঞায়িত বৈশিষ্ট্যটি খুঁজে পায় অথবা প্রোটোটাইপ চেইনের শেষ প্রান্তে না পৌঁছায়। এই আচরণটি ক্লাসিক্যাল ইনহেরিটেন্স অনুকরণ করে, তবে এটি আসলে [ইনহেরিটেন্সের চেয়ে ডেলিগেশন] বেশি।

প্রোটোটাইপাল ইনহেরিটেন্সের উদাহরণ

// প্যারেন্ট অবজেক্ট কনস্ট্রাক্টর। function Animal(name) { this.name = name; } // প্যারেন্ট অবজেক্টের প্রোটোটাইপে একটি পদ্ধতি যোগ করুন। Animal.prototype.makeSound = function () { console.log('The ' + this.constructor.name + ' makes a sound.'); }; // চাইল্ড অবজেক্ট কনস্ট্রাক্টর। function Dog(name) { Animal.call(this, name); // প্যারেন্ট কনস্ট্রাক্টর কল করুন। } // চাইল্ড অবজেক্টের প্রোটোটাইপকে প্যারেন্টের প্রোটোটাইপ হিসাবে সেট করুন। Object.setPrototypeOf(Dog.prototype, Animal.prototype); // চাইল্ড অবজেক্টের প্রোটোটাইপে একটি পদ্ধতি যোগ করুন। Dog.prototype.bark = function () { console.log('Woof!'); }; // Dog এর একটি নতুন ইনস্ট্যান্স তৈরি করুন। const bolt = new Dog('Bolt'); // চাইল্ড অবজেক্টে পদ্ধতিগুলি কল করুন। console.log(bolt.name); // "Bolt" bolt.makeSound(); // "The Dog makes a sound." bolt.bark(); // "Woof!"

লক্ষ্য করার বিষয়গুলি হল:

  • Dog-এ .makeSound সংজ্ঞায়িত করা হয়নি, তাই ইঞ্জিন প্রোটোটাইপ চেইনে উপরে যায় এবং উত্তরাধিকারসূত্রে প্রাপ্ত Animal থেকে .makeSound খুঁজে পায়।
  • ইনহেরিটেন্স চেইন তৈরি করতে Object.create ব্যবহার করা আর সুপারিশ করা হয় না। পরিবর্তে Object.setPrototypeOf ব্যবহার করুন।

AMD বনাম CommonJS সম্পর্কে আপনার কী ধারণা?

উভয়ই একটি মডিউল সিস্টেম বাস্তবায়নের উপায়, যা ES2015 আসার আগে জাভাস্ক্রিপ্টে স্থানীয়ভাবে উপস্থিত ছিল না। CommonJS সিঙ্ক্রোনাস যখন AMD (Asynchronous Module Definition) স্পষ্টতই অ্যাসিঙ্ক্রোনাস। CommonJS সার্ভার-সাইড ডেভেলপমেন্টের কথা মাথায় রেখে ডিজাইন করা হয়েছে যখন AMD, মডিউলগুলির অ্যাসিঙ্ক্রোনাস লোডিংয়ের সমর্থন সহ, ব্রাউজারগুলির জন্য আরও বেশি উদ্দেশ্যপ্রণোদিত।

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

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

নিম্নলিখিতটি কেন IIFE হিসাবে কাজ করে না তা ব্যাখ্যা করুন: `function foo(){ }();`। এটিকে সঠিকভাবে IIFE করার জন্য কী পরিবর্তন করতে হবে?

IIFE এর অর্থ হল ইমিডিয়েটলি ইনভোকড ফাংশন এক্সপ্রেশনস। জাভাস্ক্রিপ্ট পার্সার function foo(){ }();-কে function foo(){ } এবং (); হিসাবে পড়ে, যেখানে পূর্বেরটি একটি ফাংশন ডিক্লারেশন এবং পরবর্তীটি (একজোড়া বন্ধনী) একটি ফাংশন কল করার চেষ্টা কিন্তু কোনো নাম নির্দিষ্ট করা নেই, তাই এটি Uncaught SyntaxError: Unexpected token ) থ্রো করে।

এখানে দুটি উপায় রয়েছে যা আরও বন্ধনী যোগ করে ঠিক করা যায়: (function foo(){ })() এবং (function foo(){ }())function দিয়ে শুরু হওয়া স্টেটমেন্টগুলিকে ফাংশন ডিক্লারেশন হিসাবে বিবেচনা করা হয়; এই ফাংশনকে () এর মধ্যে মোড়ানো হলে এটি একটি ফাংশন এক্সপ্রেশন হয়ে যায় যা পরবর্তী () দিয়ে এক্সিকিউট করা যায়। এই ফাংশনগুলি গ্লোবাল স্কোপে উন্মুক্ত হয় না এবং যদি আপনার বডির মধ্যে এটিকে রেফারেন্স করার প্রয়োজন না হয় তবে আপনি এর নামও বাদ দিতে পারেন।

আপনি void অপারেটরও ব্যবহার করতে পারেন: void function foo(){ }();। দুর্ভাগ্যবশত, এই পদ্ধতির একটি সমস্যা আছে। প্রদত্ত এক্সপ্রেশনের মূল্যায়ন সর্বদা undefined হয়, তাই যদি আপনার IIFE ফাংশন কিছু ফেরত দেয়, তবে আপনি এটি ব্যবহার করতে পারবেন না। একটি উদাহরণ:

const foo = void (function bar() { return 'foo'; })(); console.log(foo); // undefined

একটি ভেরিয়েবল যা: `null`, `undefined` বা undeclared - তাদের মধ্যে পার্থক্য কী? আপনি এই অবস্থাগুলির যেকোনো একটি পরীক্ষা করার জন্য কীভাবে অগ্রসর হবেন?

Undeclared ভেরিয়েবল তৈরি হয় যখন আপনি এমন একটি পরিচিতিপ্রদানকারীতে একটি মান অ্যাসাইন করেন যা পূর্বে var, let বা const ব্যবহার করে তৈরি করা হয়নি। Undeclared ভেরিয়েবলগুলি বর্তমান স্কোপের বাইরে, বিশ্বব্যাপী সংজ্ঞায়িত হবে। কঠোর মোডে, যখন আপনি একটি undeclared ভেরিয়েবলে অ্যাসাইন করার চেষ্টা করবেন তখন একটি ReferenceError নিক্ষেপ করা হবে। Undeclared ভেরিয়েবলগুলি খারাপ যেমন গ্লোবাল ভেরিয়েবলগুলি খারাপ। এগুলি যে কোনও মূল্যে এড়িয়ে চলুন! সেগুলি পরীক্ষা করার জন্য, এর ব্যবহারকে একটি try/catch ব্লকের মধ্যে মোড়ানো।

function foo() { x = 1; // কঠোর মোডে একটি ReferenceError ছুঁড়ে দেয় } foo(); console.log(x); // 1

একটি ভেরিয়েবল যা undefined তা হল একটি ভেরিয়েবল যা ঘোষণা করা হয়েছে, কিন্তু কোনও মান অ্যাসাইন করা হয়নি। এটির প্রকার undefined। যদি একটি ফাংশন নির্বাহের ফলস্বরূপ কোনও মান ফেরত না দেয় এবং এটি একটি ভেরিয়েবলে অ্যাসাইন করা হয়, তবে সেই ভেরিয়েবলের মানও undefined থাকে। এটি পরীক্ষা করার জন্য, কঠোর সমতা (===) অপারেটর বা typeof ব্যবহার করে তুলনা করুন যা 'undefined' স্ট্রিং দেবে। মনে রাখবেন যে আপনার অ্যাবস্ট্রাক্ট সমতা অপারেটর ব্যবহার করে পরীক্ষা করা উচিত নয়, কারণ মান null হলেও এটি true ফেরত দেবে।

var foo; console.log(foo); // undefined console.log(foo === undefined); // true console.log(typeof foo === 'undefined'); // true console.log(foo == null); // true। ভুল, এটি পরীক্ষা করার জন্য ব্যবহার করবেন না! function bar() {} var baz = bar(); console.log(baz); // undefined

একটি ভেরিয়েবল যা null তা স্পষ্টভাবে null মানটিতে অ্যাসাইন করা হয়েছে। এটি কোনও মানকে প্রতিনিধিত্ব করে এবং undefined থেকে ভিন্ন এই অর্থে যে এটি স্পষ্টভাবে অ্যাসাইন করা হয়েছে। null পরীক্ষা করার জন্য, কেবল কঠোর সমতা অপারেটর ব্যবহার করে তুলনা করুন। মনে রাখবেন যে উপরের মতো, আপনার অ্যাবস্ট্রাক্ট সমতা অপারেটর (==) ব্যবহার করে পরীক্ষা করা উচিত নয়, কারণ মান undefined হলেও এটি true ফেরত দেবে।

var foo = null; console.log(foo === null); // true console.log(typeof foo === 'object'); // true console.log(foo == undefined); // true। ভুল, এটি পরীক্ষা করার জন্য ব্যবহার করবেন না!

ব্যক্তিগত অভ্যাস হিসাবে, আমি আমার ভেরিয়েবলগুলি কখনও undeclared বা unassigned রাখি না। আমি যদি এখনও ব্যবহার করতে না চাই তবে ঘোষণা করার পরে আমি স্পষ্টভাবে null অ্যাসাইন করব। আপনি যদি আপনার ওয়ার্কফ্লোতে একটি লিন্টার ব্যবহার করেন, তবে এটি সাধারণত পরীক্ষা করতে সক্ষম হবে যে আপনি undeclared ভেরিয়েবলগুলি রেফারেন্স করছেন না।

ক্লোজার কী, এবং আপনি কীভাবে/কেন এটি ব্যবহার করবেন?

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

কেন এটি ব্যবহার করবেন?

  • ডেটা গোপনীয়তা / ক্লোজার সহ ব্যক্তিগত পদ্ধতি অনুকরণ করা। [মডিউল প্যাটার্ন]-এ সাধারণত ব্যবহৃত হয়।
  • [আংশিক অ্যাপ্লিকেশন বা কারিং]।

আপনি কি `.forEach` লুপ এবং `.map()` লুপের মধ্যে প্রধান পার্থক্য বর্ণনা করতে পারেন এবং কেন আপনি একটির পরিবর্তে অন্যটি বেছে নেবেন?

এই দুটির মধ্যে পার্থক্য বুঝতে, আসুন প্রতিটি ফাংশন কী করে তা দেখি।

forEach

  • একটি অ্যারের উপাদানগুলির মাধ্যমে পুনরাবৃত্তি করে।
  • প্রতিটি উপাদানের জন্য একটি কলব্যাক এক্সিকিউট করে।
  • কোনো মান ফেরত দেয় না।
const a = [1, 2, 3]; const doubled = a.forEach((num, index) => { // num এবং/অথবা index দিয়ে কিছু করুন। }); // doubled = undefined

map

  • একটি অ্যারের উপাদানগুলির মাধ্যমে পুনরাবৃত্তি করে।
  • প্রতিটি উপাদানে ফাংশন কল করে একটি নতুন উপাদানে 'ম্যাপ' করে, ফলে একটি নতুন অ্যারে তৈরি হয়।
const a = [1, 2, 3]; const doubled = a.map((num) => { return num * 2; }); // doubled = [2, 4, 6]

.forEach এবং .map() এর মধ্যে প্রধান পার্থক্য হল যে .map() একটি নতুন অ্যারে ফেরত দেয়। যদি আপনার ফলাফলের প্রয়োজন হয়, কিন্তু আসল অ্যারে পরিবর্তন করতে না চান, তবে .map() হল স্পষ্ট পছন্দ। যদি আপনার কেবল একটি অ্যারের উপর পুনরাবৃত্তি করার প্রয়োজন হয়, forEach একটি ভাল পছন্দ।

বেনামী ফাংশনের একটি সাধারণ ব্যবহার কী?

এগুলি IIFE-তে ব্যবহার করা যেতে পারে কিছু কোড একটি স্থানীয় স্কোপের মধ্যে আবদ্ধ করতে যাতে এতে ঘোষিত ভেরিয়েবলগুলি গ্লোবাল স্কোপে লিক না হয়।

(function () { // এখানে কিছু কোড। })();

একটি কলব্যাক হিসাবে যা একবার ব্যবহৃত হয় এবং অন্য কোথাও ব্যবহার করার প্রয়োজন হয় না। হ্যান্ডলারগুলি যখন কোড কল করার ঠিক ভিতরে সংজ্ঞায়িত করা হয়, তখন কোডটি আরও স্ব-অন্তর্ভুক্ত এবং পঠনযোগ্য মনে হবে, অন্য কোথাও ফাংশন বডি খুঁজতে হবে না।

setTimeout(function () { console.log('Hello world!'); }, 1000);

কার্যকরী প্রোগ্রামিং কনস্ট্রাক্ট বা লোডাশের আর্গুমেন্ট (কলব্যাকের অনুরূপ)।

const arr = [1, 2, 3]; const double = arr.map(function (el) { return el * 2; }); console.log(double); // [2, 4, 6]

আপনি আপনার কোড কীভাবে সংগঠিত করেন? (মডিউল প্যাটার্ন, ক্লাসিক্যাল ইনহেরিটেন্স?)

অতীতে, আমি আমার মডেলগুলির জন্য Backbone ব্যবহার করতাম যা একটি আরও OOP পদ্ধতির প্রচলন করে, Backbone মডেল তৈরি করে এবং সেগুলিতে পদ্ধতি সংযুক্ত করে।

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

আমি যেখানে সম্ভব ক্লাসিক্যাল ইনহেরিটেন্স ব্যবহার করা এড়িয়ে চলি। যখন এবং যদি আমি করি, আমি [এই নিয়মগুলি] মেনে চলি।

হোস্ট অবজেক্ট এবং নেটিভ অবজেক্টের মধ্যে পার্থক্য কী?

নেটিভ অবজেক্টগুলি হল ECMAScript স্পেসিফিকেশন দ্বারা সংজ্ঞায়িত জাভাস্ক্রিপ্ট ভাষার অংশ অবজেক্ট, যেমন String, Math, RegExp, Object, Function ইত্যাদি।

হোস্ট অবজেক্টগুলি রানটাইম এনভায়রনমেন্ট (ব্রাউজার বা নোড) দ্বারা সরবরাহ করা হয়, যেমন window, XMLHTTPRequest ইত্যাদি।

পার্থক্যগুলি: `function Person(){}`, `var person = Person()`, এবং `var person = new Person()`?

এই প্রশ্নটি বেশ অস্পষ্ট। আমার সেরা অনুমান হল এটি জাভাস্ক্রিপ্টে কনস্ট্রাক্টর সম্পর্কে জিজ্ঞাসা করছে। প্রযুক্তিগতভাবে বলতে গেলে, function Person(){} কেবল একটি সাধারণ ফাংশন ডিক্লারেশন। কনভেনশন হল PascalCase ব্যবহার করা ফাংশনগুলির জন্য যা কনস্ট্রাক্টর হিসাবে ব্যবহৃত হওয়ার উদ্দেশ্যে।

var person = Person() Person-কে একটি ফাংশন হিসাবে আহ্বান করে, কনস্ট্রাক্টর হিসাবে নয়। যদি ফাংশনটি একটি কনস্ট্রাক্টর হিসাবে ব্যবহৃত হওয়ার উদ্দেশ্যে হয় তবে এটি একটি সাধারণ ভুল। সাধারণত, কনস্ট্রাক্টর কিছু ফেরত দেয় না, তাই একটি সাধারণ ফাংশনের মতো কনস্ট্রাক্টরকে আহ্বান করলে undefined ফেরত দেবে এবং সেটি ইনস্ট্যান্স হিসাবে উদ্দেশ্য করা ভেরিয়েবলে অ্যাসাইন করা হবে।

var person = new Person() new অপারেটর ব্যবহার করে Person অবজেক্টের একটি ইনস্ট্যান্স তৈরি করে, যা Person.prototype থেকে উত্তরাধিকার সূত্রে প্রাপ্ত। একটি বিকল্প হবে Object.create ব্যবহার করা, যেমন: Object.create(Person.prototype)

function Person(name) { this.name = name; } var person = Person('John'); console.log(person); // undefined console.log(person.name); // Uncaught TypeError: undefined এর 'name' বৈশিষ্ট্য পড়তে পারে না var person = new Person('John'); console.log(person); // Person { name: "John" } console.log(person.name); // "john"

`.call` এবং `.apply` এর মধ্যে পার্থক্য কী?

উভয় .call এবং .apply ফাংশন আহ্বান করতে ব্যবহৃত হয় এবং প্রথম প্যারামিটারটি ফাংশনের মধ্যে this এর মান হিসাবে ব্যবহৃত হবে। তবে, .call পরবর্তী আর্গুমেন্ট হিসাবে কমা-বিচ্ছিন্ন আর্গুমেন্ট গ্রহণ করে যখন .apply পরবর্তী আর্গুমেন্ট হিসাবে আর্গুমেন্টের একটি অ্যারে গ্রহণ করে। এটি মনে রাখার একটি সহজ উপায় হল C এর জন্য call এবং কমা-বিচ্ছিন্ন এবং A এর জন্য apply এবং আর্গুমেন্টের একটি অ্যারে।

function add(a, b) { return a + b; } console.log(add.call(null, 1, 2)); // 3 console.log(add.apply(null, [1, 2])); // 3

`Function.prototype.bind` ব্যাখ্যা করুন।

[MDN] থেকে শব্দ-থেকে-শব্দ নেওয়া হয়েছে:

bind() পদ্ধতি একটি নতুন ফাংশন তৈরি করে যা, যখন কল করা হয়, তখন তার this কীওয়ার্ড প্রদত্ত মানটিতে সেট করা থাকে, একটি নির্দিষ্ট আর্গুমেন্টের ক্রম নতুন ফাংশন কল করার সময় প্রদত্ত যেকোনো আর্গুমেন্টের আগে আসে।

আমার অভিজ্ঞতায়, এটি ক্লাসগুলির পদ্ধতিগুলিতে this এর মান বাইন্ড করার জন্য সবচেয়ে দরকারী যা আপনি অন্যান্য ফাংশনগুলিতে পাস করতে চান। এটি প্রায়শই React কম্পোনেন্টগুলিতে করা হয়।

আপনি কখন `document.write()` ব্যবহার করবেন?

document.write() document.open() দ্বারা খোলা একটি ডকুমেন্ট স্ট্রিমে একটি টেক্সট স্ট্রিং লেখে। যখন পৃষ্ঠা লোড হওয়ার পর document.write() এক্সিকিউট করা হয়, তখন এটি document.open কল করবে যা পুরো ডকুমেন্ট (<head> এবং <body> সরানো হয়!) পরিষ্কার করে দেয় এবং প্রদত্ত প্যারামিটার মান দিয়ে বিষয়বস্তু প্রতিস্থাপন করে। তাই এটি সাধারণত বিপজ্জনক এবং অপব্যবহারের ঝুঁকিপূর্ণ বলে বিবেচিত হয়।

অনলাইনে কিছু উত্তর আছে যা ব্যাখ্যা করে যে document.write() অ্যানালিটিক্স কোডে বা [যখন আপনি এমন স্টাইল অন্তর্ভুক্ত করতে চান যা শুধুমাত্র জাভাস্ক্রিপ্ট সক্ষম থাকলে কাজ করবে] তখন ব্যবহার করা হয়। এটি HTML5 বয়লারপ্লেটে [স্ক্রিপ্টগুলি সমান্তরালভাবে লোড করতে এবং এক্সিকিউশন অর্ডার সংরক্ষণ করতে] ব্যবহার করা হয়! তবে, আমি সন্দেহ করি এই কারণগুলি পুরানো হয়ে গেছে এবং আধুনিক দিনে document.write() ব্যবহার না করেই সেগুলি অর্জন করা যেতে পারে। আমি যদি এই বিষয়ে ভুল করে থাকি তবে দয়া করে আমাকে সংশোধন করুন।

ফিচার ডিটেকশন, ফিচার ইনফারেন্স এবং UA স্ট্রিং ব্যবহারের মধ্যে পার্থক্য কী?

ফিচার ডিটেকশন

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

if ('geolocation' in navigator) { // navigator.geolocation ব্যবহার করা যেতে পারে } else { // ফিচারের অভাব সামলানো }

[Modernizr] ফিচার ডিটেকশন হ্যান্ডেল করার জন্য একটি দুর্দান্ত লাইব্রেরি।

ফিচার ইনফারেন্স

ফিচার ইনফারেন্স ফিচার ডিটেকশনের মতো একটি ফিচার পরীক্ষা করে, তবে এটি অন্য একটি ফাংশন ব্যবহার করে কারণ এটি ধরে নেয় যে এটিও বিদ্যমান থাকবে, উদাহরণস্বরূপ:

if (document.getElementsByTagName) { element = document.getElementById(id); }

এটি realmente সুপারিশ করা হয় না। ফিচার ডিটেকশন আরও ত্রুটিহীন।

UA স্ট্রিং

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

Ajax যতটা সম্ভব বিস্তারিতভাবে ব্যাখ্যা করুন।

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

XMLHttpRequest API প্রায়শই অ্যাসিঙ্ক্রোনাস যোগাযোগের জন্য ব্যবহৃত হয় অথবা আজকাল, fetch() API।

Ajax ব্যবহারের সুবিধা এবং অসুবিধা কী?

সুবিধাগুলি

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

অসুবিধাগুলি

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

JSONP কীভাবে কাজ করে তা ব্যাখ্যা করুন (এবং এটি আসলে Ajax নয়)।

JSONP (JSON with Padding) হল একটি পদ্ধতি যা সাধারণত ওয়েব ব্রাউজারগুলিতে ক্রস-ডোমেইন নীতিগুলি বাইপাস করতে ব্যবহৃত হয় কারণ বর্তমান পৃষ্ঠা থেকে একটি ক্রস-অরিজিন ডোমেইনে Ajax অনুরোধের অনুমতি নেই।

JSONP একটি <script> ট্যাগের মাধ্যমে এবং সাধারণত একটি callback ক্যোয়ারী প্যারামিটার সহ একটি ক্রস-অরিজিন ডোমেইনে অনুরোধ করে কাজ করে, উদাহরণস্বরূপ: https://example.com?callback=printData। সার্ভার তখন ডেটাটিকে printData নামক একটি ফাংশনের মধ্যে মোড়ানো এবং ক্লায়েন্টের কাছে ফেরত পাঠাবে।

<script> function printData(data) { console.log(`আমার নাম হল ${data.name}!`); } </script> <script src="[https://example.com?callback=printData](https://example.com?callback=printData)"></script>
printData({ name: 'ইয়াং শুন' });

ক্লায়েন্টের তার গ্লোবাল স্কোপে printData ফাংশনটি থাকতে হবে এবং ক্রস-অরিজিন ডোমেইন থেকে প্রতিক্রিয়া প্রাপ্ত হলে ক্লায়েন্ট দ্বারা ফাংশনটি এক্সিকিউট হবে।

JSONP অনিরাপদ হতে পারে এবং এর কিছু নিরাপত্তা প্রভাব রয়েছে। যেহেতু JSONP আসলে জাভাস্ক্রিপ্ট, তাই এটি জাভাস্ক্রিপ্ট যা কিছু করতে পারে তা করতে পারে, তাই আপনাকে JSONP ডেটার প্রদানকারীকে বিশ্বাস করতে হবে।

আজকাল, [CORS] হল প্রস্তাবিত পদ্ধতি এবং JSONP একটি হ্যাক হিসাবে বিবেচিত হয়।

আপনি কি কখনো জাভাস্ক্রিপ্ট টেমপ্লেটিং ব্যবহার করেছেন? যদি তাই হয়, আপনি কোন লাইব্রেরি ব্যবহার করেছেন?

হ্যাঁ। হ্যান্ডেলবার্স, আন্ডারস্কোর, লোডাশ, AngularJS, এবং JSX। আমি AngularJS-এ টেমপ্লেটিং পছন্দ করতাম না কারণ এটি নির্দেশাবলীতে স্ট্রিংয়ের ব্যাপক ব্যবহার করত এবং টাইপো ধরা পড়ত না। JSX আমার নতুন প্রিয় কারণ এটি জাভাস্ক্রিপ্টের কাছাকাছি এবং শেখার জন্য প্রায় কোনও সিনট্যাক্স নেই। আজকাল, আপনি এমনকি তৃতীয় পক্ষের কোডের উপর নির্ভর না করে দ্রুত টেমপ্লেট তৈরির জন্য ES2015 টেমপ্লেট স্ট্রিং লিটারেল ব্যবহার করতে পারেন।

const template = `<div>আমার নাম হল: ${name}</div>`;

তবে, উপরের পদ্ধতিতে একটি সম্ভাব্য XSS সম্পর্কে সচেতন থাকুন কারণ টেমপ্লেটিং লাইব্রেরিগুলির মতো আপনার জন্য বিষয়বস্তু এস্কেপ করা হয় না।

"হোস্টিং" ব্যাখ্যা করুন।

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

মনে রাখবেন যে ঘোষণাটি আসলে সরানো হয় না - জাভাস্ক্রিপ্ট ইঞ্জিন সংকলনের সময় ঘোষণাগুলি পার্স করে এবং ঘোষণা এবং তাদের স্কোপ সম্পর্কে সচেতন হয়। ঘোষণাগুলিকে তাদের স্কোপের শীর্ষে হোস্ট করা হয়েছে বলে কল্পনা করে এই আচরণটি বোঝা সহজ। কয়েকটি উদাহরণ দিয়ে ব্যাখ্যা করা যাক।

console.log(foo); // undefined var foo = 1; console.log(foo); // 1

ফাংশন ডিক্লারেশনগুলির বডি হোস্ট করা হয় যখন ফাংশন এক্সপ্রেশনগুলির (ভেরিয়েবল ডিক্লারেশনের আকারে লেখা) শুধুমাত্র ভেরিয়েবল ডিক্লারেশন হোস্ট করা হয়।

// ফাংশন ডিক্লারেশন console.log(foo); // [Function: foo] foo(); // 'ফূওওওও' function foo() { console.log('ফূওওওও'); } console.log(foo); // [Function: foo] // ফাংশন এক্সপ্রেশন console.log(bar); // undefined bar(); // Uncaught TypeError: bar একটি ফাংশন নয় var bar = function () { console.log('বারররর'); }; console.log(bar); // [Function: bar]

let এবং const এর মাধ্যমে ঘোষিত ভেরিয়েবলগুলিও হোস্ট করা হয়। তবে, var এবং function এর বিপরীতে, তারা ইনিশিয়ালাইজ করা হয় না এবং ঘোষণার আগে তাদের অ্যাক্সেস করলে একটি ReferenceError ব্যতিক্রম ঘটবে। ভেরিয়েবলটি ব্লকের শুরু থেকে ঘোষণা প্রক্রিয়া না হওয়া পর্যন্ত একটি "টেম্পোরাল ডেড জোন" এ থাকে।

x; // undefined y; // রেফারেন্স ত্রুটি: y সংজ্ঞায়িত নয় var x = 'local'; let y = 'local';

ইভেন্ট বাবলিং বর্ণনা করুন।

যখন একটি DOM উপাদানে একটি ইভেন্ট ট্রিগার হয়, তখন যদি একটি লিসেনার সংযুক্ত থাকে তবে এটি ইভেন্টটি হ্যান্ডেল করার চেষ্টা করবে, তারপর ইভেন্টটি তার প্যারেন্টে বাবল আপ হয় এবং একই ঘটনা ঘটে। এই বাবলিং উপাদানটির পূর্বপুরুষদের মাধ্যমে document পর্যন্ত ঘটে। ইভেন্ট বাবলিং হল ইভেন্ট ডেলিগেশনের পিছনের প্রক্রিয়া।

একটি "অ্যাট্রিবিউট" এবং একটি "প্রপার্টি" এর মধ্যে পার্থক্য কী?

অ্যাট্রিবিউটগুলি HTML মার্কআপে সংজ্ঞায়িত হয় কিন্তু প্রপার্টিগুলি DOM এ সংজ্ঞায়িত হয়। পার্থক্যটি বোঝাতে, কল্পনা করুন আমাদের HTML এ এই টেক্সট ফিল্ডটি আছে: <input type="text" value="Hello">

const input = document.querySelector('input'); console.log(input.getAttribute('value')); // হ্যালো console.log(input.value); // হ্যালো

কিন্তু আপনি টেক্সট ফিল্ডের মান পরিবর্তন করার পর এতে "World!" যোগ করে, এটি এমন হয়:

console.log(input.getAttribute('value')); // হ্যালো console.log(input.value); // হ্যালো ওয়ার্ল্ড!

বিল্ট-ইন জাভাস্ক্রিপ্ট অবজেক্টগুলি এক্সটেন্ড করা কেন একটি ভালো ধারণা নয়?

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

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

ডকুমেন্ট `load` ইভেন্ট এবং ডকুমেন্ট `DOMContentLoaded` ইভেন্টের মধ্যে পার্থক্য কী?

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

window-এর load ইভেন্টটি শুধুমাত্র DOM এবং সমস্ত নির্ভরশীল সম্পদ এবং অ্যাসেট লোড হওয়ার পরেই ট্রিগার হয়।

`==` এবং `===` এর মধ্যে পার্থক্য কী?

== হল অ্যাবস্ট্রাক্ট ইকুয়ালিটি অপারেটর যখন === হল স্ট্রিক্ট ইকুয়ালিটি অপারেটর। == অপারেটর যেকোনো প্রয়োজনীয় টাইপ রূপান্তর করার পরে সমতার জন্য তুলনা করবে। === অপারেটর টাইপ রূপান্তর করবে না, তাই যদি দুটি মান একই টাইপের না হয় তবে === কেবল false ফেরত দেবে। == ব্যবহার করার সময়, মজার ঘটনা ঘটতে পারে, যেমন:

1 == '1'; // true 1 == [1]; // true 1 == true; // true 0 == ''; // true 0 == '0'; // true 0 == false; // true

আমার পরামর্শ হল == অপারেটর কখনই ব্যবহার না করা, null বা undefined এর সাথে তুলনা করার সুবিধার জন্য ছাড়া, যেখানে a == null true ফেরত দেবে যদি a null বা undefined হয়।

var a = null; console.log(a == null); // true console.log(a == undefined); // true

জাভাস্ক্রিপ্টের সাথে সম্পর্কিত একই-উৎপত্তি নীতি ব্যাখ্যা করুন।

একই-উৎপত্তি নীতি জাভাস্ক্রিপ্টকে ডোমেইন সীমানা জুড়ে অনুরোধ করা থেকে বাধা দেয়। একটি উৎসকে URI স্কিম, হোস্টনেম এবং পোর্ট নম্বরের সমন্বয় হিসাবে সংজ্ঞায়িত করা হয়। এই নীতি একটি পৃষ্ঠার একটি দূষিত স্ক্রিপ্টকে সেই পৃষ্ঠার ডকুমেন্ট অবজেক্ট মডেলের মাধ্যমে অন্য একটি ওয়েব পৃষ্ঠার সংবেদনশীল ডেটাতে অ্যাক্সেস পেতে বাধা দেয়।

এটি কাজ করুন:

duplicate([1, 2, 3, 4, 5]); // [1,2,3,4,5,1,2,3,4,5]
function duplicate(arr) { return arr.concat(arr); } duplicate([1, 2, 3, 4, 5]); // [1,2,3,4,5,1,2,3,4,5]

অথবা ES6 দিয়ে:

const duplicate = (arr) => [...arr, ...arr]; duplicate([1, 2, 3, 4, 5]); // [1,2,3,4,5,1,2,3,4,5]

কেন এটিকে ট্যারনারি এক্সপ্রেশন বলা হয়, 'ট্যারনারি' শব্দটি কী নির্দেশ করে?

'ট্যারনারি' তিনটি বোঝায়, এবং একটি ট্যারনারি এক্সপ্রেশন তিনটি অপারেন্ড গ্রহণ করে, পরীক্ষা শর্ত, 'দেন' এক্সপ্রেশন এবং 'এলস' এক্সপ্রেশন। ট্যারনারি এক্সপ্রেশন জাভাস্ক্রিপ্টের জন্য নির্দিষ্ট নয় এবং কেন এটি এই তালিকায় আছে আমি নিশ্চিত নই।

`"use strict";` কী? এটি ব্যবহারের সুবিধা এবং অসুবিধা কী?

'use strict' হল একটি স্টেটমেন্ট যা পুরো স্ক্রিপ্ট বা পৃথক ফাংশনে কঠোর মোড সক্ষম করতে ব্যবহৃত হয়। কঠোর মোড হল জাভাস্ক্রিপ্টের একটি সীমাবদ্ধ বৈকল্পিকে অপ্ট ইন করার একটি উপায়।

সুবিধা:

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

অসুবিধা:

  • অনেক অনুপস্থিত বৈশিষ্ট্য যা কিছু ডেভেলপার অভ্যস্ত হতে পারে।
  • function.caller এবং function.arguments এ আর অ্যাক্সেস নেই।
  • বিভিন্ন কঠোর মোডে লেখা স্ক্রিপ্টগুলির সংযোজন সমস্যার কারণ হতে পারে।

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

একটি ফর লুপ তৈরি করুন যা `100` পর্যন্ত পুনরাবৃত্তি করে যখন `3` এর গুণিতকে "fizz", `5` এর গুণিতকে "buzz" এবং `3` এবং `5` এর গুণিতকে "fizzbuzz" আউটপুট করে।

[Paul Irish] দ্বারা তৈরি FizzBuzz এর এই সংস্করণটি দেখুন।

for (let i = 1; i <= 100; i++) { let f = i % 3 == 0, b = i % 5 == 0; console.log(f ? (b ? 'FizzBuzz' : 'Fizz') : b ? 'Buzz' : i); }

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

সাধারণভাবে, একটি ওয়েবসাইটের গ্লোবাল স্কোপকে যেমন আছে তেমনই রাখা এবং এটিকে কখনও স্পর্শ না করা কেন একটি ভালো ধারণা?

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

আপনি কেন `load` ইভেন্টের মতো কিছু ব্যবহার করবেন? এই ইভেন্টের কি কোনো অসুবিধা আছে? আপনি কি কোনো বিকল্প জানেন, এবং কেন আপনি সেগুলি ব্যবহার করবেন?

load ইভেন্টটি ডকুমেন্ট লোডিং প্রক্রিয়ার শেষে ট্রিগার হয়। এই মুহুর্তে, ডকুমেন্টের সমস্ত অবজেক্ট DOM-এ থাকে এবং সমস্ত চিত্র, স্ক্রিপ্ট, লিঙ্ক এবং সাব-ফ্রেম লোড হওয়া শেষ করে।

DOM ইভেন্ট DOMContentLoaded পৃষ্ঠাটির DOM তৈরি হওয়ার পরে ট্রিগার হবে, তবে অন্যান্য সম্পদ লোড হওয়ার জন্য অপেক্ষা করবে না। কিছু নির্দিষ্ট ক্ষেত্রে এটি পছন্দের হয় যখন ইনিশিয়ালাইজ করার আগে আপনার পুরো পৃষ্ঠা লোড হওয়ার প্রয়োজন হয় না।

একটি একক পৃষ্ঠার অ্যাপ কী এবং কীভাবে এটিকে SEO-বান্ধব করা যায় তা ব্যাখ্যা করুন।

নীচের অংশটি দুর্দান্ত [Grab Front End Guide] থেকে নেওয়া হয়েছে, যা কাকতালীয়ভাবে, আমি নিজেই লিখেছি!

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

তবে, আধুনিক SPA-তে, পরিবর্তে ক্লায়েন্ট-সাইড রেন্ডারিং ব্যবহার করা হয়। ব্রাউজার সার্ভার থেকে প্রাথমিক পৃষ্ঠা লোড করে, সাথে পুরো অ্যাপের জন্য প্রয়োজনীয় স্ক্রিপ্ট (ফ্রেমওয়ার্ক, লাইব্রেরি, অ্যাপ কোড) এবং স্টাইলশীট লোড করে। যখন ব্যবহারকারী অন্যান্য পৃষ্ঠায় নেভিগেট করে, তখন একটি পৃষ্ঠা রিফ্রেশ ট্রিগার হয় না। পৃষ্ঠার URL [HTML5 History API] এর মাধ্যমে আপডেট করা হয়। নতুন পৃষ্ঠার জন্য প্রয়োজনীয় নতুন ডেটা, সাধারণত JSON ফরম্যাটে, ব্রাউজার সার্ভারে [AJAX] অনুরোধের মাধ্যমে পুনরুদ্ধার করে। SPA তখন জাভাস্ক্রিপ্টের মাধ্যমে গতিশীলভাবে ডেটা দিয়ে পৃষ্ঠাটি আপডেট করে, যা এটি ইতিমধ্যে প্রাথমিক পৃষ্ঠা লোডের সময় ডাউনলোড করেছে। এই মডেলটি স্থানীয় মোবাইল অ্যাপগুলি কীভাবে কাজ করে তার অনুরূপ।

সুবিধাগুলি:

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

অসুবিধাগুলি:

  • একাধিক পৃষ্ঠার জন্য প্রয়োজনীয় ফ্রেমওয়ার্ক, অ্যাপ কোড এবং অ্যাসেট লোড করার কারণে ভারী প্রাথমিক পৃষ্ঠা লোড হয়।
  • আপনার সার্ভারে একটি অতিরিক্ত ধাপ করতে হবে যা হল সমস্ত অনুরোধকে একটি একক এন্ট্রি পয়েন্টে রুট করতে এবং সেখান থেকে ক্লায়েন্ট-সাইড রাউটিংকে দায়িত্ব নিতে অনুমতি দিতে হবে।
  • SPA গুলি বিষয়বস্তু রেন্ডার করার জন্য জাভাস্ক্রিপ্টের উপর নির্ভরশীল, তবে সমস্ত সার্চ ইঞ্জিন ক্রলিংয়ের সময় জাভাস্ক্রিপ্ট এক্সিকিউট করে না, এবং তারা আপনার পৃষ্ঠায় খালি বিষয়বস্তু দেখতে পারে। এটি অনিচ্ছাকৃতভাবে আপনার অ্যাপের সার্চ ইঞ্জিন অপ্টিমাইজেশন (SEO) ক্ষতি করে। তবে, বেশিরভাগ সময়, যখন আপনি অ্যাপ তৈরি করছেন, SEO সবচেয়ে গুরুত্বপূর্ণ বিষয় নয়, কারণ সমস্ত বিষয়বস্তু সার্চ ইঞ্জিন দ্বারা ইন্ডেক্সযোগ্য হতে হবে না। এটি কাটিয়ে উঠতে, আপনি আপনার অ্যাপ সার্ভার-সাইড রেন্ডার করতে পারেন অথবা [Prerender] এর মতো পরিষেবা ব্যবহার করতে পারেন যাতে "আপনার জাভাস্ক্রিপ্ট একটি ব্রাউজারে রেন্ডার করা হয়, স্ট্যাটিক HTML সংরক্ষণ করা হয়, এবং ক্রলারগুলিতে সেটি ফেরত দেওয়া হয়"।

প্রমিজ এবং/অথবা তাদের পলিফিলগুলির সাথে আপনার অভিজ্ঞতার পরিধি কী?

এটির কার্যকরী জ্ঞান আছে। একটি প্রমিজ হল একটি অবজেক্ট যা ভবিষ্যতে কোনো এক সময় একটি একক মান তৈরি করতে পারে: হয় একটি সমাধান করা মান অথবা এটির সমাধান না হওয়ার কারণ (যেমন, একটি নেটওয়ার্ক ত্রুটি ঘটেছে)। একটি প্রমিজ 3টি সম্ভাব্য অবস্থার মধ্যে একটিতে থাকতে পারে: পূরণ হয়েছে, বাতিল হয়েছে, বা মুলতুবি আছে। প্রমিজ ব্যবহারকারীরা পূরণ হওয়া মান বা বাতিল হওয়ার কারণ হ্যান্ডেল করার জন্য কলব্যাক সংযুক্ত করতে পারে।

কিছু সাধারণ পলিফিল হল $.deferred, Q এবং Bluebird কিন্তু তাদের সবগুলি স্পেসিফিকেশন মেনে চলে না। ES2015 প্রমিজগুলিকে আউট অফ দ্য বক্স সমর্থন করে এবং আজকাল সাধারণত পলিফিলের প্রয়োজন হয় না।

কলব্যাকের পরিবর্তে প্রমিজ ব্যবহারের সুবিধা এবং অসুবিধা কী?

সুবিধা

  • কলব্যাক হেল এড়ানো যায় যা অপঠনযোগ্য হতে পারে।
  • .then() দিয়ে পঠনযোগ্য ক্রমিক অ্যাসিঙ্ক্রোনাস কোড লেখা সহজ করে।
  • Promise.all() দিয়ে সমান্তরাল অ্যাসিঙ্ক্রোনাস কোড লেখা সহজ করে।
  • প্রমিজের মাধ্যমে, কলব্যাক-শুধুমাত্র কোডিংয়ে উপস্থিত এই পরিস্থিতিগুলি ঘটবে না:
    • খুব তাড়াতাড়ি কলব্যাক কল করা
    • খুব দেরিতে কলব্যাক কল করা (অথবা কখনো নয়)
    • খুব কম বা খুব বেশি বার কলব্যাক কল করা
    • কোনো প্রয়োজনীয় পরিবেশ/প্যারামিটার পাস করতে ব্যর্থ হওয়া
    • ঘটতে পারে এমন যেকোনো ত্রুটি/ব্যতিক্রম গিলে ফেলা

অসুবিধা

  • সামান্য বেশি জটিল কোড (বিতর্কিত)।
  • পুরানো ব্রাউজারে যেখানে ES2015 সমর্থিত নয়, সেখানে এটি ব্যবহার করার জন্য আপনাকে একটি পলিফিল লোড করতে হবে।

জাভাস্ক্রিপ্ট কোড এমন একটি ভাষায় লেখার কিছু সুবিধা/অসুবিধা কী যা জাভাস্ক্রিপ্টে কম্পাইল হয়?

জাভাস্ক্রিপ্টে কম্পাইল হওয়া ভাষাগুলির কিছু উদাহরণ হল CoffeeScript, Elm, ClojureScript, PureScript এবং TypeScript।

সুবিধা:

  • জাভাস্ক্রিপ্টে দীর্ঘস্থায়ী কিছু সমস্যা সমাধান করে এবং জাভাস্ক্রিপ্ট অ্যান্টি-প্যাটার্নগুলিকে নিরুৎসাহিত করে।
  • জাভাস্ক্রিপ্টের উপরে কিছু সিনট্যাকটিক সুগার প্রদান করে আপনাকে ছোট কোড লিখতে সক্ষম করে, যা আমি মনে করি ES5 এর অভাব ছিল, তবে ES2015 দুর্দান্ত।
  • স্ট্যাটিক টাইপগুলি দুর্দান্ত (টাইপস্ক্রিপ্টের ক্ষেত্রে) বড় প্রকল্পগুলির জন্য যা সময়ের সাথে বজায় রাখতে হবে।

অসুবিধা:

  • একটি বিল্ড/কম্পাইল প্রক্রিয়া প্রয়োজন কারণ ব্রাউজারগুলি শুধুমাত্র জাভাস্ক্রিপ্ট চালায় এবং আপনার কোড ব্রাউজারগুলিতে পরিবেশন করার আগে জাভাস্ক্রিপ্টে কম্পাইল করতে হবে।
  • আপনার সোর্স ম্যাপগুলি আপনার প্রি-কম্পাইল করা উৎসের সাথে সুন্দরভাবে ম্যাপ না করলে ডিবাগিং একটি কষ্টকর হতে পারে।
  • বেশিরভাগ ডেভেলপার এই ভাষাগুলির সাথে পরিচিত নন এবং এটি শিখতে হবে। আপনি যদি আপনার প্রকল্পগুলির জন্য এটি ব্যবহার করেন তবে আপনার দলের জন্য একটি র‌্যাম্প আপ খরচ জড়িত।
  • ছোট সম্প্রদায় (ভাষার উপর নির্ভর করে), যার অর্থ সম্পদ, টিউটোরিয়াল, লাইব্রেরি এবং টুলিং খুঁজে পাওয়া কঠিন হবে।
  • IDE/সম্পাদকের সমর্থন নাও থাকতে পারে।
  • এই ভাষাগুলি সর্বদা সর্বশেষ জাভাস্ক্রিপ্ট স্ট্যান্ডার্ডের চেয়ে পিছিয়ে থাকবে।
  • ডেভেলপারদের সচেতন থাকতে হবে যে তাদের কোড কীসে কম্পাইল করা হচ্ছে — কারণ সেটিই আসলে চলবে, এবং শেষ পর্যন্ত সেটাই গুরুত্বপূর্ণ।

বাস্তবে, ES2015 জাভাস্ক্রিপ্টকে ব্যাপকভাবে উন্নত করেছে এবং এটিকে লিখতে আরও সুন্দর করে তুলেছে। আজকাল আমার কাছে CoffeeScript এর প্রয়োজন মনে হয় না।

জাভাস্ক্রিপ্ট কোড ডিবাগ করার জন্য আপনি কোন সরঞ্জাম এবং কৌশল ব্যবহার করেন?

  • React এবং Redux
    • [React Devtools]
    • [Redux Devtools]
  • Vue
    • [Vue Devtools]
  • জাভাস্ক্রিপ্ট
    • [Chrome Devtools]
    • debugger স্টেটমেন্ট
    • ভালো পুরাতন console.log ডিবাগিং

অবজেক্ট প্রপার্টি এবং অ্যারে আইটেমগুলিতে পুনরাবৃত্তি করার জন্য আপনি কোন ভাষার নির্মাণ ব্যবহার করেন?

অবজেক্টের জন্য:

  • for-in লুপ - for (var property in obj) { console.log(property); }। তবে, এটি এর উত্তরাধিকারসূত্রে প্রাপ্ত বৈশিষ্ট্যগুলির মধ্য দিয়েও পুনরাবৃত্তি করবে, এবং আপনি এটি ব্যবহার করার আগে একটি obj.hasOwnProperty(property) চেক যোগ করবেন।
  • Object.keys() - Object.keys(obj).forEach(function (property) { ... })Object.keys() একটি স্ট্যাটিক পদ্ধতি যা আপনার কাছে পাস করা অবজেক্টের সমস্ত এনুমেরেবল বৈশিষ্ট্য তালিকাভুক্ত করবে।
  • Object.getOwnPropertyNames() - Object.getOwnPropertyNames(obj).forEach(function (property) { ... })Object.getOwnPropertyNames() একটি স্ট্যাটিক পদ্ধতি যা আপনার কাছে পাস করা অবজেক্টের সমস্ত এনুমেরেবল এবং নন-এনুমেরেবল বৈশিষ্ট্য তালিকাভুক্ত করবে।

অ্যারের জন্য:

  • for লুপ - for (var i = 0; i < arr.length; i++)। এখানে সাধারণ ত্রুটি হল যে var ফাংশন স্কোপে থাকে এবং ব্লক স্কোপে নয় এবং বেশিরভাগ সময় আপনি ব্লক স্কোপড ইটারেটর ভেরিয়েবল চাইবেন। ES2015 let প্রবর্তন করে যা ব্লক স্কোপ রয়েছে এবং পরিবর্তে এটি ব্যবহার করার সুপারিশ করা হয়। সুতরাং এটি হয়ে যায়: for (let i = 0; i < arr.length; i++)
  • forEach - arr.forEach(function (el, index) { ... })। এই কনস্ট্রাক্টটি মাঝে মাঝে আরও সুবিধাজনক হতে পারে কারণ আপনার যদি শুধুমাত্র অ্যারে উপাদানগুলির প্রয়োজন হয় তবে আপনাকে index ব্যবহার করতে হবে না। এছাড়াও every এবং some পদ্ধতি রয়েছে যা আপনাকে পুনরাবৃত্তিটি তাড়াতাড়ি শেষ করতে দেবে।
  • for-of লুপ - for (let elem of arr) { ... }। ES6 একটি নতুন লুপ প্রবর্তন করে, for-of লুপ, যা আপনাকে String, Array, Map, Set ইত্যাদির মতো পুনরাবৃত্তিযোগ্য প্রোটোকল মেনে চলা অবজেক্টগুলির উপর লুপ করতে দেয়। এটি for লুপ এবং forEach() পদ্ধতির সুবিধাগুলিকে একত্রিত করে। for লুপের সুবিধা হল যে আপনি এটি থেকে বিরতি দিতে পারেন, এবং forEach() এর সুবিধা হল এটি for লুপের চেয়ে বেশি সংক্ষিপ্ত কারণ আপনার একটি কাউন্টার ভেরিয়েবলের প্রয়োজন নেই। for-of লুপের মাধ্যমে, আপনি একটি লুপ থেকে বিরতি দেওয়ার ক্ষমতা এবং আরও সংক্ষিপ্ত সিনট্যাক্স উভয়ই পান।

বেশিরভাগ সময়, আমি .forEach পদ্ধতিটি পছন্দ করব, তবে এটি আসলে আপনি কী করতে চান তার উপর নির্ভর করে। ES6 এর আগে, যখন আমাদের break ব্যবহার করে লুপটি অকালিকভাবে শেষ করার প্রয়োজন হত তখন আমরা for লুপ ব্যবহার করতাম। কিন্তু এখন ES6 এর সাথে, আমরা for-of লুপ দিয়ে তা করতে পারি। যখন আমার আরও বেশি নমনীয়তা প্রয়োজন হয়, যেমন প্রতি লুপে একাধিকবার ইটারেটর বৃদ্ধি করা, তখন আমি for লুপ ব্যবহার করব।

এছাড়াও, for-of লুপ ব্যবহার করার সময়, যদি আপনার প্রতিটি অ্যারে উপাদানের সূচক এবং মান উভয়ই অ্যাক্সেস করার প্রয়োজন হয়, তবে আপনি ES6 অ্যারে entries() পদ্ধতি এবং ডিস্ট্রাকচারিংয়ের মাধ্যমে তা করতে পারেন:

const arr = ['a', 'b', 'c']; for (let [index, elem] of arr.entries()) { console.log(index, ': ', elem); }

মিউটেবল এবং ইমিউটেবল অবজেক্টের মধ্যে পার্থক্য ব্যাখ্যা করুন।

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

জাভাস্ক্রিপ্টে ইমিউটেবল অবজেক্টের একটি উদাহরণ কী?

জাভাস্ক্রিপ্টে, কিছু বিল্ট-ইন টাইপ (সংখ্যা, স্ট্রিং) ইমিউটেবল, তবে কাস্টম অবজেক্টগুলি সাধারণত মিউটেবল হয়।

কিছু বিল্ট-ইন ইমিউটেবল জাভাস্ক্রিপ্ট অবজেক্ট হল Math, Date

সাধারণ জাভাস্ক্রিপ্ট অবজেক্টে ইমিউটেবিলিটি যোগ/সিমুলেট করার কয়েকটি উপায় এখানে দেওয়া হল।

অবজেক্ট কনস্ট্যান্ট প্রপার্টিস

writable: false এবং configurable: false একত্রিত করে, আপনি মূলত একটি কনস্ট্যান্ট (পরিবর্তন করা যাবে না, পুনরায় সংজ্ঞায়িত করা যাবে না বা মুছে ফেলা যাবে না) একটি অবজেক্ট প্রপার্টি হিসাবে তৈরি করতে পারেন, যেমন:

let myObject = {}; Object.defineProperty(myObject, 'number', { value: 42, writable: false, configurable: false, }); console.log(myObject.number); // 42 myObject.number = 43; console.log(myObject.number); // 42

এক্সটেনশন প্রতিরোধ করুন

আপনি যদি একটি অবজেক্টে নতুন প্রপার্টি যোগ করা থেকে বিরত রাখতে চান, কিন্তু অন্যথায় অবজেক্টের বাকি প্রপার্টিগুলিকে একা রাখতে চান, তবে Object.preventExtensions(...) কল করুন:

var myObject = { a: 2, }; Object.preventExtensions(myObject); myObject.b = 3; myObject.b; // undefined

নন-স্ট্রিক্ট মোডে, b তৈরি ব্যর্থ হয় নীরবভাবে। স্ট্রিক্ট মোডে, এটি একটি TypeError ছুঁড়ে দেয়।

সীল

Object.seal() একটি "সীল করা" অবজেক্ট তৈরি করে, যার অর্থ এটি একটি বিদ্যমান অবজেক্ট নেয় এবং মূলত তার উপর Object.preventExtensions() কল করে, তবে এর বিদ্যমান সমস্ত প্রপার্টিকে configurable: false হিসাবে চিহ্নিত করে।

সুতরাং, আপনি আর কোনো প্রপার্টি যোগ করতে পারবেন না, তবে আপনি কোনো বিদ্যমান প্রপার্টি পুনরায় কনফিগার বা মুছতে পারবেন না (যদিও আপনি এখনও তাদের মান পরিবর্তন করতে পারবেন)।

ফ্রিজ

Object.freeze() একটি হিমায়িত অবজেক্ট তৈরি করে, যার অর্থ এটি একটি বিদ্যমান অবজেক্ট নেয় এবং মূলত তার উপর Object.seal() কল করে, তবে এটি সমস্ত "ডেটা অ্যাক্সেসর" প্রপার্টিকে writable:false হিসাবে চিহ্নিত করে, যাতে তাদের মান পরিবর্তন করা না যায়।

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

var immutable = Object.freeze({});

একটি অবজেক্ট ফ্রিজ করা একটি অবজেক্টে নতুন প্রপার্টি যোগ করার অনুমতি দেয় না এবং বিদ্যমান প্রপার্টিগুলি সরানো বা পরিবর্তন করা থেকে বিরত থাকে। Object.freeze() অবজেক্টের এনুমেরেবিলিটি, কনফিগারাবিলিটি, রাইটেবিলিটি এবং প্রোটোটাইপ সংরক্ষণ করে। এটি পাস করা অবজেক্টটি ফেরত দেয় এবং একটি হিমায়িত কপি তৈরি করে না।

ইমিউটেবিলিটির সুবিধা এবং অসুবিধা কী?

সুবিধা

  • পরিবর্তন সনাক্তকরণ সহজ - অবজেক্টের সমতা রেফারেনশিয়াল ইকুয়ালিটির মাধ্যমে কার্যকর এবং সহজে নির্ধারণ করা যায়। এটি React এবং Redux এ অবজেক্টের পার্থক্য তুলনা করার জন্য দরকারী।
  • ইমিউটেবল অবজেক্ট সহ প্রোগ্রামগুলি সম্পর্কে চিন্তা করা কম জটিল, কারণ আপনাকে একটি অবজেক্ট সময়ের সাথে কীভাবে বিকশিত হতে পারে তা নিয়ে চিন্তা করতে হবে না।
  • যখন ইমিউটেবল অবজেক্টগুলি ফাংশন থেকে ফেরত আসে বা ফাংশনে পাস করা হয় তখন প্রতিরক্ষামূলক কপিগুলির আর প্রয়োজন হয় না, কারণ একটি ইমিউটেবল অবজেক্ট এর দ্বারা পরিবর্তিত হওয়ার কোনো সম্ভাবনা থাকে না।
  • রেফারেন্সের মাধ্যমে সহজ শেয়ারিং - একটি অবজেক্টের একটি কপি অন্যটির মতোই ভালো, তাই আপনি অবজেক্ট ক্যাশ করতে পারেন বা একই অবজেক্ট একাধিকবার পুনরায় ব্যবহার করতে পারেন।
  • থ্রেড-নিরাপদ - ইমিউটেবল অবজেক্টগুলি একটি মাল্টি-থ্রেডেড পরিবেশে থ্রেডগুলির মধ্যে নিরাপদে ব্যবহার করা যেতে পারে কারণ অন্যান্য সমান্তরালভাবে চলমান থ্রেডগুলিতে তাদের পরিবর্তিত হওয়ার কোনো ঝুঁকি নেই।
  • ImmutableJS-এর মতো লাইব্রেরি ব্যবহার করে, অবজেক্টগুলি স্ট্রাকচারাল শেয়ারিং ব্যবহার করে পরিবর্তিত হয় এবং একই কাঠামোর একাধিক অবজেক্টের জন্য কম মেমরি প্রয়োজন হয়।

অসুবিধা

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

আপনার নিজের কোডে আপনি কীভাবে ইমিউটেবিলিটি অর্জন করতে পারেন?

বিকল্প হল const ঘোষণাগুলি উপরের উল্লেখিত কৌশলগুলির সাথে একত্রিত করে তৈরি করা। অবজেক্ট "মিউটেট" করার জন্য, আসল অবজেক্ট পরিবর্তন না করে নতুন অবজেক্ট তৈরি করতে স্প্রেড অপারেটর, Object.assign, Array.concat() ইত্যাদি ব্যবহার করুন।

উদাহরণ:

// অ্যারে উদাহরণ const arr = [1, 2, 3]; const newArr = [...arr, 4]; // [1, 2, 3, 4] // অবজেক্ট উদাহরণ const human = Object.freeze({ race: 'human' }); const john = { ...human, name: 'John' }; // {race: "human", name: "John"} const alienJohn = { ...john, race: 'alien' }; // {race: "alien", name: "John"}

সিঙ্ক্রোনাস এবং অ্যাসিঙ্ক্রোনাস ফাংশনের মধ্যে পার্থক্য ব্যাখ্যা করুন।

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

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

ইভেন্ট লুপ কী? কল স্ট্যাক এবং টাস্ক কিউ এর মধ্যে পার্থক্য কী?

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

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

`function foo() {}` এবং `var foo = function() {}` এর মধ্যে `foo` এর ব্যবহারের পার্থক্য ব্যাখ্যা করুন।

পূর্বেরটি একটি ফাংশন ডিক্লারেশন যখন পরেরটি একটি ফাংশন এক্সপ্রেশন। মূল পার্থক্য হল ফাংশন ডিক্লারেশনগুলির বডি হোস্টেড হয় কিন্তু ফাংশন এক্সপ্রেশনগুলির বডি হোস্টেড হয় না (তাদের ভেরিয়েবলগুলির মতো একই হোস্টিং আচরণ থাকে)। হোস্টিং সম্পর্কে আরও ব্যাখ্যার জন্য, উপরের [হোস্টিং সম্পর্কে] প্রশ্নটি দেখুন। যদি আপনি একটি ফাংশন এক্সপ্রেশন সংজ্ঞায়িত হওয়ার আগে আহ্বান করার চেষ্টা করেন, তবে আপনি একটি Uncaught TypeError: XXX একটি ফাংশন নয় ত্রুটি পাবেন।

ফাংশন ডিক্লারেশন

foo(); // 'ফূওওওও' function foo() { console.log('ফূওওওও'); }

ফাংশন এক্সপ্রেশন

foo(); // Uncaught TypeError: foo একটি ফাংশন নয় var foo = function () { console.log('ফূওওওও'); };

`let`, `var` বা `const` ব্যবহার করে তৈরি ভেরিয়েবলগুলির মধ্যে পার্থক্য কী?

var কীওয়ার্ড ব্যবহার করে ঘোষিত ভেরিয়েবলগুলি যে ফাংশনে তৈরি করা হয় তার স্কোপের মধ্যে সীমাবদ্ধ থাকে, অথবা যদি কোনো ফাংশনের বাইরে তৈরি করা হয় তবে গ্লোবাল অবজেক্টের মধ্যে সীমাবদ্ধ থাকে। let এবং const হল ব্লক স্কোপড, যার অর্থ তারা কেবল নিকটতম কার্লি ব্রেসের সেটের মধ্যে অ্যাক্সেসযোগ্য (ফাংশন, if-else ব্লক বা for-লুপ)।

function foo() { // সমস্ত ভেরিয়েবল ফাংশনগুলির মধ্যে অ্যাক্সেসযোগ্য। var bar = 'bar'; let baz = 'baz'; const qux = 'qux'; console.log(bar); // bar console.log(baz); // baz console.log(qux); // qux } console.log(bar); // ReferenceError: bar সংজ্ঞায়িত নয় console.log(baz); // ReferenceError: baz সংজ্ঞায়িত নয় console.log(qux); // ReferenceError: qux সংজ্ঞায়িত নয়
if (true) { var bar = 'bar'; let baz = 'baz'; const qux = 'qux'; } // var ঘোষিত ভেরিয়েবলগুলি ফাংশন স্কোপের যেকোনো স্থানে অ্যাক্সেসযোগ্য। console.log(bar); // bar // let এবং const সংজ্ঞায়িত ভেরিয়েবলগুলি যে ব্লকে সংজ্ঞায়িত হয়েছিল তার বাইরে অ্যাক্সেসযোগ্য নয়। console.log(baz); // ReferenceError: baz সংজ্ঞায়িত নয় console.log(qux); // ReferenceError: qux সংজ্ঞায়িত নয়

var ভেরিয়েবলগুলিকে হোয়িস্ট করার অনুমতি দেয়, যার অর্থ সেগুলি ঘোষিত হওয়ার আগে কোডে রেফারেন্স করা যেতে পারে। let এবং const এটি অনুমতি দেবে না, পরিবর্তে একটি ত্রুটি ছুঁড়ে দেবে।

console.log(foo); // undefined var foo = 'foo'; console.log(baz); // ReferenceError: ইনিশিয়ালাইজেশনের আগে লেক্সিক্যাল ডিক্লারেশন 'baz' অ্যাক্সেস করতে পারে না let baz = 'baz'; console.log(bar); // ReferenceError: ইনিশিয়ালাইজেশনের আগে লেক্সিক্যাল ডিক্লারেশন 'bar' অ্যাক্সেস করতে পারে না const bar = 'bar';

var দিয়ে একটি ভেরিয়েবল পুনরায় ঘোষণা করলে একটি ত্রুটি ছুঁড়বে না, কিন্তু let এবং const ছুঁড়বে।

var foo = 'foo'; var foo = 'bar'; console.log(foo); // "bar" let baz = 'baz'; let baz = 'qux'; // Uncaught SyntaxError: Identifier 'baz' ইতিমধ্যেই ঘোষিত হয়েছে

let এবং const এর মধ্যে পার্থক্য হল যে let ভেরিয়েবলের মান পুনরায় অ্যাসাইন করার অনুমতি দেয় যখন const তা করে না।

// এটা ঠিক আছে। let foo = 'foo'; foo = 'bar'; // এটা একটা ব্যতিক্রম ঘটায়। const baz = 'baz'; baz = 'qux';

ES6 ক্লাস এবং ES5 ফাংশন কনস্ট্রাক্টরগুলির মধ্যে পার্থক্য কী?

প্রথমে প্রতিটি উদাহরণ দেখি:

// ES5 ফাংশন কনস্ট্রাক্টর function Person(name) { this.name = name; } // ES6 ক্লাস class Person { constructor(name) { this.name = name; } }

সাধারণ কনস্ট্রাক্টরগুলির জন্য, তারা বেশ একই রকম দেখায়।

কনস্ট্রাক্টরের প্রধান পার্থক্য আসে উত্তরাধিকার ব্যবহার করার সময়। যদি আমরা একটি Student ক্লাস তৈরি করতে চাই যা Person এর সাবক্লাস এবং একটি studentId ফিল্ড যোগ করতে চাই, তবে উপরের ছাড়াও আমাদের যা করতে হবে তা হল:

// ES5 ফাংশন কনস্ট্রাক্টর function Student(name, studentId) { // সুপারক্লাসের কনস্ট্রাক্টর কল করুন সুপারক্লাস-প্রাপ্ত সদস্যদের ইনিশিয়ালাইজ করতে। Person.call(this, name); // সাবক্লাসের নিজস্ব সদস্যদের ইনিশিয়ালাইজ করুন। this.studentId = studentId; } Student.prototype = Object.create(Person.prototype); Student.prototype.constructor = Student; // ES6 ক্লাস class Student extends Person { constructor(name, studentId) { super(name); this.studentId = studentId; } }

ES5 এ উত্তরাধিকার ব্যবহার করা অনেক বেশি দীর্ঘ এবং ES6 সংস্করণটি বুঝতে এবং মনে রাখতে সহজ।

আপনি কি নতুন অ্যারো => ফাংশন সিনট্যাক্সের জন্য একটি ব্যবহার-কেস দিতে পারেন? এই নতুন সিনট্যাক্স অন্যান্য ফাংশন থেকে কীভাবে আলাদা?

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

একটি কনস্ট্রাক্টরে একটি পদ্ধতির জন্য অ্যারো সিনট্যাক্স ব্যবহার করার সুবিধা কী?

একটি কনস্ট্রাক্টরের ভিতরে একটি পদ্ধতি হিসাবে অ্যারো ফাংশন ব্যবহার করার প্রধান সুবিধা হল যে ফাংশন তৈরির সময় this-এর মান সেট হয়ে যায় এবং তারপর এটি পরিবর্তন করা যায় না। সুতরাং, যখন কনস্ট্রাক্টরটি একটি নতুন অবজেক্ট তৈরি করতে ব্যবহৃত হয়, তখন this সর্বদা সেই অবজেক্টটিকে নির্দেশ করবে। উদাহরণস্বরূপ, ধরুন আমাদের একটি Person কনস্ট্রাক্টর আছে যা একটি প্রথম নাম আর্গুমেন্ট হিসাবে নেয় এবং সেই নামটি console.log করার জন্য দুটি পদ্ধতি আছে, একটি নিয়মিত ফাংশন হিসাবে এবং অন্যটি অ্যারো ফাংশন হিসাবে:

const Person = function (firstName) { this.firstName = firstName; this.sayName1 = function () { console.log(this.firstName); }; this.sayName2 = () => { console.log(this.firstName); }; }; const john = new Person('John'); const dave = new Person('Dave'); john.sayName1(); // John john.sayName2(); // John // নিয়মিত ফাংশনের 'this' মান পরিবর্তন করা যেতে পারে, কিন্তু অ্যারো ফাংশনের পারে না john.sayName1.call(dave); // Dave (কারণ "this" এখন ডেভ অবজেক্ট) john.sayName2.call(dave); // John john.sayName1.apply(dave); // Dave (কারণ 'this' এখন ডেভ অবজেক্ট) john.sayName2.apply(dave); // John john.sayName1.bind(dave)(); // Dave (কারণ 'this' এখন ডেভ অবজেক্ট) john.sayName2.bind(dave)(); // John var sayNameFromWindow1 = john.sayName1; sayNameFromWindow1(); // undefined (কারণ 'this' এখন উইন্ডো অবজেক্ট) var sayNameFromWindow2 = john.sayName2; sayNameFromWindow2(); // John

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

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

একটি উচ্চ-ক্রম ফাংশনের সংজ্ঞা কী?

একটি উচ্চ-ক্রম ফাংশন হল যেকোনো ফাংশন যা এক বা একাধিক ফাংশনকে আর্গুমেন্ট হিসাবে নেয়, যা এটি কিছু ডেটার উপর কাজ করার জন্য ব্যবহার করে, এবং/অথবা একটি ফাংশনকে ফলাফল হিসাবে ফেরত দেয়। উচ্চ-ক্রম ফাংশনগুলি বারবার সম্পাদিত কিছু অপারেশনকে অ্যাবস্ট্রাক্ট করার উদ্দেশ্যে করা হয়। এর ক্লাসিক উদাহরণ হল map, যা একটি অ্যারে এবং একটি ফাংশনকে আর্গুমেন্ট হিসাবে নেয়। map তখন এই ফাংশনটি অ্যারের প্রতিটি আইটেমকে রূপান্তর করতে ব্যবহার করে, রূপান্তরিত ডেটা সহ একটি নতুন অ্যারে ফেরত দেয়। জাভাস্ক্রিপ্টে অন্যান্য জনপ্রিয় উদাহরণ হল forEach, filter এবং reduce। একটি উচ্চ-ক্রম ফাংশন কেবল অ্যারে ম্যানিপুলেট করতে হবে না কারণ অন্য ফাংশন থেকে একটি ফাংশন ফেরত দেওয়ার অনেক ব্যবহার-কেস রয়েছে। Function.prototype.bind জাভাস্ক্রিপ্টে এমন একটি উদাহরণ।

ম্যাপ

ধরা যাক আমাদের নামের একটি অ্যারে আছে যা আমাদের প্রতিটি স্ট্রিংকে আপারকেসে রূপান্তর করতে হবে।

const names = ['irish', 'daisy', 'anna'];

আবশ্যিক উপায়টি হবে নিম্নরূপ:

const transformNamesToUppercase = function (names) { const results = []; for (let i = 0; i < names.length; i++) { results.push(names[i].toUpperCase()); } return results; }; transformNamesToUppercase(names); // ['আইরিশ', 'ডেইজি', 'আনা']

.map(transformerFn) ব্যবহার করলে কোডটি ছোট এবং আরও ঘোষণামূলক হয়।

const transformNamesToUppercase = function (names) { return names.map((name) => name.toUpperCase()); }; transformNamesToUppercase(names); // ['আইরিশ', 'ডেইজি', 'আনা']

আপনি কি একটি অবজেক্ট বা একটি অ্যারে ডিস্ট্রাকচারিংয়ের একটি উদাহরণ দিতে পারেন?

ডিস্ট্রাকচারিং হল ES6 এ উপলব্ধ একটি এক্সপ্রেশন যা অবজেক্ট বা অ্যারেগুলির মানগুলিকে বের করে এবং সেগুলিকে স্বতন্ত্র ভেরিয়েবলগুলিতে স্থাপন করার একটি সংক্ষিপ্ত এবং সুবিধাজনক উপায় সক্ষম করে।

অ্যারে ডিস্ট্রাকচারিং

// ভেরিয়েবল অ্যাসাইনমেন্ট। const foo = ['one', 'two', 'three']; const [one, two, three] = foo; console.log(one); // "one" console.log(two); // "two" console.log(three); // "three"
// ভেরিয়েবল অদলবদল let a = 1; let b = 3; [a, b] = [b, a]; console.log(a); // 3 console.log(b); // 1

অবজেক্ট ডিস্ট্রাকচারিং

// ভেরিয়েবল অ্যাসাইনমেন্ট। const o = { p: 42, q: true }; const { p, q } = o; console.log(p); // 42 console.log(q); // true

ES6 টেমপ্লেট লিটারালগুলি স্ট্রিং তৈরি করার ক্ষেত্রে প্রচুর নমনীয়তা সরবরাহ করে, আপনি কি একটি উদাহরণ দিতে পারেন?

টেম্পলেট লিটারালগুলি স্ট্রিং ইন্টারপোলেশনকে সহজ করতে, বা একটি স্ট্রিংয়ে ভেরিয়েবল অন্তর্ভুক্ত করতে সাহায্য করে। ES2015 এর আগে, সাধারণত এমন কিছু করা হত:

var person = { name: 'টাইলর', age: 28 }; console.log( 'হাই, আমার নাম ' + person.name + ' এবং আমার বয়স ' + person.age + ' বছর!', ); // 'হাই, আমার নাম টাইলর এবং আমার বয়স 28 বছর!'

টেম্পলেট লিটারাল ব্যবহার করে, আপনি এখন একই আউটপুট এভাবে তৈরি করতে পারেন:

const person = { name: 'টাইলর', age: 28 }; console.log(`হাই, আমার নাম ${person.name} এবং আমার বয়স ${person.age} বছর!`); // 'হাই, আমার নাম টাইলর এবং আমার বয়স 28 বছর!'

মনে রাখবেন যে আপনি টেমপ্লেট লিটারাল ব্যবহার করছেন তা বোঝাতে ব্যাকটিক্স ব্যবহার করেন, কোটেশন নয়, এবং আপনি ${} প্লেসহোল্ডারগুলির ভিতরে এক্সপ্রেশনগুলি সন্নিবেশ করতে পারেন।

একটি দ্বিতীয় সহায়ক ব্যবহার-কেস হল বহু-লাইন স্ট্রিং তৈরি করা। ES2015 এর আগে, আপনি একটি বহু-লাইন স্ট্রিং এভাবে তৈরি করতে পারতেন:

console.log('এটি প্রথম লাইন।\nএটি দ্বিতীয় লাইন।'); // এটি প্রথম লাইন। // এটি দ্বিতীয় লাইন।

অথবা যদি আপনি আপনার কোডে এটিকে একাধিক লাইনে ভাঙতে চান যাতে একটি দীর্ঘ স্ট্রিং পড়তে আপনার টেক্সট এডিটর ডানদিকে স্ক্রল করতে না হয়, তবে আপনি এটি এভাবেও লিখতে পারতেন:

console.log('এটি প্রথম লাইন।\n' + 'এটি দ্বিতীয় লাইন।'); // এটি প্রথম লাইন। // এটি দ্বিতীয় লাইন।

তবে, টেমপ্লেট লিটারালগুলি আপনি সেগুলিতে যে স্পেসিং যোগ করেন তা সংরক্ষণ করে। উদাহরণস্বরূপ, উপরে আমরা যে একই বহু-লাইন আউটপুট তৈরি করেছি তা তৈরি করতে, আপনি কেবল করতে পারেন:

console.log(`এটি প্রথম লাইন। এটি দ্বিতীয় লাইন।`); // এটি প্রথম লাইন। // এটি দ্বিতীয় লাইন।

টেম্পলেট লিটারালগুলির আরেকটি ব্যবহার-কেস হবে সাধারণ ভেরিয়েবল ইন্টারপোলেশনের জন্য টেমপ্লেটিং লাইব্রেরিগুলির বিকল্প হিসাবে ব্যবহার করা:

const person = { name: 'টাইলর', age: 28 }; document.body.innerHTML = ` <div> <p>নাম: ${person.name}</p> <p>বয়স: ${person.age}</p> </div> `;

মনে রাখবেন যে আপনার কোড .innerHTML ব্যবহার করে XSS এর শিকার হতে পারে। ডেটা যদি ব্যবহারকারী থেকে আসে তবে এটি প্রদর্শন করার আগে স্যানিটাইজ করুন!

আপনি কি একটি কারি ফাংশনের একটি উদাহরণ দিতে পারেন এবং কেন এই সিনট্যাক্সটি একটি সুবিধা প্রদান করে?

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

function curry(fn) { if (fn.length === 0) { return fn; } function _curried(depth, args) { return function (newArgument) { if (depth - 1 === 0) { return fn(...args, newArgument); } return _curried(depth - 1, [...args, newArgument]); }; } return _curried(fn.length, []); } function add(a, b) { return a + b; } var curriedAdd = curry(add); var addFive = curriedAdd(5); var result = [0, 1, 2, 3, 4, 5].map(addFive); // [5, 6, 7, 8, 9, 10]

স্প্রেড সিনট্যাক্স ব্যবহারের সুবিধা কী এবং এটি রেস্ট সিনট্যাক্স থেকে কীভাবে আলাদা?

ES6 এর স্প্রেড সিনট্যাক্স কার্যকরী দৃষ্টান্ত ব্যবহার করে কোডিং করার সময় খুব দরকারী কারণ আমরা সহজেই অ্যারে বা অবজেক্টের কপি তৈরি করতে পারি Object.create, slice বা কোনো লাইব্রেরি ফাংশনের আশ্রয় না নিয়ে। এই ভাষার বৈশিষ্ট্যটি Redux এবং RxJS প্রকল্পগুলিতে প্রায়শই ব্যবহৃত হয়।

function putDookieInAnyArray(arr) { return [...arr, 'dookie']; } const result = putDookieInAnyArray(['I', 'really', "don't", 'like']); // ["I", "really", "don't", "like", "dookie"] const person = { name: 'টড', age: 29, }; const copyOfTodd = { ...person };

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

function addFiveToABunchOfNumbers(...numbers) { return numbers.map((x) => x + 5); } const result = addFiveToABunchOfNumbers(4, 5, 6, 7, 8, 9, 10); // [9, 10, 11, 12, 13, 14, 15] const [a, b, ...rest] = [1, 2, 3, 4]; // a: 1, b: 2, rest: [3, 4] const { e, f, ...others } = { e: 1, f: 2, g: 3, h: 4, }; // e: 1, f: 2, others: { g: 3, h: 4 }

আপনি কীভাবে ফাইলগুলির মধ্যে কোড শেয়ার করতে পারেন?

এটি জাভাস্ক্রিপ্ট পরিবেশের উপর নির্ভর করে।

ক্লায়েন্টে (ব্রাউজার পরিবেশ), যতক্ষণ ভেরিয়েবল/ফাংশনগুলি গ্লোবাল স্কোপে (window) ঘোষিত হয়, ততক্ষণ সমস্ত স্ক্রিপ্ট সেগুলি উল্লেখ করতে পারে। বিকল্পভাবে, আরও মডিউলার পদ্ধতির জন্য RequireJS এর মাধ্যমে অ্যাসিঙ্ক্রোনাস মডিউল ডেফিনিশন (AMD) গ্রহণ করুন।

সার্ভারে (Node.js), সাধারণ উপায় হল CommonJS ব্যবহার করা। প্রতিটি ফাইলকে একটি মডিউল হিসাবে বিবেচনা করা হয় এবং এটি module.exports অবজেক্টের সাথে সংযুক্ত করে ভেরিয়েবল এবং ফাংশন এক্সপোর্ট করতে পারে।

ES2015 একটি মডিউল সিনট্যাক্স সংজ্ঞায়িত করে যা AMD এবং CommonJS উভয়কেই প্রতিস্থাপন করার লক্ষ্য রাখে। এটি অবশেষে ব্রাউজার এবং নোড উভয় পরিবেশেই সমর্থিত হবে।

আপনি কেন স্ট্যাটিক ক্লাস সদস্য তৈরি করতে চাইতে পারেন?

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