একাধিক যুক্তি বনাম বনাম অপশন অবজেক্ট


157

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

উদাহরণস্বরূপ আমি একটি অ্যারে নোডলিস্টে মানচিত্র করতে একটি ফাংশন লিখছি:

function map(nodeList, callback, thisObject, fromIndex, toIndex){
    ...
}

আমি পরিবর্তে এটি ব্যবহার করতে পারি:

function map(options){
    ...
}

যেখানে বিকল্পগুলি একটি বস্তু:

options={
    nodeList:...,
    callback:...,
    thisObject:...,
    fromIndex:...,
    toIndex:...
}

কোনটি প্রস্তাবিত উপায়? যখন কোনও বনাম অন্যটি ব্যবহার করার জন্য কোনও গাইডলাইন রয়েছে?

[আপডেট] বিকল্প বিকল্পের পক্ষে inক্যমত্য বলে মনে হচ্ছে, তাই আমি একটি মন্তব্য যুক্ত করতে চাই: আমার ক্ষেত্রে যুক্তিগুলির তালিকাটি ব্যবহার করতে প্ররোচিত হওয়ার একটি কারণ ছিল জাভাস্ক্রিপ্টের সাথে সামঞ্জস্যপূর্ণ আচরণ করা was অ্যারে.ম্যাপ পদ্ধতিতে নির্মিত।


2
দ্বিতীয় বিকল্পটি আপনাকে যুক্তিযুক্ত নাম দেয়, যা আমার মতে একটি দুর্দান্ত জিনিস।
ওয়ার্নার কেভেলাম ভেষ্টেরস

এগুলি কি alচ্ছিক বা প্রয়োজনীয় যুক্তি রয়েছে?
আমি

আমার ব্যবহারকারীর @ user1689607 সর্বশেষ তিনটি alচ্ছিক।
ক্রিস্টোফ

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

1
নেটিভ এপিআইয়ের পরে মডেলিং করা কোনও খারাপ জিনিস নয়, যদি আপনার ফাংশনটি একই রকম কিছু করে। এটি সমস্ত "কোডকে সর্বাধিক পঠনযোগ্য করে তোলে to" এ নেমে আসে। Array.prototype.mapএকটি সাধারণ এপিআই রয়েছে যা কোনও আধা-অভিজ্ঞ কোডারকে ঝাঁকুনিতে ফেলে রাখা উচিত নয়।
জেরেমি জে স্টারচার

উত্তর:


160

অন্য অনেকের মত, আমি প্রায়শই options objectপ্যারামিটারগুলির দীর্ঘ তালিকা পাস করার পরিবর্তে কোনও ফাংশনে পাস করতে পছন্দ করি তবে এটি সত্যিকারের প্রসঙ্গে নির্ভর করে।

আমি লিটমাস পরীক্ষা হিসাবে কোড পাঠযোগ্যতা ব্যবহার করি।

উদাহরণস্বরূপ, যদি আমার এই ফাংশন কলটি থাকে:

checkStringLength(inputStr, 10);

আমি মনে করি যে কোডটি সেইভাবে বেশ পঠনযোগ্য এবং পৃথক প্যারামিটারগুলি পাস করা ঠিক।

অন্যদিকে, এখানে কলগুলির সাথে এখানে ফাংশন রয়েছে:

initiateTransferProtocol("http", false, 150, 90, null, true, 18);

আপনি কিছু গবেষণা না করলে পুরোপুরি অপঠনযোগ্য অন্যদিকে, এই কোডটি ভালভাবে পড়ে:

initiateTransferProtocol({
  "protocol": "http",
  "sync":      false,
  "delayBetweenRetries": 150,
  "randomVarianceBetweenRetries": 90,
  "retryCallback": null,
  "log": true,
  "maxRetries": 18
 });

এটি বিজ্ঞানের চেয়ে শিল্পের চেয়ে বেশি, তবে আমার যদি থাম্বের নিয়মগুলির নাম লিখতে হত:

একটি বিকল্প প্যারামিটার ব্যবহার করুন যদি:

  • আপনার চারটি বেশি পরামিতি রয়েছে
  • যে কোনও পরামিতি .চ্ছিক
  • এটি কী প্যারামিটার নেয় তা নির্ধারণ করতে আপনাকে কখনও ফাংশনটি সন্ধান করতে হবে
  • "এআরআরআরআরজি!" চিৎকার করার সময় যদি কেউ কখনও আপনাকে শ্বাসরোধ করার চেষ্টা করে!

