কল এবং প্রয়োগের মধ্যে পার্থক্য কী?


3101

একটি ফাংশন ব্যবহার callএবং applyপ্রার্থনা মধ্যে পার্থক্য কি ?

var func = function() {
  alert('hello!');
};

func.apply(); বনাম func.call();

পূর্বোক্ত দুটি পদ্ধতির মধ্যে পারফরম্যান্সের পার্থক্য রয়েছে কি? callওভার applyএবং বিপরীতে ব্যবহার করা ভাল কখন ?


726
aআরোগুলির অ্যারের জন্য এবং cকলের কলামগুলির জন্য কল করার জন্য আবেদন করার কথা ভাবুন ।
ল্যারি ব্যাটাল

176
@ ল্যারিবাটল আমি প্রায় একই কাজ করি তবে আমি মনে করি কমে কলের জন্য অ্যারে এবং সি এর জন্য একটি প্রয়োগ (যেমন কমা দ্বারা পৃথক যুক্তি)।
সামিহ

3
আমি এটা বোকা সম্মত। সবচেয়ে বিরক্তিকর বিষয় হ'ল কোনওভাবে এই সাক্ষাত্কারের সময় এই প্রশ্নটি জিজ্ঞাসা করা হয় কারণ কিছু প্রভাবশালী চম্প তাদের গুরুত্বপূর্ণ জেএস প্রশ্নের তালিকায় প্রশ্নটি যুক্ত করেছিল।
রিঙ্গো

6
আপনি একবার কাজের জন্য আবেদন করুন (একটি যুক্তি), আপনি [ফোন] বহুবার লোককে কল করেন (বেশ কয়েকটি যুক্তি)। বিকল্প: এখানে [খুব?] ডিউটি ​​গেমের অনেক কল রয়েছে।
গ্রাস ডাবল

1
যখন "এই" মান নির্বিশেষে আর্গুমেন্ট মানগুলির তালিকার সাথে একটি ভেরিয়াদিক ফাংশন চাওয়ার উদ্দেশ্য হয়, তখন ES6 স্প্রেড অপারেটর ব্যবহার করুন, যেমন fn(...input)ইনপুটটি অ্যারে থাকে। বিকাশকারী.মোজিলা.আর.ইন-
ইউএস

উত্তর:


3644

পার্থক্যটি হ'ল applyআপনাকে argumentsঅ্যারে হিসাবে ফাংশনটি শুরু করতে দেয় ; callপরামিতিগুলি সুস্পষ্টভাবে তালিকাভুক্ত করা প্রয়োজন। একটি দরকারী স্মৃতিসম্বন্ধীয় হয় " একটি জন্য একটি rray এবং সি জন্য omma।"

প্রয়োগ এবং কল করার বিষয়ে MDN এর ডকুমেন্টেশন দেখুন ।

সিউডো সিনট্যাক্স:

theFunction.apply(valueForThis, arrayOfArgs)

theFunction.call(valueForThis, arg1, arg2, ...)

এছাড়াও রয়েছে ES6 হিসাবে, ফাংশনটির spreadসাথে ব্যবহারের জন্য অ্যারের সম্ভাবনা call, আপনি এখানে সামঞ্জস্যগুলি দেখতে পারেন ।

কোডের উদাহরণ:

function theFunction(name, profession) {
    console.log("My name is " + name + " and I am a " + profession +".");
}
theFunction("John", "fireman");
theFunction.apply(undefined, ["Susan", "school teacher"]);
theFunction.call(undefined, "Claude", "mathematician");
theFunction.call(undefined, ...["Matthew", "physicist"]); // used with the spread operator


24
একটি বিষয় যুক্ত করতে হবে যে আরোগুলি অবশ্যই একটি সংখ্যাসূচক অ্যারে ([]) হওয়া উচিত। সহযোগী অ্যারে ({}) কাজ করবে না।
কেভিন শ্রোয়েদার

325
@KevinSchroeder: জাভাস্ক্রিপ্ট বাচনে সালে []একটি বলা হয় অ্যারের , {}একটি বলা হয় অবজেক্ট
মার্টিজন

89
আমি প্রায়শই ভুলে যেতাম কোন অ্যারে লাগে এবং যা আপনাকে আর্গুমেন্টগুলি তালিকাভুক্ত করার প্রত্যাশা করে। একটি কৌশল আমি এটা মনে রাখতে ব্যবহার হলে সঙ্গে পদ্ধতি শুরু প্রথম অক্ষর একটি তারপর, এটা অর্থাত একটি অ্যারের লাগে একটি pply অ্যারে
আজিজ punjani

