আপনি যদি কিছুদিন ধরে জাভাস্ক্রিপ্টে প্রোগ্রামিং করে থাকেন, তাহলে আপনি অবশ্যই "" কীওয়ার্ডটি চিনতে পারবেন এটি আপনার একাধিক মাথাব্যথার কারণ হয়েছে।আর যেহেতু ES6 তে তীর ফাংশনগুলি উপস্থিত হয়েছে, তাই জিনিসগুলি আরও জটিল হয়ে উঠেছে... অথবা সহজতর হয়েছে, আপনি এটিকে কীভাবে দেখেন তার উপর নির্ভর করে।
এই প্রবন্ধে আমরা এটি কীভাবে কাজ করে তা ঘনিষ্ঠভাবে দেখব। এটি ঐতিহ্যবাহী ফাংশন এবং তীর ফাংশনের ক্ষেত্রে প্রযোজ্য।কেন এটি কখনও কখনও একটি নির্দিষ্ট বস্তুর দিকে নির্দেশ করে এবং কখনও কখনও বিশ্বব্যাপী বস্তুর দিকে নির্দেশ করে বলে মনে হয়, এবং কোন পরিস্থিতিতে তীর ফাংশন ব্যবহার করা যুক্তিসঙ্গত এবং কোন পরিস্থিতিতে এগুলি এড়িয়ে চলাই ভালো?
ঠিক কি this জাভাস্ক্রিপ্টে
সংরক্ষিত শব্দ this এটি কার্যকরকরণ প্রসঙ্গের একটি উল্লেখ। বর্তমানে কোন ফাংশনটি কার্যকর হচ্ছে। অন্যান্য ভাষার মতো নয়, জাভাস্ক্রিপ্টে সিদ্ধান্তটি ফাংশনটি কোথায় সংজ্ঞায়িত করা হয়েছে তার উপর নির্ভর করে না, বরং ফাংশনের কার্যকরকরণের উপর নির্ভর করে। কিভাবে আহ্বান করতে হয়.
এর মানে হল যে একই ফাংশনকে বিভিন্ন উপায়ে ডাকা যেতে পারে, এবং প্রতিটিতে, this অন্য কোনও বস্তুর দিকে নির্দেশ করতে পারেএটি এমন কিছু নয় যা আপনি সরাসরি অ্যাসাইনমেন্ট দিয়ে পরিবর্তন করতে পারবেন (আপনি করতে পারবেন না) this = algo), কিন্তু আপনি নির্দিষ্ট প্রক্রিয়ার মাধ্যমে এটিকে প্রভাবিত করতে পারেন যেমন call, apply y bind.
তদুপরি, তাদের আচরণের মধ্যে পার্থক্য রয়েছে কঠোর মোড এবং অ-কঠোর মোডনন-স্ট্রিক্ট মোডে, যদি আপনি একটি ফাংশনকে "bare" বলেন (এর সামনে কোন বস্তু ছাড়াই), this এটি সাধারণত গ্লোবাল অবজেক্ট (ব্রাউজারে, window), কঠোর মোডে থাকাকালীন এটি হতে পারে undefinedবিভিন্ন উৎস থেকে কোড উদাহরণ তুলনা করার সময় এই পার্থক্যটি গুরুত্বপূর্ণ।
এটি বিশ্বব্যাপী প্রেক্ষাপটে এবং স্বাভাবিক কার্যক্রমে
ব্রাউজারগুলিতে, যখন আপনি কোনও মডিউল বা ফাংশনের ভিতরে থাকেন না, তখন গ্লোবাল কনটেক্সট হল অবজেক্ট window, এবং সেখানে this সেই বস্তুর দিকে নির্দেশ করুনঅর্থাৎ, যদি আপনি কনসোলে নিম্নলিখিতটি টাইপ করেন:
console.log(this === window); // true en un entorno de navegador no estricto
"ক্লাসিক" উপায়ে (স্বাভাবিক ফাংশন) ঘোষিত একটি ফাংশনের মধ্যে, এর মান this এটা নির্ভর করে সেই ফাংশনটিকে কী বলা হয় তার উপর।যদি আপনি এটিকে পূর্ববর্তী বস্তু ছাড়াই আহ্বান করেন, অ-কঠোর মোডে this এটি সাধারণত বিশ্বব্যাপী, এবং স্পষ্টভাবে বলতে গেলে এটি হবে undefinedএই কারণেই কখনও কখনও, এক সাইট থেকে অন্য সাইটে কোড স্থানান্তর করার সময়, এটা আর তোমার প্রত্যাশা মতো নয়।.
এটি সাধারণ ফাংশনের সাথে সংজ্ঞায়িত অবজেক্ট পদ্ধতিতে
যখন আপনি ঐতিহ্যবাহী সিনট্যাক্স ব্যবহার করে একটি বস্তুর উপর একটি পদ্ধতি সংজ্ঞায়িত করেন, this পদ্ধতির মধ্যে, বস্তুর নিজেই রেফারেন্স যেখান থেকে সেই পদ্ধতিটি ব্যবহার করা হয়েছে।
উদাহরণস্বরূপ, যদি আপনার কাছে এরকম কিছু থাকে:
const obj = {
speak() {
console.log(this);
}
};
obj.speak();
কল obj.speak() তোলে this মধ্যে speak একজন হও objএটি এমন আচরণ যা মানুষ সাধারণত স্বজ্ঞাতভাবে আশা করে: পদ্ধতিটি বস্তুর "পক্ষে" কথা বলে।
যদি আপনি সংক্ষিপ্ত বাক্য গঠনের পরিবর্তে একটি ক্লাসিক ফাংশন ব্যবহার করেন, তাহলে প্রভাব একই হবে, কারণ মূল কথা হলো পদ্ধতিটি কীভাবে ব্যবহার করা হয় তার উপর।আপনি পদ্ধতির সংক্ষিপ্ত রূপ ব্যবহার করেছেন নাকি কীওয়ার্ড ব্যবহার করেছেন তাতে কিছু যায় আসে না function বস্তুর ভেতরে।
এটি তীর ফাংশন দিয়ে সংজ্ঞায়িত পদ্ধতিতে
যখন আপনি একটি তীর ফাংশন দিয়ে পদ্ধতিটি সংজ্ঞায়িত করেন তখন সবকিছু পরিবর্তিত হয়। এরকম কিছু:
const obj2 = {
speak: () => {
console.log(this);
}
};
obj2.speak();
এই ক্ষেত্রে, কার্যকর করার সময় obj2.speak() আপনি তা দেখতে পাবেন this এটা আর নেই obj2কিন্তু বাহ্যিক আভিধানিক প্রেক্ষাপট সেই বস্তুতে, যা একটি ক্লাসিক ব্রাউজার স্ক্রিপ্টে সাধারণত বিশ্বব্যাপী বস্তু হয় window.
প্রথমবার যখন তুমি এটি দেখো, তখনই এটা বিভ্রান্তিকর, কারণ তুমি আশা করো যে বস্তুর একটি পদ্ধতি বস্তুটিকেই নির্দেশ করবে। তবে, তীর ফাংশনগুলি তাদের নিজস্ব তৈরি করে না thisতারা উত্তরাধিকারসূত্রে এর মূল্য পায় this যদি সেই সুযোগটি বিশ্বব্যাপী হয়, তাহলে তারা বিশ্বব্যাপী সুযোগের উত্তরাধিকারী হবে; যদি এটি অন্য একটি সুযোগ হয়, তাহলে তারা সেই অন্য সুযোগটি উত্তরাধিকারী হবে।
অতএব, আধুনিক ডকুমেন্টেশনে প্রায়শই পুনরাবৃত্তি করা একটি সুপারিশ হল: অবজেক্ট মেথড হিসেবে তীর ফাংশন ব্যবহার করবেন না যখন তোমার প্রয়োজন হবে this সেই বস্তুর দিকে লক্ষ্য করো।
এর আভিধানিক পরিধি this তীর ফাংশন
সাধারণ ফাংশন এবং তীর ফাংশনের মধ্যে মূল পার্থক্য হল যে পরবর্তীটি এর জন্য একটি আভিধানিক লিঙ্ক আছে thisসহজভাবে বলতে গেলে: তারা তাদের সিদ্ধান্ত নেয় না this যখন তারা একে অপরকে ডাকে তখন নয়, কিন্তু যখন তারা সৃষ্টি.
এই উদাহরণটি কল্পনা করুন:
const obj3 = {
speak() {
(() => {
console.log(this);
})();
}
};
obj3.speak();
এখানে মনে হতে পারে যে, ভেতরে যেমন speak আমরা একটি তীর ফাংশন কার্যকর করি, এটি বিশ্বব্যাপী "রিসেট" করা উচিতকিন্তু ঠিক বিপরীতটি ঘটে: তীর ফাংশনটি ক্যাপচার করে this এর চারপাশে থাকা ফাংশনেরএই ক্ষেত্রে কোন পদ্ধতিটি speak হিসাবে আহ্বান করা হয়েছে obj3.speak()অতএব, এর মান this কনসোলে যেটি দেখানো হয়েছে তা হল obj3.
আমি বলতে চাচ্ছি, তীর ফাংশনগুলির নিজস্ব নেই thisবরং তাদের আশেপাশের পরিবেশ পুনঃব্যবহার করুনএটি নেস্টেড কলব্যাক, টাইমার, প্রতিশ্রুতি এবং অন্য যেকোনো জায়গায় অবিশ্বাস্যভাবে কার্যকর যেখানে, ক্লাসিক ফাংশনগুলির সাথে, আপনাকে কুস্তি করতে হয়েছিল .bind অথবা এর মতো কৌশল সহ const that = this;.
ক্ষতি এবং সংরক্ষণের ব্যবহারিক উদাহরণ this
জাভাস্ক্রিপ্টের একটি ক্লাসিক সমস্যা হল, যখন কোনও পদ্ধতির ভিতরে কোনও ফাংশন সংজ্ঞায়িত করা হয়, তুমি রেফারেন্স হারাবে this যে বস্তুর দিকে নির্দেশ করেছে এবং আপনি বিশ্বব্যাপী এক বা সঙ্গে শেষ undefined.
আসুন ব্যবহারের সাধারণ উদাহরণটি নেওয়া যাক setTimeout একটি ঐতিহ্যবাহী ফাংশন সহ একটি বস্তুর পদ্ধতির মধ্যে:
const persona = {
nombre: 'Agustin',
decirNombre: function() {
setTimeout(function() {
console.log(this.nombre);
}, 3000);
}
};
persona.decirNombre(); // Muestra undefined
এখানে এই ফাংশনের মধ্যে এটি পাস করা হয়েছে setTimeout এটা আর বস্তু নয় personaসেই কলব্যাক ফাংশনটি বিশ্বব্যাপী প্রেক্ষাপটে কার্যকর হয় (একটি ব্রাউজারে, window), তাই this.nombre এটি বিশ্বব্যাপী এমন একটি সম্পত্তি পড়ার চেষ্টা করে, যার অস্তিত্ব নেই, এবং শেষ পর্যন্ত এটি হয়ে যায় undefined.
তীর ফাংশন বিদ্যমান থাকার আগে, একটি সাধারণ সমাধান ছিল এর মান সংরক্ষণ করা this একটি সহায়ক চলকের মধ্যে ফাংশনে "টেনে আনা":
const persona = {
nombre: 'Agustin',
decirNombre: function() {
let that = this; // aquí this es persona
setTimeout(function() {
console.log(that.nombre);
}, 3000);
}
};
এই চলকের জন্য ধন্যবাদ, বস্তুর সঠিক রেফারেন্স বজায় রাখা হয়েছে। কিন্তু এটি কিছুটা কুৎসিত এবং পুনরাবৃত্তিমূলক কৌশল। তীর ফাংশনের সাহায্যে, এই সমস্যাটি অনেক সহজ করা হয়েছে:
const persona = {
nombre: 'Agustin',
decirNombre: function() {
setTimeout(() => {
console.log(this.nombre);
}, 3000);
}
};
এখানে তীর ফাংশনটি নিজস্ব তৈরি করে না thisতাই উত্তরাধিকারসূত্রে পায় this পদ্ধতির decirNombreবস্তুটি কোনটি? personaফলাফল: "আগাস্টিন" সঠিকভাবে প্রদর্শিত হয় মধ্যবর্তী ভেরিয়েবলের প্রয়োজন ছাড়াই অথবা .bind.
কল, প্রয়োগ এবং আবদ্ধ: এর মান নিয়ন্ত্রণ করা this
মেথড কলের মাধ্যমে প্রসঙ্গ সেট করার "প্রাকৃতিক" উপায় ছাড়াও, জাভাস্ক্রিপ্ট আমাদের এমন সরঞ্জাম দেয় যা এর মান জোর করে চাপিয়ে দিন this স্বাভাবিক কাজে: call, apply y bind.
পদ্ধতি call() y apply() তারা অবিলম্বে ফাংশনটি চালু করে, যা আপনাকে যে বস্তুটি ব্যবহার করতে চান তা পাস করার অনুমতি দেয় this। পার্থক্য এটি call একের পর এক যুক্তি গ্রহণ করে, যখন apply এগুলি একটি অ্যারেতে গৃহীত হয়। bind(), পরিবর্তে, এটি একটি নতুন ফাংশন প্রদান করে যার সাথে this আপনার নির্দেশিত মানের সাথে "সংযুক্ত"যাতে তুমি পরে যখন তোমার পছন্দ হবে তখন তাকে ফোন করতে পারো।
তবে, তীর ফাংশনের ক্ষেত্রে, এই পদ্ধতিগুলি পরিবর্তনের জন্য কার্যকর নয় this কারণ এর মান আভিধানিকভাবে সংযুক্ত। তুমি ব্যবহার করতে পার call, apply o bind আর্গুমেন্ট পাস করতে, কিন্তু তীর ফাংশনের প্রেক্ষাপট পরিবর্তন করতে নয়, যা নিয়মিত ফাংশনের সাথে একটি অত্যন্ত গুরুত্বপূর্ণ পার্থক্য।
তীর ফাংশনের মৌলিক বাক্য গঠন
আচরণের বাইরেও thisতীর ফাংশনগুলি একটি প্রদান করে আরও সংক্ষিপ্ত এবং অভিব্যক্তিপূর্ণ বাক্য গঠন অনেক পরিস্থিতিতে। সাধারণ রূপ হল:
(arg1, arg2, ..., argN) => expresion
এই ফর্মটি স্বয়ংক্রিয়ভাবে তীরের ডানদিকের রাশির ফলাফল ফেরত দেয়, তাই শব্দটি লেখার কোন প্রয়োজন নেই return যখন তোমার কাছে কেবল একটি সরল অভিব্যক্তি থাকে।
বাক্য গঠনের কিছু সাধারণ বিষয়:
- প্যারামিটার ছাড়া:
() => 42বা এমনকি এমনকি_ => 42যদি আপনি আর্গুমেন্টের নাম সম্পর্কে চিন্তা না করেন। - একটি মাত্র প্যারামিটার সহ:
বন্ধনী ঐচ্ছিক; আপনি লিখতে পারেনx => x * 2o(x) => x * 2. - একাধিক পরামিতি সহ:
বন্ধনী প্রয়োজন:(x, y) => x + y.
যখন আপনার একাধিক বিবৃতির প্রয়োজন হয়, আপনি ব্যবহার করতে পারেন ব্লক বডি চাবি সহ:
const sumar = (x, y) => {
const resultado = x + y;
return resultado;
};
এই ক্ষেত্রে, যেহেতু চাবি আছে, আর কোন অন্তর্নিহিত প্রত্যাবর্তন নেই; যদি তুমি না রাখো returnফাংশনটি ফিরে আসবে undefinedএটি তীর ফাংশন এবং ঐতিহ্যবাহী ফাংশন উভয়ের ক্ষেত্রেই প্রযোজ্য।
তীর ফাংশন সহ আক্ষরিক বস্তুগুলি ফেরত দিন
একটি ছোট কিন্তু খুব সাধারণ সিনট্যাকটিক বিশদ রয়েছে: যখন একটি তীর ফাংশন একটি প্রদান করে সরাসরি আক্ষরিক বস্তুআপনাকে এটি বন্ধনীর মধ্যে আবদ্ধ করতে হবে যাতে দোভাষী এটিকে একটি ব্লক ভেবে ভুল না করে।
উদাহরণস্বরূপ:
x => ({ y: x })
এই বন্ধনীগুলো ছাড়া, জাভাস্ক্রিপ্ট কোঁকড়া বন্ধনীগুলিকে ফাংশন বডির শুরু হিসেবে ব্যাখ্যা করত, বস্তু হিসেবে নয়। এটি একটি সহজ কৌশল, কিন্তু এটি ভুলে গেলে অনেক বোকা ভুলের কারণ হয়ে দাঁড়ায়।
তীর ফাংশন: বেনামী এবং প্রোটোটাইপ ছাড়াই
তীর ফাংশন হল বাক্য গঠনগতভাবে বেনামীতাদের সঠিক নাম নেই, যা জিনিসগুলিকে কিছুটা জটিল করে তুলতে পারে। ডিবাগ এবং ত্রুটি বার্তাকারণ ট্রেসে আপনি ফাংশন আইডেন্টিফায়ারটি সরাসরি দেখতে পাবেন না, যদি না আপনি এটিকে একটি স্বীকৃত নাম সহ একটি ধ্রুবকের সাথে বরাদ্দ করেন।
অতিরিক্তভাবে, তীরটি ফাংশন করে তাদের কোন সম্পত্তি নেই prototype এবং এগুলি নির্মাণ কোম্পানি হিসেবে ব্যবহার করা যাবে নাযদি তুমি তাদের ডেকে আনার চেষ্টা করো newআপনি একটি ত্রুটি পাবেন। কনস্ট্রাক্টর বা ক্লাস ব্যবহার করে অবজেক্ট তৈরি করতে, আপনাকে এখনও সাধারণ ফাংশন বা সিনট্যাক্স ব্যবহার করতে হবে। class.
আরেকটি পরিণতি হল যে অভ্যন্তরীণ স্ব-রেফারেন্সিং প্রয়োজন এমন প্যাটার্নের জন্য এগুলি উপযুক্ত নয়।, যেমন কিছু ধরণের পুনরাবৃত্তি বা ইভেন্ট হ্যান্ডলার যাদের ব্যবহার করে নিজেদের সদস্যতা ত্যাগ করতে হবে this অথবা ফাংশনের নিজস্ব নাম।
যেখানে তীর ফাংশনগুলি জ্বলজ্বল করে
তীর ফাংশনের দুর্দান্ত শক্তি হল তাদের এর আভিধানিক সংযোগ thisএগুলি সেই পরিস্থিতিতে আদর্শ যেখানে আপনি কলব্যাকটি অন্য ফাংশনে পাস করতে চান যাতে এটি বজায় থাকে this আশেপাশের এলাকার।
উদাহরণস্বরূপ, এমন একটি বস্তুতে যেখানে এমন একটি পদ্ধতি রয়েছে যা একটি টাইমার শুরু করে এবং অ্যাক্সেস চালিয়ে যেতে হয় ব্যবহার করে বস্তুর নিজস্ব বৈশিষ্ট্য this:
const contador = {
id: 42,
iniciar() {
setTimeout(() => {
console.log(this.id); // this es contador
}, 1000);
}
};
ES5 তে এটি রাখা সাধারণ ছিল .bind(this) কলব্যাকে অথবা সংরক্ষণ করুন this অন্য একটি ভেরিয়েবলে। তীর ফাংশন সহ, কোডটি আরও পরিষ্কার এবং আসল উদ্দেশ্যের কাছাকাছি হয়ে ওঠে।.
এগুলি অ্যারে পদ্ধতির ক্ষেত্রেও খুবই ব্যবহারিক, যেমন map, filter, reduce এবং কোম্পানি, কারণ সিনট্যাকটিক শব্দ কমানো যখন ফাংশন লজিক সংক্ষিপ্ত হয়:
const numeros = [1, 2, 3];
const dobles = numeros.map(n => n * 2);
অল্প পরিমাণে ব্যবহার করলে, এই কম্প্যাক্ট আকারগুলি এক নজরে ডেটা প্রবাহ অনুসরণ করা সহজ করে তোলে।
তীর ফাংশন কখন এড়িয়ে চলতে হবে
যদিও তীর ফাংশনগুলি খুবই কার্যকর, তবে এগুলি নিয়মিত ফাংশনের প্রতিস্থাপন নয়। বেশ কয়েকটি স্পষ্ট উদাহরণ রয়েছে যেখানে এগুলো ব্যবহার না করাই ভালো।:
- বস্তু পদ্ধতি যা নির্ভর করে
this:
যদি আপনি একটি পদ্ধতিকে এভাবে সংজ্ঞায়িত করেনsaltos: () => { this.vidas--; }একটি বস্তুর ভিতরেgato,thisএটি বিড়ালের দিকে ইঙ্গিত করবে না, বরং বাইরের পরিবেশের দিকে ইঙ্গিত করবে, এবং সম্পত্তিটি আপনার প্রত্যাশা অনুযায়ী আপডেট হবে না। - DOM ইভেন্ট কলব্যাক যার জন্য একটি প্রয়োজন
thisপ্রগতিশীল:
একটি হ্যান্ডলারে যেমনboton.addEventListener('click', () => { this.classList.toggle('on'); });,thisবোতাম টিপলে হবে না, বরং উচ্চতর প্রেক্ষাপটে, সম্ভবত আপনাকে একটি টাইপ ত্রুটি দেবে। - নির্মাতা বা ফাংশন যা প্রয়োজন
prototype:
যেহেতু এটি ব্যবহার করা যাবে নাnewতীর ফাংশনগুলি ইনস্ট্যান্স তৈরি বা প্রোটোটাইপ-ভিত্তিক প্যাটার্নের জন্য উপযুক্ত নয়।
এই সমস্ত ক্ষেত্রে, একটি স্বাভাবিক কার্যকারিতাই উপযুক্ত হাতিয়ার হিসেবে রয়ে গেছে কারণ এটি অনুমতি দেয় যে this এটি ফাংশনটি কীভাবে ব্যবহার করা হয় তার সাথে গতিশীলভাবে সংযুক্ত।
যদি তুমি সচেতনভাবে স্বাভাবিক ফাংশন এবং তীর ফাংশনের মধ্যে কোনটি বেছে নিতে অভ্যস্ত হও, যা তোমার প্রয়োজনের উপর নির্ভর করে, this এবং প্রেক্ষাপট থেকে, আপনার কোডটি আরও অনুমানযোগ্য এবং পঠনযোগ্য হবে। যে কেউ পরে এটি রাখে তার জন্য।
পরিশেষে, এর মূল্য কীভাবে তা বোঝা this জাভাস্ক্রিপ্টে, এবং তীর ফাংশন কীভাবে সেই মানটি উত্তরাধিকার সূত্রে পায় অপ্রত্যাশিত ফলাফলের সাথে লড়াই বন্ধ করার, ES6 এর সিনট্যাকটিক সুগার এবং লেখার পদ্ধতি, কলব্যাক এবং ইভেন্ট হ্যান্ডলারগুলি ব্যবহার করার মূল চাবিকাঠি যা আপনার মনে ঠিক যা ছিল তা করে, তা হল লেক্সিকাল স্কোপটি বোঝা যেখানে সেগুলি তৈরি করা হয়েছে।