10
দুর্দান্ত উত্তর। এটা নির্ভর করে. বুলিয়ান ট্র্যাপগুলি
ট্রেভর ডিকসন

2
ওহ হ্যাঁ ... আমি এই লিঙ্কটি ভুলে গিয়েছিলাম। এটি সত্যই আমাকে এপিআইগুলি কীভাবে কাজ করে তা পুনর্বিবেচনা করতে বাধ্য করেছিল এবং আমি জিনিসগুলি বোবা করার বিষয়টি শিখার পরেও কোডের কয়েকটি টুকরো পুনরায় লিখেছিলাম। ধন্যবাদ!
জেরেমি জে স্টারচার

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

1
আপনি যদি সমস্ত 'কোডিং সেরা অনুশীলনগুলির' বিটের পারফরম্যান্স পরিণতিতে আগ্রহী হন, তবে এখানে উভয় উপায়ে একটি জেসফুল পরীক্ষা করা হয়েছে: jsperf.com/function-blelean-arguments-vs-options-object/10 ছোট্ট পাকটি নোট করুন তৃতীয় বিকল্প, যেখানে আমি একটি 'প্রিসেট' (ধ্রুবক) বিকল্প অবজেক্ট ব্যবহার করি, যা আপনি যখন অনেকগুলি কল করতে পারেন তখনই (আপনার রানটাইমের জীবদ্দশায়, যেমন আপনার ওয়েবপৃষ্ঠায়) একই সেটিংস সহ উন্নয়নের সময় পরিচিত (সংক্ষেপে) বলা যেতে পারে : যখন আপনার বিকল্পের মানগুলি আপনার উত্সকোডে হার্ডকোডযুক্ত থাকে)।
জের হোবল্ট

2
@ শিয়ান সত্যই, আমি কোডিংয়ের এই স্টাইলটি আর ব্যবহার করি না। আমি টাইপস্ক্রিপ্ট এবং নামকরণকৃত পরামিতিগুলির ব্যবহার স্যুইচ করেছি।
জেরেমি জে স্টারচার

28

একাধিক যুক্তি বেশিরভাগ বাধ্যতামূলক পরামিতিগুলির জন্য। তাদের সাথে কোনও ভুল নেই।

আপনার যদি alচ্ছিক প্যারামিটার থাকে তবে এটি জটিল হয়ে যায়। যদি তাদের মধ্যে একটি অন্যের উপর নির্ভর করে, যাতে তাদের একটি নির্দিষ্ট ক্রম থাকে (যেমন চতুর্থটির তৃতীয়টির প্রয়োজন হয়), আপনার এখনও একাধিক যুক্তি ব্যবহার করা উচিত। প্রায় সমস্ত নেটিভ ইকামাস্ক্রিপ্ট এবং ডোম-পদ্ধতিগুলি এ জাতীয়ভাবে কাজ করে। একটি ভাল উদাহরণ openএক্সএমএলএইচটিপিআরকেইস্টের পদ্ধতি , যেখানে শেষ 3 টি যুক্তি alচ্ছিক - নিয়মটি "ব্যবহারকারী ছাড়া কোনও পাসওয়ার্ড নয়" ( এমডিএন ডক্সও দেখুন ) like

দুটি ক্ষেত্রে বিকল্প বিকল্পগুলি কার্যকর হয়:

  • আপনি এতগুলি প্যারামিটার পেয়েছেন যে এটি বিভ্রান্ত হয়ে পড়ে: "নামকরণ" আপনাকে সহায়তা করবে, সেগুলির ক্রম সম্পর্কে আপনাকে চিন্তা করার দরকার নেই (বিশেষত যদি তারা পরিবর্তিত হতে পারে)
  • আপনি alচ্ছিক পরামিতি পেয়েছেন। অবজেক্টগুলি খুব নমনীয় এবং কোনও আদেশ ছাড়াই আপনাকে কেবল আপনার প্রয়োজনীয় জিনিসগুলি এবং অন্য কিছু (বা undefinedগুলি) দিয়ে দেয়।

