আমি ইদানীং প্রচুর জাভাস্ক্রিপ্ট পড়ছি এবং আমি লক্ষ্য করে দেখছি যে পুরো ফাইলটি আমদানির জন্য .js ফাইলগুলিতে নীচের মত মোড়ানো আছে।
(function() {
...
code
...
})();
কন্সট্রাক্টর ফাংশনগুলির একটি সহজ সেটের চেয়ে এটি করার কারণ কী?
আমি ইদানীং প্রচুর জাভাস্ক্রিপ্ট পড়ছি এবং আমি লক্ষ্য করে দেখছি যে পুরো ফাইলটি আমদানির জন্য .js ফাইলগুলিতে নীচের মত মোড়ানো আছে।
(function() {
...
code
...
})();
কন্সট্রাক্টর ফাংশনগুলির একটি সহজ সেটের চেয়ে এটি করার কারণ কী?
উত্তর:
এটি সাধারণত নেমস্পেস (পরে দেখুন) এবং সদস্য ফাংশন এবং / অথবা ভেরিয়েবলের দৃশ্যমানতা নিয়ন্ত্রণ করে। এটি একটি বস্তুর সংজ্ঞা মত ভাবেন। এর প্রযুক্তিগত নামটি অবিলম্বে আমন্ত্রিত ফাংশন এক্সপ্রেশন (আইআইএফই)। jQuery প্লাগইন সাধারণত এইভাবে লেখা হয়।
জাভাস্ক্রিপ্টে, আপনি বাসা ফাংশন করতে পারেন। সুতরাং, নিম্নলিখিতটি আইনী:
function outerFunction() {
function innerFunction() {
// code
}
}
এখন আপনি কল করতে পারেন outerFunction()
, তবে এর দৃশ্যমানতা innerFunction()
সীমার মধ্যে সীমাবদ্ধ outerFunction()
, যার অর্থ এটি ব্যক্তিগত outerFunction()
। এটি মূলত জাভাস্ক্রিপ্টে ভেরিয়েবলগুলির মতো একই নীতি অনুসরণ করে:
var globalVariable;
function someFunction() {
var localVariable;
}
সঙ্গতিপূর্ণভাবেই:
function globalFunction() {
var localFunction1 = function() {
//I'm anonymous! But localFunction1 is a reference to me!
};
function localFunction2() {
//I'm named!
}
}
উপরের দৃশ্যে, আপনি globalFunction()
যে কোনও জায়গা থেকে কল করতে পারেন , তবে আপনি কল করতে পারবেন না localFunction1
বা করতে পারবেন না localFunction2
।
আপনি যখন লিখছেন তখন আপনি কী করছেন (function() { ... })()
, আপনি প্রথম বন্ধনের প্রথম সেটটির অভ্যন্তরে কোডটি একটি ফাংশন আক্ষরিক (যা পুরো "অবজেক্ট" বলতে আসলে আসলে একটি ফাংশন) তৈরি করছেন। এর পরে, আপনি ()
সুনির্দিষ্টভাবে সংজ্ঞায়িত ফাংশনটি (চূড়ান্ত ) স্ব-আমন্ত্রণ করছেন । আমি এর আগে যেমন উল্লেখ করেছি এর বড় সুবিধাটি হ'ল আপনার ব্যক্তিগত পদ্ধতি / ফাংশন এবং বৈশিষ্ট্য থাকতে পারে:
(function() {
var private_var;
function private_function() {
//code
}
})();
প্রথম উদাহরণে, আপনি globalFunction
এটি চালানোর জন্য স্পষ্টতই নাম দ্বারা প্রার্থনা করবেন । এটি হ'ল, আপনি globalFunction()
এটি চালানোর জন্য কি করবেন। তবে উপরের উদাহরণে আপনি কেবল একটি ফাংশন সংজ্ঞায়িত করছেন না; আপনি একসাথে এটি সংজ্ঞায়িত করছেন এবং আহবান করছেন । এর অর্থ হ'ল যখন আপনার জাভাস্ক্রিপ্ট ফাইলটি লোড হবে, এটি তাত্ক্ষণিকভাবে কার্যকর করা হবে। অবশ্যই, আপনি করতে পারেন:
function globalFunction() {
// code
}
globalFunction();
আচরণটি একটি উল্লেখযোগ্য পার্থক্য বাদে মূলত একই রকম হবে: আপনি যখন আইআইএফই ব্যবহার করেন আপনি বিশ্বব্যাপী সুযোগকে দূষিত করা এড়ান (ফলস্বরূপ এর অর্থ এইও হয় যে আপনি নামটি না পেয়ে একাধিকবার ফাংশনটি চালাতে পারবেন না, তবে যেহেতু এই ফাংশনটি কেবল একবার বাস্তবায়িত হওয়ার জন্য বোঝানো হয় এটি আসলে কোনও সমস্যা নয়)।
আইআইএফইগুলির সাথে ঝরঝরে জিনিসটি হ'ল আপনি অভ্যন্তরীণ জিনিসগুলি সংজ্ঞায়িত করতে এবং বাইরের বিশ্বের যে অংশগুলি চান তা কেবল প্রকাশ করতে পারেন (নাম স্পেসিংয়ের উদাহরণ যাতে আপনি মূলত নিজের লাইব্রেরি / প্লাগইন তৈরি করতে পারেন):
var myPlugin = (function() {
var private_var;
function private_function() {
}
return {
public_function1: function() {
},
public_function2: function() {
}
}
})()
এখন আপনি কল করতে পারেন myPlugin.public_function1()
, কিন্তু আপনি অ্যাক্সেস করতে পারবেন না private_function()
! ক্লাস সংজ্ঞা মত সুন্দর। এটি আরও ভালভাবে বুঝতে, আমি আরও কিছু পড়ার জন্য নীচের লিঙ্কগুলির সুপারিশ করছি:
সম্পাদনা
আমি উল্লেখ করতে ভুলে গেছি. এই ফাইনালে ()
, আপনি ভিতরে যা চান তা পাস করতে পারেন। উদাহরণস্বরূপ, আপনি jQuery প্লাগইনগুলি তৈরি করার সময় আপনি এতে পাস jQuery
বা $
পছন্দ করেন:
(function(jQ) { ... code ... })(jQuery)
সুতরাং আপনি এখানে যা করছেন তা একটি ফাংশন সংজ্ঞায়িত করছে যা একটি প্যারামিটারে লাগে (যাকে বলা হয় jQ
, স্থানীয় ভেরিয়েবল, এবং কেবলমাত্র সেই ফাংশনে পরিচিত )। তারপর তুমি আত্ম-invoking ফাংশন এবং একটি প্যারামিটার কথা প্রসঙ্গে (নামেও jQuery
কিন্তু এই এক বহির্বিশ্বের এবং প্রকৃত jQuery এর নিজেই একটি রেফারেন্স থেকে)। এটি করার জন্য কোনও চাপ দেওয়ার দরকার নেই তবে কয়েকটি সুবিধা রয়েছে:
এর আগে আমি বর্ণনা দিয়েছিলাম যে কীভাবে এই ফাংশনগুলি শুরুতে স্বয়ংক্রিয়ভাবে সঞ্চালিত হয়, তবে তারা যদি স্বয়ংক্রিয়ভাবে চালিত হয় তবে কে আর্গুমেন্টগুলিতে পার করছে? এই কৌশলটি ধরে নিয়েছে যে আপনার প্রয়োজনীয় সমস্ত প্যারামিটারগুলি ইতিমধ্যে গ্লোবাল ভেরিয়েবল হিসাবে সংজ্ঞায়িত হয়েছে। সুতরাং jQuery যদি ইতিমধ্যে বিশ্বব্যাপী ভেরিয়েবল হিসাবে সংজ্ঞায়িত না হয় তবে এই উদাহরণটি কাজ করবে না। আপনারা যেমন অনুমান করতে পারেন, jquery.js এর সূচনা করার সময় একটি জিনিস 'jQuery' গ্লোবাল ভেরিয়েবল সংজ্ঞায়িত করা হয়, তেমনি এর আরও বিখ্যাত '$' গ্লোবাল ভেরিয়েবলও সংজ্ঞায়িত করা হয়েছে, যা এই কোডটি jQuery অন্তর্ভুক্ত করার পরে কাজ করতে দেয়।
;(function(jQ) { ... code ... })(jQuery);
এইভাবে কেউ যদি তাদের স্ক্রিপ্টে একটি সেমিকোলন ফেলে রাখে তবে এটি আপনার ভাঙবে না, বিশেষত যদি আপনি অন্যের সাথে আপনার স্ক্রিপ্টকে ছোট করে দেখানোর পরিকল্পনা করেন।
(function (context) { ..... })(this)
যা আপনার পছন্দসই বিষয়টিকে প্রাসঙ্গিক প্রসঙ্গের সাথে এভাবে প্রকাশ করার অনুমতি দেয়।
এর সহজতম ফর্মটিতে, এই কৌশলটির লক্ষ্য কোনও ফাংশন স্কোপের ভিতরে কোড মোড়ানো ।
এটি এর সম্ভাবনা হ্রাস করতে সহায়তা করে:
এটা তোলে নেই সনাক্ত করে কখন ডকুমেন্ট প্রস্তুত - এটি কোন ধরণের নয় document.onload
কিংবাwindow.onload
এটি সাধারণত একটি Immediately Invoked Function Expression (IIFE)
বা হিসাবে পরিচিত Self Executing Anonymous Function
।
var someFunction = function(){ console.log('wagwan!'); };
(function() { /* function scope starts here */
console.log('start of IIFE');
var myNumber = 4; /* number variable declaration */
var myFunction = function(){ /* function variable declaration */
console.log('formidable!');
};
var myObject = { /* object variable declaration */
anotherNumber : 1001,
anotherFunc : function(){ console.log('formidable!'); }
};
console.log('end of IIFE');
})(); /* function scope ends */
someFunction(); // reachable, hence works: see in the console
myFunction(); // unreachable, will throw an error, see in the console
myObject.anotherFunc(); // unreachable, will throw an error, see in the console
উপরের উদাহরণে, ফাংশনে সংজ্ঞায়িত যেকোন পরিবর্তনীয় (অর্থাত্ ঘোষিত হিসাবে ঘোষণা করা হয়েছে var
) "ব্যক্তিগত" হবে এবং কেবলমাত্র ফাংশন স্কোপের মধ্যে অ্যাক্সেসযোগ্য (ভিভিন পালিথ এটি রেখেছেন)। অন্য কথায়, এই পরিবর্তনগুলি ফাংশনের বাইরে দৃশ্যমান / পৌঁছনীয় নয়। লাইভ ডেমো দেখুন ।
জাভাস্ক্রিপ্টের ফাংশন স্কোপিং রয়েছে। "একটি ফাংশনে সংজ্ঞায়িত প্যারামিটার এবং ভেরিয়েবলগুলি ফাংশনের বাইরে দৃশ্যমান হয় না এবং ফাংশনের মধ্যে যে কোনও জায়গায় সংজ্ঞায়িত একটি ভেরিয়েবল ফাংশনের অভ্যন্তরে সর্বত্র দৃশ্যমান হয়। ("জাভাস্ক্রিপ্ট: দ্য গুড পার্টস" থেকে)।
শেষ পর্যন্ত, পূর্বে পোস্ট করা কোডটি নীচের মতও করা যেতে পারে:
var someFunction = function(){ console.log('wagwan!'); };
var myMainFunction = function() {
console.log('start of IIFE');
var myNumber = 4;
var myFunction = function(){ console.log('formidable!'); };
var myObject = {
anotherNumber : 1001,
anotherFunc : function(){ console.log('formidable!'); }
};
console.log('end of IIFE');
};
myMainFunction(); // I CALL "myMainFunction" FUNCTION HERE
someFunction(); // reachable, hence works: see in the console
myFunction(); // unreachable, will throw an error, see in the console
myObject.anotherFunc(); // unreachable, will throw an error, see in the console
একদিন, সম্ভবত কেউ ভেবেছিলেন "'মাইমেন ফাংশন' নামকরণ এড়াতে অবশ্যই একটি উপায় থাকতে হবে, যেহেতু আমরা যা চাই তা তা অবিলম্বে সম্পাদন করা" "
আপনি যদি বেসিকগুলিতে ফিরে যান তবে আপনি এটি সন্ধান করতে পারেন:
expression
: একটি মান মূল্যায়ন কিছু। অর্থাত3+11/x
statement
: কোডের লাইন (গুলি) কিছু করছে তবে এটি কোনও মানকে মূল্যায়ন করে না । অর্থাতif(){}
একইভাবে, ফাংশন এক্সপ্রেশনগুলি একটি মানকে মূল্যায়ন করে। এবং এর একটি পরিণতি (আমি ধরে নিই?) হ'ল এগুলি তাত্ক্ষণিকভাবে আহ্বান করা যেতে পারে:
var italianSayinSomething = function(){ console.log('mamamia!'); }();
সুতরাং আমাদের আরও জটিল উদাহরণ হয়ে ওঠে:
var someFunction = function(){ console.log('wagwan!'); };
var myMainFunction = function() {
console.log('start of IIFE');
var myNumber = 4;
var myFunction = function(){ console.log('formidable!'); };
var myObject = {
anotherNumber : 1001,
anotherFunc : function(){ console.log('formidable!'); }
};
console.log('end of IIFE');
}();
someFunction(); // reachable, hence works: see in the console
myFunction(); // unreachable, will throw an error, see in the console
myObject.anotherFunc(); // unreachable, will throw an error, see in the console
পরবর্তী পদক্ষেপটি " var myMainFunction =
আমরা যদি এটি ব্যবহার না করি তবে কেন হবে !?" চিন্তাভাবনা ।
উত্তরটি সহজ: এটিকে সরিয়ে দেওয়ার চেষ্টা করুন, যেমন নীচে:
function(){ console.log('mamamia!'); }();
এটি কাজ করবে না কারণ "ফাংশন ঘোষণাগুলি চলনযোগ্য নয়" ।
কৌশলটি হ'ল অপসারণের মাধ্যমে var myMainFunction =
আমরা ফাংশন প্রকাশকে একটি ফাংশন ঘোষণায় রূপান্তরিত করি । এ সম্পর্কিত আরও তথ্যের জন্য "সংস্থানসমূহ" এ লিঙ্কগুলি দেখুন।
পরবর্তী প্রশ্নটি হ'ল "কেন আমি এটিকে ব্যতীত অন্য কিছু দিয়ে ফাংশন এক্সপ্রেশন হিসাবে রাখতে পারি না var myMainFunction =
?
উত্তরটি "আপনি পারেন", এবং আসলে আপনি এটি করতে পারেন এমন অনেকগুলি উপায় রয়েছে: একটি +
, ক !
, ক -
, বা সম্ভবত একটি জোড়া বন্ধনে আবৃত করা (এটি এখন কনভেনশন দ্বারা সম্পন্ন হয়েছে) এবং আরও আমি বিশ্বাস করি। উদাহরণ স্বরূপ:
(function(){ console.log('mamamia!'); })(); // live demo: jsbin.com/zokuwodoco/1/edit?js,console.
অথবা
+function(){ console.log('mamamia!'); }(); // live demo: jsbin.com/wuwipiyazi/1/edit?js,console
অথবা
-function(){ console.log('mamamia!'); }(); // live demo: jsbin.com/wejupaheva/1/edit?js,console
সুতরাং একবার আমাদের "বিকল্প কোড" যা ছিল তার সাথে প্রাসঙ্গিক সংশোধনটি যুক্ত করা হলে আমরা "কোড বর্ণিত" উদাহরণে ব্যবহৃত ঠিক একই কোডটিতে ফিরে আসি
var someFunction = function(){ console.log('wagwan!'); };
(function() {
console.log('start of IIFE');
var myNumber = 4;
var myFunction = function(){ console.log('formidable!'); };
var myObject = {
anotherNumber : 1001,
anotherFunc : function(){ console.log('formidable!'); }
};
console.log('end of IIFE');
})();
someFunction(); // reachable, hence works: see in the console
myFunction(); // unreachable, will throw an error, see in the console
myObject.anotherFunc(); // unreachable, will throw an error, see in the console
সম্পর্কে আরও পড়ুন Expressions vs Statements
:
একটি বিষয় যেটি ভাবতে পারে তা হ'ল "আপনি যখন ফাংশনের অভ্যন্তরে ভেরিয়েবলটি 'সঠিকভাবে' সংজ্ঞায়িত না করেন - তখন কি তার পরিবর্তে কোনও সাধারণ অ্যাসাইনমেন্ট করবেন?"
(function() {
var myNumber = 4; /* number variable declaration */
var myFunction = function(){ /* function variable declaration */
console.log('formidable!');
};
var myObject = { /* object variable declaration */
anotherNumber : 1001,
anotherFunc : function(){ console.log('formidable!'); }
};
myOtherFunction = function(){ /* oops, an assignment instead of a declaration */
console.log('haha. got ya!');
};
})();
myOtherFunction(); // reachable, hence works: see in the console
window.myOtherFunction(); // works in the browser, myOtherFunction is then in the global scope
myFunction(); // unreachable, will throw an error, see in the console
মূলত, যদি কোনও চলক যা তার বর্তমান স্কোপ হিসাবে ঘোষিত হয়নি, যদি একটি মান নির্ধারিত হয়, তবে "স্ক্র্যাপ চেইনটি ততক্ষণ দেখা যায় যতক্ষণ না এটি ভেরিয়েবলটি সন্ধান করে বা বিশ্বব্যাপী সুযোগকে আঘাত করে না (এমন সময়ে এটি এটি তৈরি করবে)"।
যখন কোনও ব্রাউজার পরিবেশে (বনাম একটি সার্ভার পরিবেশ যেমন নোডেজের মতো) থাকে তখন বিশ্বব্যাপী সুযোগটি window
বস্তু দ্বারা সংজ্ঞায়িত হয় । তাই আমরা করতে পারি window.myOtherFunction()
।
এই বিষয়টিতে আমার "ভাল অভ্যাস" টিপটি হ'ল যে কোনও কিছু সংজ্ঞায়িত করার সময় সর্বদা ব্যবহার করাvar
: এটি কোনও সংখ্যা, বস্তু বা ফাংশন এবং এমনকি বিশ্বব্যাপী সুযোগে থাকা সত্ত্বেও। এটি কোডটিকে অনেক সহজ করে তোলে।
বিঃদ্রঃ:
block scope
(: ব্লক সুযোগ স্থানীয় ভেরিয়েবল যোগ আপডেট ES6 ।)function scope
& global scope
( window
ব্রাউজার পরিবেশে সুযোগ) রয়েছেসম্পর্কে আরও পড়ুন Javascript Scopes
:
আপনি যখন এই IIFE
ধারণাটি পেয়ে যান , তখন এটির দিকে পরিচালিত হয় module pattern
যা সাধারণত এই আইআইএফই প্যাটার্নটি কাজে লাগিয়ে করা হয়। আনন্দ কর :)
একটি ব্রাউজারে জাভাস্ক্রিপ্টে কেবলমাত্র বেশ কয়েকটি কার্যকর স্কোপ রয়েছে: ফাংশন স্কোপ এবং বৈশ্বিক সুযোগ।
যদি কোনও ভেরিয়েবল ফাংশন স্কোপে না থাকে তবে এটি বিশ্বব্যাপী সুযোগে। এবং গ্লোবাল ভেরিয়েবলগুলি সাধারণত খারাপ হয়, সুতরাং এটি একটি লাইব্রেরির ভেরিয়েবলগুলি নিজের কাছে রাখার জন্য একটি নির্মাণ।
এটাকে ক্লোজার বলা হয়। এটি মূলত ফাংশনের অভ্যন্তরে কোডটি সিল করে যাতে অন্যান্য গ্রন্থাগারগুলি এতে হস্তক্ষেপ না করে। এটি সংকলিত ভাষাগুলিতে একটি নেমস্পেস তৈরির অনুরূপ।
উদাহরণ। ধরুন আমি লিখি:
(function() {
var x = 2;
// do stuff with x
})();
এখন অন্য লাইব্রেরিগুলি x
আমার লাইব্রেরিতে ব্যবহারের জন্য তৈরি করা চলকটি অ্যাক্সেস করতে পারে না ।
(function(){ ... return { publicProp1: 'blah' }; })();
। অবশ্যই স্পষ্টতই নেমস্পেসিংয়ের সমান্তরাল নয়, তবে এটি সেভাবে ভাবতে সহায়তা করতে পারে।
এইচটিএমএল 5 কিছু বস্তুর ব্রাউজার সমর্থন নির্ধারণের এই পদ্ধতি হিসাবে আপনি বৃহত্তর এক্সপ্রেশনগুলিতে ডেটা হিসাবে ফাংশন ক্লোজারগুলি ব্যবহার করতে পারেন ।
navigator.html5={
canvas: (function(){
var dc= document.createElement('canvas');
if(!dc.getContext) return 0;
var c= dc.getContext('2d');
return typeof c.fillText== 'function'? 2: 1;
})(),
localStorage: (function(){
return !!window.localStorage;
})(),
webworkers: (function(){
return !!window.Worker;
})(),
offline: (function(){
return !!window.applicationCache;
})()
}
ভেরিয়েবল স্থানীয় রাখার পাশাপাশি গ্লোবাল ভেরিয়েবল ব্যবহার করে একটি লাইব্রেরি লেখার সময় খুব সহজে ব্যবহার করা হয়, আপনি এটি লাইব্রেরির মধ্যে ব্যবহারের জন্য একটি সংক্ষিপ্ত পরিবর্তনশীল নাম দিতে পারেন। এটি প্রায়শই jQuery প্লাগইন লেখার ক্ষেত্রে ব্যবহার করা হয়, যেহেতু jQuery আপনাকে jQuery.noConflict () ব্যবহার করে jQuery- এর $ পরিবর্তনশীল পয়েন্টিংটি অক্ষম করতে দেয়। যদি এটি অক্ষম থাকে তবে আপনার কোডটি এখনও ব্যবহার করতে পারে $ এবং যদি আপনি কেবল এটি করেন তবে তা ভাঙ্গতে পারে না:
(function($) { ...code...})(jQuery);
কোডটি "কঠোর মোডে" কার্যকর করা উচিত তা নিশ্চিত করার জন্য আমাদের স্কোপ ফাংশনে 'ব্যবহার কঠোর' ব্যবহার করা উচিত। নমুনা কোড নীচে দেখানো হয়েছে
(function() {
'use strict';
//Your code from here
})();