কোনও জাভাস্ক্রিপ্ট ফাংশনে পরিবর্তনশীল সংখ্যক আর্গুমেন্ট প্রেরণ করা কি সম্ভব?


169

একটি অ্যারে থেকে জাভাস্ক্রিপ্ট ফাংশনটিতে একটি পরিবর্তনশীল সংখ্যক আর্গুমেন্ট প্রেরণ করা কি সম্ভব?

var arr = ['a','b','c']

var func = function()
{
    // debug 
    alert(arguments.length);
    //
    for(arg in arguments)
        alert(arg);
}

func('a','b','c','d'); // prints 4 which is what I want, then 'a','b','c','d'
func(arr); // prints 1, then 'Array'

আমি সম্প্রতি প্রচুর পাইথন লিখেছি এবং ভারার্গস গ্রহণ করতে এবং সেগুলি পাঠাতে সক্ষম হবার জন্য এটি একটি দুর্দান্ত প্যাটার্ন। যেমন

def func(*args):
   print len(args)
   for i in args:
       print i

func('a','b','c','d'); // prints 4 which is what I want, then 'a','b','c','d'
func(*arr) // prints 4 which is what I want, then 'a','b','c','d'

জাভাস্ক্রিপ্টে আর্গুমেন্ট অ্যারে হিসাবে বিবেচনা করার জন্য একটি অ্যারে প্রেরণ করা কি সম্ভব ?


4
নোট করুন যে for - inকোনও argumentsঅবজেক্টের সাথে লুপ ব্যবহার করা ভাল নয় - তার lengthপরিবর্তে সম্পত্তির উপরে পুনরায় পুনরুক্ত হওয়া লুপের জন্য 'সাধারণ' ব্যবহার করা উচিত
ইয়ি জিয়াং

2
এটি কখনই সমস্যা হয়নি, আপনি কেন বিষয়টি ব্যাখ্যা করতে পারেন? আর্গুমেন্ট অবজেক্ট অ্যাগ্রুমেন্টস [0.. দৈর্ঘ্য -1] সংস্করণটি ব্যবহারের জন্য একটি নগণ্য কর্মক্ষমতা উন্নতির জন্য প্রায় সর্বদা যথেষ্ট ছোট small
ফায়ার ক্র


1
আমি মনে করি যে আর্গুমেন্টগুলি প্রকৃত অ্যারে নয়, তবে একটি বিশেষ অবজেক্ট, সুতরাং জেএস প্রয়োগের উপর নির্ভর করে "ইন" সিন্টেক্সটি কাজ করতে পারে না।
ও'রুনি

উত্তর:


206

আপডেট : ES6 সাল থেকে, ফাংশনটি কল করার সময় আপনি কেবল স্প্রেড সিনট্যাক্সটি ব্যবহার করতে পারেন :

func(...arr);

যেহেতু ES6 এছাড়াও আপনার আর্গুমেন্টগুলিকে অ্যারের হিসাবে বিবেচনা করার প্রত্যাশা করে, আপনি পরামিতি তালিকায় স্প্রেড সিনট্যাক্সটিও ব্যবহার করতে পারেন, উদাহরণস্বরূপ:

function func(...args) {
  args.forEach(arg => console.log(arg))
}

const values = ['a', 'b', 'c']
func(...values)
func(1, 2, 3)

এবং আপনি এটিকে সাধারণ পরামিতিগুলির সাথে একত্রিত করতে পারেন, উদাহরণস্বরূপ আপনি যদি প্রথম দুটি যুক্তি আলাদাভাবে পেতে চান এবং বাকীটি অ্যারে হিসাবে:

function func(first, second, ...theRest) {
  //...
}

এবং সম্ভবত আপনার পক্ষে দরকারী, আপনি জানতে পারবেন যে কোনও কার্য কত আর্গুমেন্ট প্রত্যাশা করে:

var test = function (one, two, three) {}; 
test.length == 3;

তবে যাইহোক আপনি একটি স্বেচ্ছাসেবী আর্গুমেন্ট পাস করতে পারেন ...