আপনার ক্ষেত্রে, আমি সুপারিশ করব map(nodeList, callback, options)nodelistএবং callbackপ্রয়োজনীয়, অন্য তিনটি যুক্তি কেবল মাঝে মধ্যে আসে এবং যুক্তিসঙ্গত খেলাপি হয়।

অন্য একটি উদাহরণ JSON.stringify। আপনি spaceকোনও replacerফাংশন পাস না করে প্যারামিটারটি ব্যবহার করতে চাইতে পারেন - তারপরে আপনাকে কল করতে হবে …, null, 4)। একটি আর্গুমেন্ট অবজেক্টটি আরও ভাল হতে পারে, যদিও এটি কেবলমাত্র 2 পরামিতিগুলির জন্য সত্যই যুক্তিসঙ্গত নয়।


@ ট্রেভর-ডিকসনের মতো +1 একই প্রশ্ন: আপনি কি এই মিশ্রণটি অনুশীলনে ব্যবহার করেছেন, উদাহরণস্বরূপ জেএস লাইব্রেরিতে?
ক্রিস্টোফ

একটি উদাহরণ jQuery এর আজাক্স পদ্ধতি হতে পারে । তারা [বাধ্যতামূলক] ইউআরএলটিকে প্রথম যুক্তি হিসাবে এবং দ্বিতীয় হিসাবে একটি বিশাল বিকল্প যুক্তি স্বীকার করে।
বার্গি

খুব অদ্ভুত! আমি এর আগে কখনও লক্ষ্য করিনি। আমি ইউআরএলটিকে একটি বিকল্প সম্পত্তি হিসাবে সর্বদা ব্যবহারে দেখেছি ...
ক্রিস্টোফ

হ্যাঁ, jQuery পিছনের দিকে সামঞ্জস্যপূর্ণ থাকার সময় তার
optionচ্ছিক

1
আমার মতে, এটি এখানে একমাত্র বুদ্ধিমান উত্তর।
বেনিয়ামিন গ্রুয়েনবাউম

11

'অবজেক্ট হিসাবে অপশন' ব্যবহার করা সবচেয়ে ভাল হতে চলেছে। আপনাকে বৈশিষ্ট্যগুলির ক্রম সম্পর্কে চিন্তা করার দরকার নেই এবং ডেটা পাস হওয়ার ক্ষেত্রে আরও নমনীয়তা রয়েছে (উদাহরণস্বরূপ optionচ্ছিক পরামিতি)

কোনও বস্তু তৈরির অর্থ হ'ল বিকল্পগুলি সহজেই একাধিক ফাংশনে ব্যবহার করা যেতে পারে:

options={
    nodeList:...,
    callback:...,
    thisObject:...,
    fromIndex:...,
    toIndex:...
}

function1(options){
    alert(options.nodeList);
}

function2(options){
    alert(options.fromIndex);
}

এখানে (যুক্তিসঙ্গত) অনুমানটি হ'ল বস্তুর সর্বদা একই কী জোড়া থাকবে। আপনি যদি ক্রেপ / বেমানান এপিআই নিয়ে কাজ করছেন তবে আপনার নিজের হাতে অন্যরকম সমস্যা রয়েছে।
ব্যাকডেস্ক

9

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

কিছু ক্ষেত্রে, উভয় ব্যবহার করা ভাল। আপনার ফাংশনে যদি এক বা দুটি প্রয়োজনীয় প্যারামিটার এবং optionচ্ছিক একগুচ্ছ থাকে তবে প্রথম দুটি প্যারামিটার প্রয়োজনীয় এবং তৃতীয়টি একটি alচ্ছিক বিকল্প হ্যাশ তৈরি করুন।

আপনার উদাহরণে, আমি করব map(nodeList, callback, options)। নোডলিস্ট এবং কলব্যাকের প্রয়োজন, কেবল এটির কল পড়ে কী ঘটছে তা বলা মোটামুটি সহজ, এবং এটি বিদ্যমান মানচিত্রের ফাংশনের মতো। অন্য কোনও বিকল্প চ্ছিক তৃতীয় প্যারামিটার হিসাবে পাস করা যেতে পারে।