16
@SAM ব্যবহার কল যদি আপনি এর মান পরিবর্তন করতে হবে একটি স্বাভাবিক ফাংশন কল পরিবর্তে শুধুমাত্র জ্ঞান করে তোলে এই ফাংশন কল জন্য। একটি উদাহরণ (এটি একটি ফাংশন আর্গুমেন্ট-অবজেক্টকে একটি অ্যারে রূপান্তর করে): Array.prototype.slice.call(arguments)বা [].slice.call(arguments)আবেদন তোলে অর্থে যদি আপনি একটি ফাংশন (প্রায়) একই পরামিতি সঙ্গে আরেকটি ফাংশন কল যে উদাহরণস্বরূপ একটি অ্যারের মধ্যে আর্গুমেন্ট আছে। প্রস্তাবনাfuncname(arg1) যদি আপনার যা প্রয়োজন তা করে তবে একটি সাধারণ ফাংশন কল ব্যবহার করুন এবং কলটি সংরক্ষণ করুন এবং যখন আপনার সত্যিকারের প্রয়োজন হয় তখন সেই বিশেষ অনুষ্ঠানের জন্য আবেদন করুন।
কিছু

4
@ কুণালসিংহ উভয়ই callএবং applyদুটি পরামিতি লাগে। apply' and কল` ফাংশনের প্রথম যুক্তিটি অবশ্যই মালিকের অবজেক্ট এবং দ্বিতীয় প্যারামিটারটি যথাক্রমে অ্যারে বা কমা দ্বারা বিভক্ত পরামিতি হবে। যদি আপনি প্রথম তর্কটি পাস করেন nullবা undefinedঅ-কড়া মোডে রেখেছেন তবে তাদের প্রতিস্থাপন করা হবে বিশ্বব্যাপী বস্তুর সাথেwindow
এজে কার্শি

229

কে স্কট অ্যালেন এই বিষয়ে একটি সুন্দর লেখার ব্যবস্থা আছে।

মূলত, তারা কীভাবে ফাংশন আর্গুমেন্টগুলি পরিচালনা করে তা নিয়ে তারা পৃথক।

প্রয়োগ () পদ্ধতিটি কল করার জন্য অভিন্ন (), প্রয়োগ ব্যতীত () দ্বিতীয় প্যারামিটার হিসাবে অ্যারের প্রয়োজন। অ্যারে লক্ষ্য পদ্ধতির জন্য আর্গুমেন্টগুলি উপস্থাপন করে। "

তাই:

// assuming you have f
function f(message) { ... }
f.call(receiver, "test");
f.apply(receiver, ["test"]);

42
প্রয়োগ () এবং কল () এর দ্বিতীয় প্যারামিটারটি alচ্ছিক, প্রয়োজনীয় নয়।
ক্রুদ্ধ কিউই

34
প্রথম প্যারামিটার খুব প্রয়োজন হয় না।
ইকরাম

@ ইক্রোম, প্রথম প্যারামিটারটির প্রয়োজন হয় না callতবে এর প্রয়োজন হয় apply
আইম্যাকস্টেলি

160

প্রতিটি ফাংশন কখন ব্যবহার করবেন সে সম্পর্কে অংশটি উত্তর দেওয়ার জন্য, applyআপনি কীভাবে আর্গুমেন্টটি যাচ্ছেন তা যদি না জানেন বা যদি তারা ইতিমধ্যে কোনও অ্যারে বা অ্যারে-জাতীয় বস্তুতে থাকে (যেমন argumentsআপনার নিজের আর্গুমেন্ট ফরোয়ার্ড করার জন্য অবজেক্টের মতো থাকে) তবে সেই অংশটি উত্তর দিন । callঅন্যথায় ব্যবহার করুন , যেহেতু কোনও অ্যারেতে আর্গুমেন্টগুলি মোড়ানোর দরকার নেই।

f.call(thisObject, a, b, c); // Fixed number of arguments

f.apply(thisObject, arguments); // Forward this function's arguments

var args = [];
while (...) {
    args.push(some_value());
}
f.apply(thisObject, args); // Unknown number of arguments

যখন আমি কোনও যুক্তি (আপনার উদাহরণের মতো) পাস করি না, তখন আমি পছন্দ করি callযেহেতু আমি ফাংশনটি কল করছি । applyবোঝায় আপনি ফাংশনটি (অস্তিত্বহীন) যুক্তিতে প্রয়োগ করছেন।