স্প্রেড সিনট্যাক্সটি ছোট এবং "মিষ্টি" এর চেয়ে কম applyএবং যদি আপনাকে thisফাংশন কলটিতে মান নির্ধারণের প্রয়োজন না হয় তবে এই উপায়।

এখানে একটি প্রয়োগ উদাহরণ রয়েছে যা এটি করার পূর্বের উপায় ছিল:

var arr = ['a','b','c'];

function func() {
  console.log(this); // 'test'
  console.log(arguments.length); // 3

  for(var i = 0; i < arguments.length; i++) {
    console.log(arguments[i]);
  }

};

func.apply('test', arr);

আজকাল আমি শুধু ব্যবহার করার প্রস্তাব applyশুধুমাত্র আপনি একটি অ্যারে থেকে আর্গুমেন্ট কোনও একটি সংখ্যার পাস করতে হবে এবং সেট thisমান। applyগ্রহণ করা হয় thisপ্রথম আর্গুমেন্ট হিসাবে মান, যা ফাংশন অনুরোধে ব্যবহার করা হবে, যদি আমরা nullঅ-কঠোর কোড ব্যবহার করি , মূল thisশব্দটি অভ্যন্তরীণ গ্লোবাল অবজেক্ট (উইন্ডো) func-কে কঠোর মোডে উল্লেখ করবে, যখন স্পষ্টভাবে 'ব্যবহার কঠোরভাবে ব্যবহার করবে 'বা ইএস মডিউলগুলিতে nullব্যবহৃত হবে।

এছাড়াও লক্ষ্য করুন যে argumentsবস্তুটি আসলে কোনও অ্যারে নয়, আপনি এটিকে রূপান্তর করতে পারেন:

var argsArray = Array.prototype.slice.call(arguments);

এবং ES6 এ:

const argsArray = [...arguments] // or Array.from(arguments)

তবে আপনি argumentsআজকাল খুব সহজেই স্প্রেড সিনট্যাক্সের জন্য সরাসরি অবজেক্টটি ব্যবহার করেন ।


1
ধন্যবাদ, প্রয়োগ কৌশলটি কার্যকর করে, এই ক্ষেত্রে কল কার্যকর হয় না। ভুল করে লেখা ছিল?
ফায়ার ক্রো

যদি ফাংশনটি আসলে কোনও শ্রেণীর সদস্য হয় তবে আপনি এটি কীভাবে করবেন? এটা কী ঠিক? theObject.member.apply (দ্য অবজেক্ট, আর্গুমেন্ট);
বাক্সিসিমো

4
Array.prototype.slice.call(arguments);ভি 8 এর মতো ব্রাউজার জেএস অপ্টিমাইজেশানকে বাধা দেয়।
বিশদটি

2
1. স্পষ্টতই, স্প্রেড অপারেটরেরarguments পক্ষে অবমূল্যায়ন করার পরিকল্পনা করা হয়েছে । এর জন্য আমার কোনও উত্স নেই তবে আমি এটি কোথাও শুনেছি। 2. এমডিএন জানিয়েছে যে অবজেক্টটিতে ব্যবহার করা ভি 8 এর মতো ইঞ্জিনগুলিতে অপ্টিমাইজেশন প্রতিরোধ করে। তারা "ঘৃণিত অ্যারে নির্মাণকারী" , বা ব্যবহার করার পরামর্শ দেয় । আপনি কি ES2015 এর জন্য আপনার উত্তর আপডেট করার যত্ন নেবেন? sliceargumentsArray.from(arguments)[...arguments]
ব্র্যাডেন সেরা

এনবি: আমি এগিয়ে গিয়ে নিজের উত্তর লিখেছিলাম ।
ব্র্যাডেন সেরা

75

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

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

var otherFunc = function() {
   alert(arguments.length); // Outputs: 10
}

var myFunc = function() {
  alert(arguments.length); // Outputs: 10
  otherFunc.apply(this, arguments);
}
myFunc(1,2,3,4,5,6,7,8,9,10);

23

Splat এবং বিস্তার অপারেটার ES6, জাভাস্ক্রীপ্ট এর পরিকল্পিত পরবর্তী সংস্করণ অংশ। এখনও পর্যন্ত কেবল ফায়ারফক্স তাদের সমর্থন করে। এই কোডটি এফএফ 16 + এ কাজ করে:

var arr = ['quick', 'brown', 'lazy'];

var sprintf = function(str, ...args)
{
    for (arg of args) {
        str = str.replace(/%s/, arg);
    }
    return str;
}

sprintf.apply(null, ['The %s %s fox jumps over the %s dog.', ...arr]);
sprintf('The %s %s fox jumps over the %s dog.', 'slow', 'red', 'sleeping');

স্প্রেডের জন্য অবার্ক সিনট্যাক্সটি নোট করুন। স্বাভাবিক সিনট্যাক্স sprintf('The %s %s fox jumps over the %s dog.', ...arr);হয় এখনও সমর্থিত নয় । আপনি এখানে একটি ES6 সামঞ্জস্যতা টেবিল খুঁজে পেতে পারেন ।

আরও for...ofএকটি ES6 সংযোজন এর ব্যবহারটিও নোট করুন । for...inঅ্যারে ব্যবহার করা একটি খারাপ ধারণা


স্প্রেডের জন্য সাধারণ সিনট্যাক্স এখন ফায়ারফক্স এবং ক্রোমে সমর্থিত
ব্যবহারকারী

8

applyফাংশন দুটি আর্গুমেন্ট লাগে; বস্তুটি thisআবদ্ধ হবে, এবং একটি অ্যারের সাথে উপস্থাপিত যুক্তিগুলি।

some_func = function (a, b) { return b }
some_func.apply(obj, ["arguments", "are", "here"])
// "are"

8

ES2015 হিসাবে দুটি পদ্ধতি রয়েছে।

argumentsঅবজেক্ট

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

আমি অন্যান্য উত্তর ব্যবহার করে উল্লেখ দেখেছি slice। এটা করবেন না। এটি অপ্টিমাইজেশন প্রতিরোধ করে (উত্স: MDN )।

Array.from(arguments)
[...arguments]

তবে, আমি যুক্তিযুক্ত হব যে argumentsএটি সমস্যাযুক্ত কারণ এটি কোনও ফাংশনকে ইনপুট হিসাবে গ্রহণ করে তা গোপন করে। একটি argumentsফাংশন সাধারণত এইভাবে লেখা হয়:

function mean(){
    let args = [...arguments];
    return args.reduce((a,b)=>a+b) / args.length;
}

কখনও কখনও, ফাংশন শিরোনামটি সি-জাতীয় ফ্যাশনে আর্গুমেন্টগুলি ডকুমেন্ট করার জন্য নীচের মতো লেখা হয়:

function mean(/* ... */){ ... }

তবে তা বিরল।

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

int myFunction();
/* This function accepts unspecified parameters */

এএনএসআই সি varargs( ...) এর জন্য এবং voidএকটি খালি যুক্তি-তালিকা নির্দিষ্ট করার জন্য একটি সুবিধা সরবরাহ করে ।

int myFunction(void);
/* This function accepts no parameters */

যখন অনেকে ফাংশনটি শূন্য আর্গুমেন্ট নেবে এমন প্রত্যাশা করেন তখন অনেকে অজান্তেই একটি unspecifiedআর্গুমেন্ট তালিকা ( int myfunction();) দিয়ে ফাংশন ঘোষণা করে । এটি প্রযুক্তিগতভাবে একটি বাগ কারণ ফাংশনটি হবে আর্গুমেন্ট গ্রহণ । তাদের যে কোনও সংখ্যা।

varargsসিতে একটি সঠিক ফাংশন রূপ নেয়:

int myFunction(int nargs, ...);

এবং জাভাস্ক্রিপ্ট আসলে এর সাথে কিছু মিল আছে।

অপারেটর / বিশ্রামের পরামিতিগুলি স্প্রেড করুন

আমি ইতিমধ্যে আপনাকে স্প্রেড অপারেটরটি দেখিয়েছি।

...name

এটি বেশ বহুমুখী, এবং খুব সুন্দরভাবে ডকুমেন্টেড ফ্যাশনে ভারার্গস নির্দিষ্ট করতে কোনও ফাংশনের যুক্তি-তালিকায় ("বিশ্রামের পরামিতি") ব্যবহার করা যেতে পারে:

function mean(...args){
    return args.reduce((a,b)=>a+b) / args.length;
}

বা ল্যাম্বডা এক্সপ্রেশন হিসাবে:

((...args)=>args.reduce((a,b)=>a+b) / args.length)(1,2,3,4,5); // 3

আমি অনেকটা স্প্রেড অপারেটরকেই পছন্দ করি। এটি পরিষ্কার এবং স্ব-ডকুমেন্টিং।


2
আপডেট হওয়া উত্তরের জন্য আপনাকে ধন্যবাদ, এই পোস্টটি ES 2015 এর পূর্বাভাস দেয় তাই আপনি আরও সাম্প্রতিক বিকল্পগুলিতে পূরণ করেছেন বলে আমি আনন্দিত
ফায়ার ক্রু

5

একে splatঅপারেটর বলা হয় । আপনি এটি ব্যবহার করে জাভাস্ক্রিপ্টে করতে পারেন apply:

var arr = ['a','b','c','d'];
var func = function() {
    // debug 
    console.log(arguments.length);
    console.log(arguments);
}
func('a','b','c','d'); // prints 4 which is what I want, then 'a','b','c','d'
func(arr); // prints 1, then 'Array'
func.apply(null, arr); 

4

ES6 আপনি ব্যবহার করতে পারেন বাকি পরামিতি জন্য varagrs। এটি আর্গুমেন্টের তালিকাটি নেয় এবং এটিকে অ্যারেতে রূপান্তর করে।

function logArgs(...args) {
    console.log(args.length)
    for(let arg of args) {
        console.log(arg)
    }
}

2

এটি পূর্ণসংখ্যার উপর চলক আর্গুমেন্ট এবং অ্যারের জন্য পূর্ণসংখ্যার যোগফল গণনা করার জন্য একটি নমুনা প্রোগ্রাম। আশাকরি এটা সাহায্য করবে.

var CalculateSum = function(){
    calculateSumService.apply( null, arguments );
}

var calculateSumService = function(){
    var sum = 0;

    if( arguments.length === 1){
        var args = arguments[0];

        for(var i = 0;i<args.length; i++){
           sum += args[i]; 
        }
    }else{
        for(var i = 0;i<arguments.length; i++){
           sum += arguments[i]; 
        }        
    }

     alert(sum);

}


//Sample method call

// CalculateSum(10,20,30);         

// CalculateSum([10,20,30,40,50]);

// CalculateSum(10,20);

1
কিছু নোট: 1. varএকটি function scopeপরিবর্তনশীল ঘোষণা । নতুন letএবং constকীওয়ার্ডগুলি (ES 2015) block scopeভেরিয়েবল ঘোষণা করে । ES 2015 এর আগে, যদিও ভেরিয়েবলগুলি অনুশীলনের বিষয় হিসাবে এখনও ফাংশনের শীর্ষে উঠানো উচিত ছিল। 2. আপনার ফাংশন বিরতি যখন একটি আর্গুমেন্ট হিসাবে একটি অ্যারের আপনার ভ্রান্ত গ্রহণযোগ্যতা কারণে দেওয়া 1 পূর্ণসংখ্যা মান (তর্কের ভারার্গস জিজ্ঞেস; আর্গুমেন্ট হিসাবে অ্যারে গ্রহণ করছে না): CalculateSum(6) -> 0। (পরবর্তী পোস্টে অবিরত)
ব্র্যাডেন সেরা

1
৩. ডিবাগ ফাংশনগুলি ব্যবহার করবেন না alert। আসলে, সময়, শুধু ব্যবহার করবেন না alert/prompt/confirmconsole.logডিবাগ করার সময় পরিবর্তে ব্যবহার করুন । ৪. ফাংশনটি returnএকটি মান যুক্ত করা উচিত alert, এটি ইঙ্গিত নয়। ৫. PascalCaseএটি ডেটা "প্রকারের" উল্লেখ না করে এড়িয়ে চলুন । অর্থাৎ একটি ক্লাস। ব্যবহার করুন camelCaseঅথবা under_scoreপরিবর্তে। ৪. আপনি আপনার কার্যগুলি যেভাবে ঘোষণা করেন তা আমি পছন্দ করি না। var f = function(){ ... }বোঝায় যে আপনি এটি কোনও সময়ে পরিবর্তন করতে চান যা সম্ভবত আপনার উদ্দেশ্য নয় inte function name(){ ... }পরিবর্তে প্রচলিত বাক্য গঠন ব্যবহার করুন।
ব্র্যাডেন সেরা