+1 আকর্ষণীয়। আপনি কি ব্যবহারের ক্ষেত্রে এটি ব্যবহার করে দেখেছেন, উদাহরণস্বরূপ জেএস লাইব্রেরিতে?
ক্রিস্টোফ

7

প্রশ্নে আপনার মন্তব্য:

আমার উদাহরণে শেষ তিনটি alচ্ছিক।

তাহলে কেন এটি করবেন না? (দ্রষ্টব্য: এই JavaScript মোটামুটি কাঁচা সাধারণত আমি ব্যবহার করতে চাই। defaultহ্যাশ এবং বিকল্প ব্যবহার করে পাস সঙ্গে এটি আপডেট Object.extend বা JQuery.extend বা অনুরূপ ..)

function map(nodeList, callback, options) {
   options = options || {};
   var thisObject = options.thisObject || {};
   var fromIndex = options.fromIndex || 0;
   var toIndex = options.toIndex || 0;
}

সুতরাং, এখন যেহেতু এটি এখন আরও বেশি স্পষ্ট যা alচ্ছিক এবং কোনটি নয়, এইগুলি ফাংশনের বৈধ ব্যবহারসমূহ:

map(nodeList, callback);
map(nodeList, callback, {});
map(nodeList, callback, null);
map(nodeList, callback, {
   thisObject: {some: 'object'},
});
map(nodeList, callback, {
   toIndex: 100,
});
map(nodeList, callback, {
   thisObject: {some: 'object'},
   fromIndex: 0,
   toIndex: 100,
});

এটি @ ট্রেভর-ডিকসনের উত্তরের অনুরূপ।
ক্রিস্টোফ

5

আমি এই প্রতিক্রিয়াটি নিয়ে পার্টিতে কিছুটা দেরি করতে পারি, তবে আমি এই বিষয়টিতে অন্যান্য বিকাশকারীদের মতামত অনুসন্ধান করে এই থ্রেডটি পেয়েছিলাম।

আমি বেশিরভাগ প্রতিক্রিয়াকারীদের সাথে এবং 'একাধিক যুক্তি' পদ্ধতির সাথে একমত নই। আমার মূল যুক্তিটি হ'ল এটি অন্যান্য বিরোধী-নিদর্শনগুলিকে যেমন "পরম অবজেক্টটি পরিবর্তন এবং ফিরিয়ে আনতে", বা "একই প্যারাম অবজেক্টটিকে অন্য ক্রিয়াকলাপগুলিতে প্রেরণ করা" যেমন নিরুত্সাহিত করে। আমি কোডবেসে কাজ করেছি যা এই অ্যান্টি-প্যাটার্নটির ব্যাপকভাবে অপব্যবহার করেছে এবং এটির ফলে ডিবাগিং কোডটি দ্রুত অসম্ভব হয়ে যায়। আমি মনে করি এটি থাম্বের একটি খুব জাভাস্ক্রিপ্ট-নির্দিষ্ট নিয়ম, যেহেতু জাভাস্ক্রিপ্টটি দৃ strongly়ভাবে টাইপ করা হয়নি এবং এ জাতীয় নির্বিচারে কাঠামোগত অবজেক্টের জন্য অনুমতি দেয়।

আমার ব্যক্তিগত মতামতটি হল যে ফাংশনগুলি কল করার সময় বিকাশকারীদের স্পষ্ট হওয়া উচিত, রিলানড্যান্ট ডেটা ঘুরিয়ে এড়ানো এবং সংশোধন-দ্বারা-রেফারেন্স এড়ানো উচিত। এমন নয় যে এই নিদর্শনগুলি সংক্ষিপ্ত, সঠিক কোড লেখার আগে। আমি কেবল অনুভব করি যে এটি আপনার প্রকল্পের খারাপ উন্নয়নের চর্চায় পড়ে যাওয়া আরও সহজ করে তোলে।

নিম্নলিখিত ভয়ানক কোড বিবেচনা করুন:

function main() {
    const x = foo({
        param1: "something",
        param2: "something else",
        param3: "more variables"
    });

    return x;
}

function foo(params) {
    params.param1 = "Something new";
    bar(params);
    return params;
}


function bar(params) {
    params.param2 = "Something else entirely";
    const y = baz(params);
    return params.param2;
}