কোনও পারফরম্যান্সের পার্থক্য থাকতে হবে না, যদি আপনি applyকোনও অ্যারেতে (যেমন f.apply(thisObject, [a, b, c])পরিবর্তে f.call(thisObject, a, b, c)) আর্গুমেন্ট ব্যবহার করেন এবং মোড়েন তবে সম্ভবত । আমি এটি পরীক্ষা করে দেখিনি, তাই পার্থক্য থাকতে পারে তবে এটি খুব ব্রাউজার নির্দিষ্ট হবে। এটা যে সম্ভবত callদ্রুততর যদি আপনি ইতিমধ্যে একটি অ্যারের মধ্যে আর্গুমেন্ট ছিল না এবং applyদ্রুততর যদি আপনি না।


111

এখানে একটি ভাল স্তন্যপায়ী। একজন pply ব্যবহার একটি rrays এবং একটি lways এক বা দুটি আর্গুমেন্ট লাগে। আপনি যখন সি ব্যবহার করেন তখন সমস্ত আর্গুমেন্টের সংখ্যায় সি ount


2
কার্যকর সেখানে স্মৃতিচারণ! প্রথম বা দ্বিতীয় প্যারামিটারের applyপ্রয়োজন হয় না বলেই আমি 'এক বা দুটি আর্গুমেন্ট' পরিবর্তন করে 'সর্বোচ্চ দুটি আর্গুমেন্ট' বলতে পারি । কেউ কেন কল করবে applyবা callপ্যারামিটার ছাড়াই আমি নিশ্চিত নই । কেউ মত দেখায় কেন এখানে খুঁজে বের করতে চেষ্টা করছে stackoverflow.com/questions/15903782/...
dantheta

92

যদিও এটি একটি পুরানো বিষয়, আমি কেবল এটিই নির্দেশ করতে চেয়েছিলাম c কলগুলি অ্যাপ্লিকেশনগুলির চেয়ে কিছুটা দ্রুত। আমি ঠিক বলতে পারি না কেন।

Jscreen, http://jsperf.com/test-call-vs-apply/3 দেখুন


[ UPDATE!]

ডগলাস ক্রকফোর্ড সংক্ষিপ্তভাবে দুজনের মধ্যে পার্থক্যের উল্লেখ করেছেন, যা পারফরম্যান্সের পার্থক্য ব্যাখ্যা করতে পারে ... http://youtu.be/ya4UHuXNygM?t=15m52s

প্রয়োগে আর্গুমেন্টের অ্যারে লাগে, যখন কলটি শূন্য বা ততোধিক পৃথক প্যারামিটার নেয়! আহ আহ!

.apply(this, [...])

.call(this, param1, param2, param3, param4...)


এটি প্যারামিটারগুলি / অ্যারে দিয়ে ফাংশনটি কী করে তার উপর নির্ভর করে, যদি অ্যারেটি প্রক্রিয়া করার প্রয়োজন না হয় তবে এটি কি কম সময় নেয়?
এরিক হোডনস্কি

12
আকর্ষণীয়ভাবে এমনকি অ্যারে ছাড়াই, কলটি এখনও আরও দ্রুত। jsperf.com/applyvscallvsfn2
জোশ ম্যাক

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

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

পরীক্ষা এবং ভিডিও ভাগ করে নেওয়ার জন্য আপনাকে ধন্যবাদ
গ্যারি

76

ক্লোজার থেকে একটি নিষ্কাশন অনুসরণ করে : মাইকেল বোলিনের সংজ্ঞা নির্দেশিকা । এটি কিছুটা লম্বা দেখায় তবে এটি প্রচুর অন্তর্দৃষ্টি দিয়ে স্যাচুরেটেড। "পরিশিষ্ট বি। প্রায়শই ভুল বোঝে জাভাস্ক্রিপ্ট ধারণা" থেকে:


thisকোনও ফাংশন বলা হলে কী বোঝায়

ফর্মটির কোনও ক্রিয়াকলাপ কল করার সময় foo.bar.baz(), অবজেক্টটিকে foo.barরিসিভার হিসাবে উল্লেখ করা হয়। যখন ফাংশনটি ডাকা হয়, এটি সেই রিসিভার যা এর মান হিসাবে ব্যবহৃত হয় this:

var obj = {};
obj.value = 10;
/** @param {...number} additionalValues */
obj.addValues = function(additionalValues) {
  for (var i = 0; i < arguments.length; i++) {
    this.value += arguments[i];
  }
  return this.value;
};
// Evaluates to 30 because obj is used as the value for 'this' when
// obj.addValues() is called, so obj.value becomes 10 + 20.
obj.addValues(20);

যদি কোনও ফাংশন ডাকা হয় তখন কোনও স্পষ্টরূপে গ্রহণযোগ্য হয় না, তবে গ্লোবাল অবজেক্টটি রিসিভার হয়ে যায়। পৃষ্ঠা 47-তে "goog.global" তে বর্ণিত হিসাবে, জাভাস্ক্রিপ্ট যখন কোনও ওয়েব ব্রাউজারে কার্যকর করা হয় তখন উইন্ডোটি বিশ্বব্যাপী অবজেক্ট। এটি কিছু অবাক করা আচরণের দিকে পরিচালিত করে:

var f = obj.addValues;
// Evaluates to NaN because window is used as the value for 'this' when
// f() is called. Because and window.value is undefined, adding a number to
// it results in NaN.
f(20);
// This also has the unintentional side effect of adding a value to window:
alert(window.value); // Alerts NaN

যদিও obj.addValuesএবং fএকই ফাংশনটি উল্লেখ করে, ডাকা হলে তারা ভিন্ন আচরণ করে কারণ প্রতিটি কলটিতে রিসিভারের মান আলাদা। এই কারণে, কোনও ফাংশনকে বোঝায় যখন কল করা হয় this, thisযখন এটি আহ্বান করা হয় তখন এটির সঠিক মান হবে তা নিশ্চিত করা গুরুত্বপূর্ণ । স্পষ্টতই, যদি thisফাংশন বডিটিতে রেফারেন্স না দেওয়া হয় তবে তার আচরণ f(20)এবং obj.addValues(20)একই রকম হবে।

যেহেতু ফাংশনগুলি জাভাস্ক্রিপ্টে প্রথম শ্রেণীর অবজেক্ট, সেগুলির নিজস্ব পদ্ধতি থাকতে পারে। সমস্ত ফাংশনগুলির পদ্ধতি রয়েছে call()এবং apply()যা thisফাংশনটি কল করার সময় রিসিভারকে পুনরায় সংজ্ঞা দেওয়া সম্ভব করে (অর্থাত, বস্তু যা বোঝায়)। পদ্ধতিটির স্বাক্ষরগুলি নিম্নরূপ:

/**
* @param {*=} receiver to substitute for 'this'
* @param {...} parameters to use as arguments to the function
*/
Function.prototype.call;
/**
* @param {*=} receiver to substitute for 'this'
* @param {Array} parameters to use as arguments to the function
*/
Function.prototype.apply;

নোট যে শুধুমাত্র মধ্যে পার্থক্য call()এবং apply()যে call()ব্যক্তি আর্গুমেন্ট হিসাবে ফাংশন পরামিতি গ্রহণ করে, যেহেতু apply()তাদের একটি একক অ্যারে হিসাবে গ্রহণ করে:

// When f is called with obj as its receiver, it behaves the same as calling
// obj.addValues(). Both of the following increase obj.value by 60:
f.call(obj, 10, 20, 30);
f.apply(obj, [10, 20, 30]);

নিম্নলিখিত কল, হয় সমতুল্য fএবং obj.addValuesএকই ফাংশন উল্লেখ করুন:

obj.addValues.call(obj, 10, 20, 30);
obj.addValues.apply(obj, [10, 20, 30]);

যাইহোক, যেহেতু এটির নির্দিষ্ট করা না হয়ে রিসিভার আর্গুমেন্টের বিকল্প হিসাবে তার নিজের গ্রাহকের মান call()বা apply()ব্যবহার করে না , নিম্নলিখিতগুলি কাজ করবে না:

// Both statements evaluate to NaN
obj.addValues.call(undefined, 10, 20, 30);
obj.addValues.apply(undefined, [10, 20, 30]);

মান thisকরতে পারেন হতে nullবা undefinedএকটি ফাংশন বলা হয় না। যখন nullবা undefinedরিসিভার হিসাবে সরবরাহ করা হয় call()বা apply(), গ্লোবাল অবজেক্ট পরিবর্তে রিসিভার জন্য মান হিসেবে ব্যবহৃত হয়। অতএব, পূর্ববর্তী কোডটিতে valueবৈশ্বিক অবজেক্টে নাম যুক্ত সম্পত্তি যুক্ত করার একই অনাকাঙ্ক্ষিত পার্শ্ব প্রতিক্রিয়া রয়েছে ।

কোনও ফাংশনটি ভেরিয়েবলটি নির্ধারণ করা হয়েছে তার জ্ঞান না থাকা হিসাবে এটি ভাবতে সহায়ক হতে পারে। এটি এই ধারণাটিকে শক্তিশালী করতে সহায়তা করে যে ফাংশনটি যখন এটি সংজ্ঞায়িত করার পরিবর্তে বলা হয় তখন এর মান আবদ্ধ হবে।


নিষ্কাশনের সমাপ্তি।


কেবল সত্যটি লক্ষ করুন, এটি দেহের additionalValuesঅভ্যন্তরে উল্লেখ করা হয়নিobj.addValues
ভিক্টর স্টলবিন