এই সমস্ত সমালোচনামূলক পয়েন্টগুলি প্রদর্শনের জন্য, এখানে আপনার উত্তরটিতে ফাংশনের একটি উন্নত সংস্করণ দেওয়া আছে
ব্র্যাডেন সেরা

2
(function(window) {
  var proxied = window.alert;
  window.alert = function() {
    return proxied.apply(window, arguments);
  };
}(this));

alert(13, 37);

1

যাঁদের এখানে এক ফাংশন থেকে অন্য ফাংশনে ভেরিয়েবল সংখ্যার পাসিং থেকে পুনঃনির্দেশ করা হয়েছিল (যা এই প্রশ্নের সদৃশ হিসাবে চিহ্নিত করা উচিত নয় ):

আপনি যদি জাভাস্ক্রিপ্ট ১.৮.৫ থেকে একটি ফাংশন থেকে অন্য ফাংশনে একটি পরিবর্তনশীল সংখ্যক আর্গুমেন্ট পাস করার চেষ্টা করছেন তবে আপনি কেবল apply()দ্বিতীয় ফাংশনটিতে কল করতে পারেন এবং argumentsপ্যারামিটারে পাস করতে পারেন :

var caller = function()
{
    callee.apply( null, arguments );
}

var callee = function()
{
    alert( arguments.length );
}

caller( "Hello", "World!", 88 ); // Shows "3".

দ্রষ্টব্য: প্রথম যুক্তিটি হ'ল thisপ্যারামিটার। পাসিংnull বিশ্বব্যাপী প্রসঙ্গ থেকে ফাংশনটি কল করবে, অর্থাত্ কোনও বস্তুর পদ্ধতির পরিবর্তে বিশ্বব্যাপী ফাংশন হিসাবে।

এই দস্তাবেজ অনুসারে , ইসমাস্ক্রিপ্ট 5 স্পেসিফিকেশন apply()কঠোরভাবে অ্যারের পরিবর্তে কোনও "জেনেরিক অ্যারে-জাতীয় বস্তু" নেওয়ার পদ্ধতিটিকে নতুনভাবে সংজ্ঞায়িত করেছে । সুতরাং, আপনি সরাসরি পাস করতে পারেনarguments দ্বিতীয় ফাংশন তালিকা ।

ক্রোম 28.0, সাফারি 6.0.5 এবং আইই 10 তে পরীক্ষা করা হয়েছে এই জেএসফিডাল দিয়ে চেষ্টা করে দেখুন ।


0

হ্যাঁ আপনি ভেরিয়েবল নম্বর পাস করতে পারেন। একটি ফাংশন যুক্তি। আপনি এটি applyঅর্জন করতে ব্যবহার করতে পারেন ।

উদাহরণ:

var arr = ["Hi","How","are","you"];

function applyTest(){
    var arg = arguments.length;
    console.log(arg);
}

applyTest.apply(null,arr);

0

আপনি কি চান যে আপনার ফাংশনটি অ্যারে আর্গুমেন্ট বা পরিবর্তনশীল যুক্তিগুলিতে প্রতিক্রিয়া জানাবে? যদি দ্বিতীয়টি হয় তবে চেষ্টা করুন:

var func = function(...rest) {
  alert(rest.length);

  // In JS, don't use for..in with arrays
  // use for..of that consumes array's pre-defined iterator
  // or a more functional approach
  rest.forEach((v) => console.log(v));
};

তবে আপনি যদি একটি অ্যারে যুক্তি পরিচালনা করতে চান

var fn = function(arr) {
  alert(arr.length);

  for(var i of arr) {
    console.log(i);
  }
};
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.