ফাংশন কল
ফাংশনগুলি কেবল এক ধরণের অবজেক্ট।
সমস্ত ফাংশন অবজেক্টের কল এবং প্রয়োগ পদ্ধতি রয়েছে যা তাদের ডাকা হয় এমন ফাংশন অবজেক্টটি কার্যকর করে।
যখন ডাকা হয়, এই পদ্ধতির প্রথম যুক্তিটি this
সেই ফাংশনটি নির্দিষ্ট করে যা ফাংশন সম্পাদনের সময় কীওয়ার্ড দ্বারা রেফারেন্স করা হবে - যদি এটি null
বা undefined
, বিশ্বব্যাপী অবজেক্ট window
, এর জন্য ব্যবহৃত হয় this
।
সুতরাং, একটি ফাংশন কল ...
whereAmI = "window";
function foo()
{
return "this is " + this.whereAmI + " with " + arguments.length + " + arguments";
}
... প্রথম বন্ধনী দিয়ে - foo()
- সমতূল্য foo.call(undefined)
বা foo.apply(undefined)
যা, কার্যকরভাবে হিসাবে একই foo.call(window)
বা foo.apply(window)
।
>>> foo()
"this is window with 0 arguments"
>>> foo.call()
"this is window with 0 arguments"
অতিরিক্ত আর্গুমেন্টটি call
ফাংশন কলের আর্গুমেন্ট হিসাবে পাস করা হবে, যেখানে একটি অতিরিক্ত অতিরিক্ত আর্গুমেন্ট apply
অ্যারের মতো অবজেক্ট হিসাবে ফাংশন কলের জন্য আর্গুমেন্টগুলি নির্দিষ্ট করতে পারে।
সুতরাং, foo(1, 2, 3)
সমতুল্য foo.call(null, 1, 2, 3)
বা foo.apply(null, [1, 2, 3])
।
>>> foo(1, 2, 3)
"this is window with 3 arguments"
>>> foo.apply(null, [1, 2, 3])
"this is window with 3 arguments"
যদি কোনও ফাংশন কোনও অবজেক্টের সম্পত্তি ...
var obj =
{
whereAmI: "obj",
foo: foo
};
... অবজেক্টের মাধ্যমে ফাংশনে একটি রেফারেন্স অ্যাক্সেস করা এবং এটিকে প্রথম বন্ধনীর সাথে কল করা - obj.foo()
- এর সমতুল্য foo.call(obj)
বা হয় foo.apply(obj)
।
যাইহোক, অবজেক্টের বৈশিষ্ট্য হিসাবে অনুষ্ঠিত ফাংশনগুলি সেই বস্তুর "আবদ্ধ" নয়। আপনি obj
উপরের সংজ্ঞাটিতে দেখতে পাচ্ছেন যেহেতু ফাংশনগুলি কেবলমাত্র এক ধরণের অবজেক্ট তাই সেগুলি উল্লেখ করা যেতে পারে (এবং এভাবে কোনও ফাংশন কলের রেফারেন্স দিয়ে পাস করা যায় বা কোনও ফাংশন কল থেকে রেফারেন্স দিয়ে ফিরে আসতে পারে)। যখন কোনও ফাংশনের রেফারেন্সটি পাস করা হয়, এটি কোথা থেকে পাস করা হয়েছিল সে সম্পর্কে কোনও অতিরিক্ত তথ্য এটি বহন করে না, যার কারণে নিম্নলিখিতটি ঘটে:
>>> baz = obj.foo;
>>> baz();
"this is window with 0 arguments"
আমাদের ফাংশন রেফারেন্সের baz
কল, কলটির জন্য কোনও প্রসঙ্গ সরবরাহ করে না, সুতরাং এটি কার্যকরভাবে একইরকম baz.call(undefined)
, তাই this
রেফারেন্সিং শেষ হয় window
। আমরা যদি baz
এটি জানতে চাই যে এটির মালিকানাধীন obj
, আমাদের যখন baz
আহ্বান করা হয় তখন কোনওভাবে সেই তথ্য সরবরাহ করা দরকার , এটিই যেখানে প্রথম যুক্তিটি call
বা apply
ক্লোজারগুলি কার্যকর হয়।
ব্যাপ্ত শৃঙ্খলা
function bind(func, context)
{
return function()
{
func.apply(context, arguments);
};
}
যখন কোনও ফাংশন কার্যকর করা হয়, এটি একটি নতুন সুযোগ তৈরি করে এবং কোনও সংযুক্তি সুযোগের একটি রেফারেন্স থাকে। উপরোক্ত উদাহরণে যখন বেনামী ফাংশন তৈরি করা হয়, তখন এটির যে সুযোগটি তৈরি হয়েছিল তার একটি রেফারেন্স থাকে যা bind
এর স্কোপ। এটি একটি "বন্ধ" হিসাবে পরিচিত।
[global scope (window)] - whereAmI, foo, obj, baz
|
[bind scope] - func, context
|
[anonymous scope]
আপনি যখন কোনও ভেরিয়েবলটি অ্যাক্সেস করার চেষ্টা করেন তখন এই "স্কোপ চেইন" প্রদত্ত নামের সাথে একটি ভেরিয়েবল সন্ধান করতে হাঁটতে পারে - যদি বর্তমান স্কোপটিতে ভেরিয়েবলটি না থাকে তবে আপনি শৃঙ্খলে পরবর্তী স্থানটি দেখুন এবং আপনি যতক্ষণ না পৌঁছাবেন ততক্ষণ বৈশ্বিক সুযোগ। বেনামে ফাংশনটি যখন ফিরে আসে এবং bind
সম্পাদন শেষ করে, বেনামে ফাংশনটির এখনও তার bind
স্কোপের একটি উল্লেখ থাকে , সুতরাং bind
এর সুযোগ "দূরে যায় না"।
উপরের সমস্তটি প্রদত্ত আপনি এখন বুঝতে সক্ষম হবেন যে নিম্নোক্ত উদাহরণে স্কোপ কীভাবে কাজ করে এবং যখন একটি নির্দিষ্ট মান সহ "প্রাক-সীমাবদ্ধ" এর কাছাকাছি কোনও ক্রিয়াকলাপটি পাস করার কৌশলটি কেন কাজ this
করবে তখন:
>>> baz = bind(obj.foo, obj);
>>> baz(1, 2);
"this is obj with 2 arguments"
var signup = { onLoadHandler:function(){ console.log(this); return Type.createDelegate(this,this._onLoad); }, _onLoad: function (s, a) { console.log("this",this); }};