আমি জানি আপনি প্রশ্নের উত্তর দিচ্ছিলেন তবে যুক্ত করতে চান: চ সংজ্ঞা দেওয়ার সময় আপনি বাঁধাই করতে পারতেন could var f = obj.addValues;হয়ে যায় var f = obj.addValues.bind(obj) এবং এখন চ (20) প্রতিবার কল ব্যবহার না করে বা প্রয়োগ না করেই কাজ করবে।
ঝিলবার্টি

আমি জানি আপনি এটি লেখেন নি তবে আপনি বইয়ের পাঠ্য এবং উদাহরণগুলি প্রাসঙ্গিক হিসাবে তুলে ধরেছেন এবং আমি খুব কৃতজ্ঞ। তারা খুব সহায়ক ছিল।
ফ্রালকন

34

এক বস্তুর জন্য অন্য বস্তুর ক্রিয়াকলাপ orrowণ গ্রহণের জন্য এটি সময়ে সময়ে কার্যকর হয়, যার অর্থ orrowণ গ্রহণকারী বস্তু কেবলমাত্র ntণদানের ক্রিয়াকলাপটি সম্পাদন করে যেমন এটি তার নিজস্ব।

একটি ছোট কোড উদাহরণ:

var friend = {
    car: false,
    lendCar: function ( canLend ){
      this.car = canLend;
 }

}; 

var me = {
    car: false,
    gotCar: function(){
      return this.car === true;
  }
};

console.log(me.gotCar()); // false

friend.lendCar.call(me, true); 

console.log(me.gotCar()); // true

friend.lendCar.apply(me, [false]);

console.log(me.gotCar()); // false

এই পদ্ধতিগুলি বস্তুকে অস্থায়ী কার্যকারিতা দেওয়ার জন্য খুব দরকারী।


1
যে সমস্ত লোকেরা কীভাবে console.logচেক আউট দেখতে হয় তা জানতে চান: কনসোল.লগ কী এবং আমি কীভাবে এটি ব্যবহার করব?
মিশেল আইরেস

25

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

  1. বাইন্ড কোনও ক্রিয়াকলাপের উদাহরণ প্রয়োগ করে যা সম্পাদন করা যায়
  2. প্রথম প্যারামিটারটি ' এটি '
  3. দ্বিতীয় প্যারামিটার হল আর্গুমেন্টগুলির একটি কমা দ্বারা পৃথক করা তালিকা ( কলের মতো )

}

function Person(name) {
    this.name = name; 
}
Person.prototype.getName = function(a,b) { 
     return this.name + " " + a + " " + b; 
}

var reader = new Person('John Smith');

reader.getName = function() {
   // Apply and Call executes the function and returns value

   // Also notice the different ways of extracting 'getName' prototype
   var baseName = Object.getPrototypeOf(this).getName.apply(this,["is a", "boy"]);
   console.log("Apply: " + baseName);

   var baseName = Object.getPrototypeOf(reader).getName.call(this, "is a", "boy"); 
   console.log("Call: " + baseName);

   // Bind returns function which can be invoked
   var baseName = Person.prototype.getName.bind(this, "is a", "boy"); 
   console.log("Bind: " + baseName());
}

reader.getName();
/* Output
Apply: John Smith is a boy
Call: John Smith is a boy
Bind: John Smith is a boy
*/

23

আমি একটি উদাহরণ দেখাতে চাই, যেখানে 'ভ্যালুফোর্ডটিস' যুক্তিটি ব্যবহৃত হয়:

Array.prototype.push = function(element) {
   /*
   Native code*, that uses 'this'       
   this.put(element);
   */
}
var array = [];
array.push(1);
array.push.apply(array,[2,3]);
Array.prototype.push.apply(array,[4,5]);
array.push.call(array,6,7);
Array.prototype.push.call(array,8,9);
//[1, 2, 3, 4, 5, 6, 7, 8, 9] 

** বিশদ: http://es5.github.io/#x15.4.4.7 *


20

কল () কমা দ্বারা বিযুক্ত আর্গুমেন্ট গ্রহণ করে, যেমন:

.call(scope, arg1, arg2, arg3)

এবং প্রয়োগ () আর্গুমেন্টের অ্যারে নেয়, প্রাক্তন:

.apply(scope, [arg1, arg2, arg3])

এখানে আরও কয়েকটি ব্যবহারের উদাহরণ রয়েছে: http://blog.i-evaluation.com/2012/08/15/javascript-call-and-apply/


call // কল () === কমা-বিচ্ছিন্ন আর্গুমেন্ট (যুক্তি-তালিকা) all কল করুন (এটি, আরগ 1, আরগস 2, আরগ 3, ...) // প্রয়োগ () === আর্গুমেন্টের অ্যারে (অ্যারে-আইটেম)) প্রয়োগ করুন (এটি, [arr0, arr1, arr2, ...]) `
xgqfrms