function baz(params) {
    params.params3 = "Changed my mind";
    return params;
}

অভিপ্রায় নির্দিষ্ট করার জন্য এই জাতীয় ধরণের আরও সুস্পষ্ট ডকুমেন্টেশন প্রয়োজন হয় না, তবে এটি অস্পষ্ট ত্রুটির জন্যও জায়গা ছেড়ে দেয়। কি হবে যদি একজন বিকাশকারী মডিফাই param1মধ্যে bar()? আপনি এটি কতটা সময় ধরে পর্যাপ্ত আকারের কোডবেসটি দেখবেন বলে মনে করেন? স্বীকার করা যায় যে, এটি উদাহরণটি কিছুটা স্বল্পমাত্রার কারণ এটি ধরে নিয়েছে যে বিকাশকারীরা ইতিমধ্যে এই পয়েন্টটি দ্বারা বেশ কয়েকটি বিরোধী-নিদর্শন প্রতিশ্রুতিবদ্ধ। তবে এটি দেখায় যে কীভাবে পরামিতিগুলি ধারণ করে এমন বস্তুগুলি ত্রুটি এবং অস্পষ্টতার জন্য বৃহত্তর কক্ষকে মঞ্জুরি দেয়, যার জন্য বৃহত্তর ডিগ্রি প্রয়োজন আন্তরিকতা এবং দৃ const়তার যথাযথতা পালন করা।

ইস্যুতে আমার দু-সেন্ট!


3

এটা নির্ভর করে.

এই জনপ্রিয় লাইব্রেরি ডিজাইনের উপর আমার পর্যবেক্ষণের ভিত্তিতে, আমাদের বিকল্প বিকল্পটি ব্যবহার করা উচিত এমন দৃশ্যপট এখানে দেওয়া হয়েছে:

  • প্যারামিটারের তালিকাটি দীর্ঘ (> 4)।
  • কিছু বা সমস্ত পরামিতি optionচ্ছিক এবং তারা একটি নির্দিষ্ট ক্রমের উপর নির্ভর করে না।
  • প্যারামিটার তালিকাটি ভবিষ্যতের এপিআই আপডেটে বাড়তে পারে।
  • অন্যান্য কোড থেকে এপিআই কল করা হবে এবং প্যারামিটারগুলির অর্থ বলার জন্য এপিআই নামটি যথেষ্ট পরিষ্কার নয়। সুতরাং এটি পঠনযোগ্যতার জন্য শক্তিশালী প্যারামিটার নামের প্রয়োজন হতে পারে।

এবং পরামিতি তালিকা ব্যবহার করার জন্য পরিস্থিতি:

  • প্যারামিটার তালিকা সংক্ষিপ্ত (<= 4)।
  • বেশিরভাগ বা সমস্ত পরামিতি প্রয়োজনীয়।
  • Ptionচ্ছিক পরামিতি একটি নির্দিষ্ট ক্রমে are (যেমন: $ .get)
  • এপিআই নামের দ্বারা পরামিতিগুলির অর্থ বলা সহজ।

2

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


1

এমন কোনও ফাংশনের জন্য যা সাধারণত কিছু পূর্বনির্ধারিত যুক্তি ব্যবহার করে আপনি ভাল বিকল্প বিকল্পটি ব্যবহার করবেন। বিপরীত উদাহরণটি কোনও ফাংশনের মতো এমন কিছু হবে যা অসীম সংখ্যক আর্গুমেন্ট পাচ্ছে যেমন: সেটসিএসএস ({উচ্চতা: 100}, {প্রস্থ: 200}, {পটভূমি: "# 000"।)।


0

আমি বড় জাভাস্ক্রিপ্ট প্রকল্প দেখতে হবে।

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

আপনার যদি ডিফল্ট আর্গুমেন্ট বা alচ্ছিক যুক্তিগুলির প্রয়োজন হয় তবে কোনও জিনিস সম্ভবত আরও ভাল হবে কারণ এটি আরও নমনীয়। তবে আপনি যদি স্বাভাবিক ক্রিয়ামূলক যুক্তিগুলি না করেন তবে আরও স্পষ্ট।

জাভাস্ক্রিপ্ট একটি argumentsঅবজেক্ট আছে। https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Functions_and_function_scope/arguments

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