19

ফাংশন.প্রোটোটাইপ.প্লাই () এর এমডিএন ডক্স থেকে :

প্রয়োগ () পদ্ধতিটি একটি প্রদত্ত thisমান এবং একটি অ্যারের (বা একটি অ্যারের মতো অবজেক্ট) হিসাবে সরবরাহিত যুক্তি সহ একটি ফাংশনকে কল করে ।

বাক্য গঠন

fun.apply(thisArg, [argsArray])

ফাংশন.প্রোটোটাইপ.কল () তে এমডিএন ডক্স থেকে :

কল () পদ্ধতিটি একটি প্রদত্ত thisমান এবং আর্গুমেন্ট পৃথকভাবে সরবরাহ করে একটি ফাংশন কল করে ।

বাক্য গঠন

fun.call(thisArg[, arg1[, arg2[, ...]]])

জাভাস্ক্রিপ্টে Function.apply এবং Function.call থেকে :

প্রয়োগ () পদ্ধতিটি কল করার জন্য অভিন্ন (), প্রয়োগ ব্যতীত () দ্বিতীয় প্যারামিটার হিসাবে অ্যারের প্রয়োজন। অ্যারে লক্ষ্য পদ্ধতির জন্য আর্গুমেন্টগুলি উপস্থাপন করে।


কোড উদাহরণ:

var doSomething = function() {
    var arr = [];
    for(i in arguments) {
        if(typeof this[arguments[i]] !== 'undefined') {
            arr.push(this[arguments[i]]);
        }
    }
    return arr;
}

var output = function(position, obj) {
    document.body.innerHTML += '<h3>output ' + position + '</h3>' + JSON.stringify(obj) + '\n<br>\n<br><hr>';
}

output(1, doSomething(
    'one',
    'two',
    'two',
    'one'
));

output(2, doSomething.apply({one : 'Steven', two : 'Jane'}, [
    'one',
    'two',
    'two',
    'one'
]));

output(3, doSomething.call({one : 'Steven', two : 'Jane'},
    'one',
    'two',
    'two',
    'one'
));

আরও দেখুন এই বেহালার


11

মৌলিক পার্থক্য হল call()একটি গ্রহণ আর্গুমেন্ট তালিকার সময়, apply()একটি গ্রহণ আর্গুমেন্ট একক অ্যারে



10

এখানে একটি ছোট পোস্ট রয়েছে, আমি এটি লিখেছিলাম:

http://sizeableidea.com/call-versus-apply-javascript/

var obj1 = { which : "obj1" },
obj2 = { which : "obj2" };

function execute(arg1, arg2){
    console.log(this.which, arg1, arg2);
}

//using call
execute.call(obj1, "dan", "stanhope");
//output: obj1 dan stanhope

//using apply
execute.apply(obj2, ["dan", "stanhope"]);
//output: obj2 dan stanhope

//using old school
execute("dan", "stanhope");
//output: undefined "dan" "stanhope"

এখানে অন্য একটি: ব্লগ.আই- মূল্যায়ন ডটকম / 2012 / 08 / 15 / javascript-call-and- অ্যাপ্লিকেশন তবে মূলত এটি সঠিক: .কেল (সুযোগ, আর্গি 1, আরজি 2, আরজি 3)
মার্ক কারওভস্কি

7

পার্থক্যটি হ'ল call()ফাংশন আর্গুমেন্টগুলি আলাদাভাবে apply()নেয় এবং ফাংশন আর্গুমেন্টগুলিকে একটি অ্যারে নেয় takes


6

আমরা কলকে আলাদা করতে পারি এবং নীচের মতো পদ্ধতিগুলি প্রয়োগ করতে পারি

কল: যুক্তি সহ একটি ফাংশন স্বতন্ত্রভাবে সরবরাহ করে। আপনি যদি আর্গুমেন্টগুলি পাস করতে জানেন বা পাস করার কোনও যুক্তি না থেকে থাকেন তবে আপনি কলটি ব্যবহার করতে পারেন।

আবেদন করুন: অ্যারের হিসাবে সরবরাহ করা যুক্তি সহ একটি ফাংশন কল করুন। আপনি কতটা যুক্তি ফাংশনে পাস করবেন তা যদি আপনি না জানেন তবে আপনি প্রয়োগটি প্রয়োগ করতে পারেন।

প্রয়োগের মাধ্যমে কল ব্যবহার করার একটি সুবিধা রয়েছে, আমাদের কেবলমাত্র পাস হওয়া অ্যারে পরিবর্তন করতে পারে কেবলমাত্র যুক্তির সংখ্যা পরিবর্তন করার দরকার নেই।

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


5

এই পদ্ধতির মধ্যে পার্থক্য হ'ল আপনি কীভাবে প্যারামিটারগুলি পাস করতে চান।

"অ্যারের জন্য আর সি এর জন্য কমা" হ্যান্ডি মিমোনিক।


11
এই উত্তরটি এমন কী সরবরাহ করে যা অন্য উত্তরে ইতিমধ্যে ভাল সরবরাহ করা হয়নি?
কিয়েল

5

কল এবং প্রয়োগ উভয়ই thisযখন কোনও ফাংশন সম্পাদন হয় তখন মানটিকে বল প্রয়োগ করতে ব্যবহৃত হয়। পার্থক্যটি হ'ল 1 যেখানে এবং সেখানে আর্গুমেন্ট callনেয় । দুটি মাত্র যুক্তি লাগে, অন্যটি হ'ল আর্গুমেন্ট অ্যারে।n+1this'n' argumentsapplythis

সুবিধা আমি দেখতে applyবেশি callযে আমরা সহজেই অনেক প্রচেষ্টা ছাড়া অন্যান্য ফাংশন একটি ফাংশন কল প্রতিনিধি পারে;

function sayHello() {
  console.log(this, arguments);
}

function hello() {
  sayHello.apply(this, arguments);
}

var obj = {name: 'my name'}
hello.call(obj, 'some', 'arguments');

আমরা কত সহজেই ব্যবহার helloকরার জন্য প্রেরণ করেছি তা পর্যবেক্ষণ করুন , তবে এটির সাথে অর্জন করা খুব কঠিন।sayHelloapplycall


4

যদিও callএবং applyএকই জিনিসটি অর্জন করা, আমি মনে করি কমপক্ষে একটি জায়গা রয়েছে যেখানে আপনি ব্যবহার করতে পারবেন না callতবে কেবল ব্যবহার করতে পারবেন apply। এটি যখন আপনি উত্তরাধিকার সমর্থন করতে চান এবং কনস্ট্রাক্টরকে কল করতে চান।

এখানে একটি ফাংশন আপনাকে এমন ক্লাস তৈরি করতে দেয় যা অন্যান্য ক্লাসগুলি বাড়িয়ে ক্লাস তৈরি করতে সহায়তা করে।

function makeClass( properties ) {
    var ctor = properties['constructor'] || function(){}
    var Super = properties['extends'];
    var Class = function () {
                 // Here 'call' cannot work, only 'apply' can!!!
                 if(Super)
                    Super.apply(this,arguments);  
                 ctor.apply(this,arguments);
                }
     if(Super){
        Class.prototype = Object.create( Super.prototype );
        Class.prototype.constructor = Class;
     }
     Object.keys(properties).forEach( function(prop) {
           if(prop!=='constructor' && prop!=='extends')
            Class.prototype[prop] = properties[prop];
     });
   return Class; 
}

//Usage
var Car = makeClass({
             constructor: function(name){
                         this.name=name;
                        },
             yourName: function() {
                     return this.name;
                   }
          });
//We have a Car class now
 var carInstance=new Car('Fiat');
carInstance.youName();// ReturnsFiat

var SuperCar = makeClass({
               constructor: function(ignore,power){
                     this.power=power;
                  },
               extends:Car,
               yourPower: function() {
                    return this.power;
                  }
              });
//We have a SuperCar class now, which is subclass of Car
var superCar=new SuperCar('BMW xy',2.6);
superCar.yourName();//Returns BMW xy
superCar.yourPower();// Returns 2.6

আমি বিশ্বাস করি নির্বাচিত উত্তরে বর্ণিত হিসাবে স্প্রেড অপারেটরের সাথে কল সেখানে কাজ করবে। আমি যদি কিছু মিস করি না
ঝিলবার্টি

4

সারসংক্ষেপ:

উভয় call()এবং apply()যে পদ্ধতিতে অবস্থিত হয় Function.prototype। তাই এগুলি প্রতিটি ফাংশন অবজেক্টে প্রোটোটাইপ চেইনের মাধ্যমে উপলব্ধ। উভয় call()এবং এর apply()নির্দিষ্ট মান সহ একটি ফাংশন কার্যকর করতে পারে this

মধ্যে মূল পার্থক্য call()এবং apply()আপনি তা আর্গুমেন্ট মধ্যে পাস আছে। উভয় call()এবং apply()আপনি একটি প্রথম যুক্তি হিসাবে পাস করুন যে বস্তুর আপনি মূল্য হতে চান this। অন্যান্য যুক্তি নিম্নলিখিত উপায়ে পৃথক:

  • সঙ্গে call() আপনি সাধারণত আর্গুমেন্ট করা আছে (দ্বিতীয় যুক্তি থেকে শুরু)
  • আপনার সাথে apply()আর্গুমেন্টের অ্যারেতে যেতে হবে।

উদাহরণ:

let obj = {
  val1: 5,
  val2: 10
}

const summation = function (val3, val4) {
  return  this.val1 + this.val2 + val3 + val4;
}

console.log(summation.apply(obj, [2 ,3]));
// first we assign we value of this in the first arg
// with apply we have to pass in an array


console.log(summation.call(obj, 2, 3));
// with call we can pass in each arg individually

আমার এই ফাংশনগুলি কেন ব্যবহার করতে হবে?

thisমান জাভাস্ক্রিপ্ট মধ্যে চতুর কখনও কখনও হতে পারে না। মান thisনির্ধারিত যখন একটি ফাংশন যখন না একটি ফাংশন সংজ্ঞায়িত করা হয় মৃত্যুদন্ড কার্যকর করা হয়। যদি আমাদের ফাংশন কোনও সঠিক thisবাঁধার উপর নির্ভরশীল হয় তবে আমরা ব্যবহার করতে পারি call()এবং apply()এই আচরণটি প্রয়োগ করতে পারি । উদাহরণ স্বরূপ:

var name = 'unwantedGlobalName';

const obj =  {
  name: 'Willem',
  sayName () { console.log(this.name);}
}


let copiedMethod = obj.sayName;
// we store the function in the copiedmethod variable



copiedMethod();
// this is now window, unwantedGlobalName gets logged

copiedMethod.call(obj);
// we enforce this to be obj, Willem gets logged


4

মূল পার্থক্যটি হ'ল, কল ব্যবহার করে আমরা সুযোগটি পরিবর্তন করতে পারি এবং আর্গুমেন্টগুলি স্বাভাবিক হিসাবে পাস করতে পারি তবে প্রয়োগের সাহায্যে আপনি এটি অ্যারের হিসাবে আর্গুমেন্ট ব্যবহার করে কল করতে পারেন (এ্যারে হিসাবে তাদের পাস করুন)। আপনার কোডটিতে তারা কী করবে সে ক্ষেত্রে তারা বেশ সাদৃশ্যপূর্ণ।

যদিও এই ফাংশনটির বাক্য গঠনটি প্রয়োগ () এর সাথে প্রায় একই রকম হয়, তবে মূল পার্থক্য হ'ল কল () একটি আর্গুমেন্ট তালিকা গ্রহণ করে, যখন প্রয়োগ () আর্গুমেন্টের একক অ্যারে গ্রহণ করে ts

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

// min/max number in an array
var numbers = [5, 6, 2, 3, 7];

// using Math.min/Math.max apply
var max = Math.max.apply(null, numbers); 
// This about equal to Math.max(numbers[0], ...)
// or Math.max(5, 6, ...)

var min = Math.min.apply(null, numbers)

সুতরাং মূল পার্থক্যটি কেবলমাত্র আমরা আর্গুমেন্টগুলি পাস করার উপায়:

কল করুন:

function.call(thisArg, arg1, arg2, ...);

প্রয়োগ করুন:

function.apply(thisArg, [argsArray]);

2

আমাকে এই সম্পর্কে একটি সামান্য বিশদ যোগ করুন।

এই দুটি কল প্রায় সমতুল্য:

func.call(context, ...args); // pass an array as list with spread operator

func.apply(context, args);   // is same as using apply

এখানে সামান্য পার্থক্য রয়েছে:

  • spreadঅপারেটর ... ক্ষণস্থায়ী অনুমতি দেয় iterable args তালিকা ডাকতে হয়।
  • কেবল অ্যারে-জাতীয় আরগস applyগ্রহণ করে ।

সুতরাং, এই কলগুলি একে অপরের পরিপূরক। যেখানে আমরা প্রত্যাবর্তনযোগ্য , callকাজ করার আশা করি, যেখানে আমরা অ্যারের মতো প্রত্যাশা করি ,apply কাজ করে।

এবং সত্যিকারের অ্যারের মতো পুনরাবৃত্তিযোগ্য এবং অ্যারে উভয়ের মতো অবজেক্টগুলির জন্য , আমরা প্রযুক্তিগতভাবে সেগুলির যে কোনওটি ব্যবহার করতে পারি, তবে প্রয়োগ সম্ভবত দ্রুততর হবে কারণ বেশিরভাগ জাভাস্ক্রিপ্ট ইঞ্জিনগুলি অভ্যন্তরীণভাবে এটি আরও ভালতর করে তোলে।

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.