জাভাস্ক্রিপ্টে ফাংশন ওভারলোডিং - সেরা অনুশীলন


782

জাভাস্ক্রিপ্টে জাল ফাংশন ওভারলোডিংয়ের সর্বোত্তম উপায় (গুলি) কী?

আমি জানি যে অন্যান্য ভাষার মতো জাভাস্ক্রিপ্টে ওভারলোড করা সম্ভব নয় to আমার যদি দুটি ব্যবহারের সাথে একটি ক্রিয়াকলাপের প্রয়োজন হয় foo(x)এবং foo(x,y,z)এটি সর্বোত্তম / পছন্দসই উপায়:

  1. প্রথম স্থানে বিভিন্ন নাম ব্যবহার করা
  2. Optionচ্ছিক যুক্তি ব্যবহার করে y = y || 'default'
  3. যুক্তি সংখ্যা ব্যবহার করে
  4. ধরণের যুক্তি পরীক্ষা করা হচ্ছে
  5. আর কীভাবে?

14
সম্ভবত আপনি কেন মনে করেন আপনার কেন শুরু করতে ফাংশন ওভারলোডিং প্রয়োজন ask আমি মনে করি এটি আমাদের একটি বাস্তব সমাধানের আরও কাছে পাবে।
ব্রেটন

1
এটি বন্ধ আছে, তবে আমি নিম্নলিখিতগুলি করছি: this.selectBy = {উদাহরণস্বরূপ: selectByInstance, // ফাংশন পাঠ্য: সিলেক্ট বাইটেক্সট, // ফাংশন মান: নির্বাচনবাইভ্যালু // ফাংশন};
বন্দী

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

2
কেবলমাত্র এটি কার্যকর হলে, আমি একটি হালকা জেএস ফ্রেমওয়ার্ক তৈরি করেছি যা টাইপ-ভিত্তিক পদ্ধতি ওভারলোডিংয়ের অনুমতি দেয় allows অবশ্যই একই সতর্কতাগুলি পারফরম্যান্সের সাথে প্রযোজ্য, তবে এটি এখন পর্যন্ত আমার প্রয়োজনের জন্য ভালভাবে কাজ করেছে এবং এখনও উন্নতির জন্য অনেকটা জায়গা রয়েছে: ব্লগ.প্রেব্লব.কম
.২০

উত্তর:


602

পরামিতিগুলির সাথে ফাংশন ওভারলোডিং করার সর্বোত্তম উপায়টি আর্গুমেন্টের দৈর্ঘ্য বা প্রকারগুলি পরীক্ষা করা নয়; প্রকারগুলি পরীক্ষা করা আপনার কোডটিকে ধীর করে দেবে এবং আপনার অ্যারে, নালস, অবজেক্টস ইত্যাদির মজা পাবেন have

বেশিরভাগ বিকাশকারীরা যা করেন তা হ'ল কোনও বিষয়কে তাদের পদ্ধতির সর্বশেষ যুক্তি হিসাবে দেখান। এই অবজেক্টটি যে কোনও কিছু রাখতে পারে।

function foo(a, b, opts) {
  // ...
  if (opts['test']) { } //if test param exists, do something.. 
}


foo(1, 2, {"method":"add"});
foo(3, 4, {"test":"equals", "bar":"tree"});

তারপরে আপনি নিজের পদ্ধতিতে যেকোনভাবে এটি পরিচালনা করতে পারেন। [স্যুইচ করুন, অন্যথায় ইত্যাদি]


43
আপনি foo () এর একটি নমুনা বাস্তবায়ন সরবরাহ করতে পারবেন যা এই "অপ্টস" পরামিতিগুলি কীভাবে ব্যবহৃত / রেফারেন্স করে তা বোঝায়?
মো হাওয়ার্ড

24
মো // এটি এমন হতে পারে; if(opts['test']) //if test param exists, do something.. if(opts['bar']) //if bar param exists, do something
ডেকার্ড

80
এটি ফাংশন ওভারলোডিং নয়। ফাংশন ওভারলোডিং একই নাম কিন্তু পৃথক পরামিতি সহ দুটি পৃথক ফাংশন করে। আপনি যা বর্ণনা করছেন তা হ'ল শেষে একটি অবজেক্ট আর্গুমেন্টের সাথে একটি ফাংশন।
d512

66
@ ব্যবহারকারী 1334007 আপনি জাভা / .NET এ যেমন করতেন তেমন ফাংশন ওভারলোডিং করা অসম্ভব। হ্যাঁ এটি "হুবহু" ওভারলোডিং নয়, তবে এটি কাজটি করে।
এপাসকারেলো

18
আমি অবাক হয়েছি কেউ ইতিমধ্যে এটি জিজ্ঞাসা করেনি: চেক arguments.lengthকরার পরামর্শ দেওয়া হচ্ছে না কেন ? এছাড়াও, আমি এখানে আগে এসেছি এবং বেশিরভাগ বিকাশকারীরা যা করেন তা হ'ল ... তবে আমি নিশ্চিত যে এটিই আমি দেখেছি done এই পদ্ধতিটি 'ওভারলোডস' থাকার সিনট্যাকটিক মিষ্টতাও নষ্ট করে!
c24w

169

আমি প্রায়শই এটি করি:

সি #:

public string CatStrings(string p1)                  {return p1;}
public string CatStrings(string p1, int p2)          {return p1+p2.ToString();}
public string CatStrings(string p1, int p2, bool p3) {return p1+p2.ToString()+p3.ToString();}

CatStrings("one");        // result = one
CatStrings("one",2);      // result = one2
CatStrings("one",2,true); // result = one2true

জাভাস্ক্রিপ্ট সমতুল্য:

function CatStrings(p1, p2, p3)
{
  var s = p1;
  if(typeof p2 !== "undefined") {s += p2;}
  if(typeof p3 !== "undefined") {s += p3;}
  return s;
};

CatStrings("one");        // result = one
CatStrings("one",2);      // result = one2
CatStrings("one",2,true); // result = one2true

এই নির্দিষ্ট উদাহরণটি আসলে জাভাস্ক্রিপ্টে সি # এর চেয়ে আরও মার্জিত। নির্দিষ্ট করা হয়নি এমন প্যারামিটারগুলি জাভাস্ক্রিপ্টে 'অপরিজ্ঞাত', যা যদি বিবৃতিতে মিথ্যাকে মূল্যায়ন করে। তবে, ফাংশন সংজ্ঞাটি সেই তথ্য সরবরাহ করে না যা p2 এবং p3 optionচ্ছিক। আপনার যদি প্রচুর ওভারলোডিংয়ের প্রয়োজন হয়, jQuery প্যারামিটার হিসাবে কোনও অবজেক্ট ব্যবহার করার সিদ্ধান্ত নিয়েছে, উদাহরণস্বরূপ, jQuery.ajax (বিকল্পগুলি)। আমি তাদের সাথে একমত হই যে ওভারলোডিংয়ের ক্ষেত্রে এটি সর্বাধিক শক্তিশালী এবং স্পষ্টতই ডকুমেন্টেবল পদ্ধতি, তবে আমার খুব কমই এক বা দুটি দ্রুত alচ্ছিক পরামিতিগুলির প্রয়োজন।

সম্পাদনা: আইনের পরামর্শ অনুযায়ী পরীক্ষার পরিবর্তন হয়েছে


16
নির্দিষ্ট করা হয়নি এমন প্যারামিটারগুলি undefinedজেএসে রয়েছে, নেই null। সেরা অনুশীলন হিসাবে, আপনার কখনই কোনও কিছু সেট undefinedকরা উচিত নয়, যতক্ষণ না আপনি নিজের পরীক্ষা পরিবর্তন করেন ততক্ষণ এটি কোনও সমস্যা হওয়া উচিত নয় p2 === undefined
তামজিন ব্লেক

3
আপনি যদি falseসর্বশেষ যুক্তি হিসাবে পাস করেন তবে এটি "false"শেষের সাথে যুক্ত if(p3)হবে না কারণ শাখা হবে না।
ড্রিমলাক্স

5
কেবলমাত্র একটি দ্রষ্টব্য নোট, আপনার typeof p2 === "undefined"সম্ভবত আপনি উদাহরণের উদাহরণে যা প্রত্যাশা করছেন তার বিপরীত, আমি মনে করি typeof p2 !== "undefined"আপনি যা ইচ্ছা করেছিলেন এটি। এছাড়াও, আমি আপনাকে স্ট্রিং, সংখ্যা এবং আপনি যে বুলিয়ানটি করতে চান তা p2 === "number"; p3 === "boolean"
হ'ল বলে পরামর্শ দিতে

8
আমি এটি করতে পছন্দ করি: পি 3 = পি 3 || 'ডিফল্ট মান';
ডোরিয়ান

3
এর অর্থ কী ===এবং !==? কেন শুধু ব্যবহার করবেন না ==এবং !=?
রিকার্ডো ক্রুজ

76

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


1
জন রেসিগ (jQuery এর) একবার এটি চেষ্টা করেছিলেন, তবে চেষ্টাটি নিখুঁতভাবে একাডেমিক ছিল এবং কোনও আসল সুবিধা দেয় নি।
স্কানলিফ


@ টেরেন্স: আমি রেসিগের পদ্ধতিটিও পছন্দ করি। ইহা যাদুর মত কাজ করে। ব্যবহারের ক্ষেত্রে বৈধতা পাওয়ার জন্য এর জন্য কেবল একটি পরীক্ষা তৈরির উপায় খুঁজে বের করতে হবে।
ক্রিসভিলানুয়েভা

"এই ফাংশনটি বিশ্বকে পরিবর্তন করবে না, তবে এটি সংক্ষিপ্ত, সংক্ষিপ্ত এবং একটি অস্পষ্ট জাভাস্ক্রিপ্ট বৈশিষ্ট্য ব্যবহার করেছে - সুতরাং এটি আমার বইয়ে জিতবে" " :-)
ফ্রিরিচ রাবাব

66

সঠিক উত্তরটি হ'ল জাভাস্ক্রিপ্টে ওভারলোড করা হচ্ছে না।

ফাংশনটির ভিতরে চেকিং / স্যুইচিং ওভারভারডিং নয়।

ওভারলোডিংয়ের ধারণা: কিছু প্রোগ্রামিং ভাষায়, ফাংশন ওভারলোডিং বা পদ্ধতি ওভারলোডিং হ'ল বিভিন্ন বাস্তবায়ন সহ একই নামের একাধিক পদ্ধতি তৈরি করার ক্ষমতা। একটি ওভারলোডেড ফাংশনে কলগুলি কলটির প্রসঙ্গে উপযুক্ত সেই ফাংশনটির একটি নির্দিষ্ট বাস্তবায়ন পরিচালনা করবে, যা একটি ফাংশন কলকে প্রসঙ্গে নির্ভর করে বিভিন্ন কার্য সম্পাদন করতে দেয়।

উদাহরণস্বরূপ, doTask () এবং doTask (অবজেক্ট O) ওভারলোডেড পদ্ধতি। পরেরটিকে কল করতে কোনও বস্তুকে অবশ্যই প্যারামিটার হিসাবে পাস করতে হবে, যদিও পূর্বেরটির জন্য প্যারামিটারের প্রয়োজন হয় না এবং খালি প্যারামিটার ক্ষেত্রের সাথে ডাকা হয়। একটি সাধারণ ত্রুটি হ'ল দ্বিতীয় পদ্ধতিতে অবজেক্টটির জন্য একটি ডিফল্ট মান নির্ধারণ করা হয়, যার ফলস্বরূপ একটি অস্পষ্ট কল ত্রুটি হতে পারে, কারণ সংকলকটি দুটি পদ্ধতির মধ্যে কোনটি ব্যবহার করবেন তা জানত না।

https://en.wikipedia.org/wiki/Function_overloading

সমস্ত প্রস্তাবিত বাস্তবায়ন দুর্দান্ত, তবে সত্যি বলতে গেলে জাভাস্ক্রিপ্টের জন্য কোনও নেটিভ বাস্তবায়ন নেই।


4
অবশেষে একটি সাধারণ উত্তর! জাভাস্ক্রিপ্টে ওভারভারলোড হচ্ছে না।
রাজ্জওয়ান টিউডরিকা

4
ওপি জাল ওভারলোডিংয়ের উপায় চেয়েছিল ।
আটার গেমস

যেমনটি আমি আগে বলেছিলাম, আমরা এখানে মানুষকে শিক্ষিত করছি, তারা যা জিজ্ঞাসা করছে তা সঠিক কিনা তা যাচাই না করে আমরা কেবল তাদের জবাব দেই না।
মার্কো

27

আপনি আরও ভাল দুটি উপায় যেতে পারেন:

  1. যদি আপনি প্রচুর নমনীয়তা ছেড়ে যেতে চান তবে একটি অভিধান (এসোসিয়েটিভ অ্যারে) পাস করুন

  2. যুক্তি হিসাবে কোনও বস্তু নিন এবং নমনীয়তা যুক্ত করতে প্রোটোটাইপ ভিত্তিক উত্তরাধিকার ব্যবহার করুন।


1
এটি আমার প্রাথমিক চিন্তা ছিল, তবে আপনি যে ফাংশনটি তৈরি করছেন তা যদি কোনও লাইব্রেরিতে বা অন্যের দ্বারা ব্যবহৃত হয় তবে মানগুলি স্পষ্টভাবে গণ্য করা সহায়ক হতে পারে
রবার্থথিংগার

19

নীচে দেখানো প্যারামিটার ধরণের সাহায্যে বাস্তব পদ্ধতি ওভারলোডিংয়ের মঞ্জুরি দেয় এমন একটি পদ্ধতির এখানে রয়েছে:

Func(new Point());
Func(new Dimension());
Func(new Dimension(), new Point());
Func(0, 0, 0, 0);

সম্পাদনা (2018) : যেহেতু এটি ২০১১ সালে লেখা হয়েছিল, সরাসরি পদ্ধতি কলগুলির গতি প্রচুর পরিমাণে বৃদ্ধি পেয়েছে যখন ওভারলোডেড পদ্ধতির গতি হয় নি।

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


এখানে বিভিন্ন পদ্ধতির একটি মাপদণ্ড রয়েছে - https://jsperf.com/function-overloading । এটি দেখায় যে ফাংশন ওভারলোডিং (অ্যাকাউন্টে প্রকার গ্রহণ করা) গুগল ক্রোমের ভি 8 -তে 16.0 (বিটা) হিসাবে প্রায় 13 গুণ কম হতে পারে

পাশাপাশি কোনও বস্তুর পাস (যেমন) {x: 0, y: 0} ) উপযুক্ত অনুসারে সিটির পদ্ধতির নামকরণও করা যায় one উদাহরণস্বরূপ, ভেক্টর.এডডভেেক্টর (ভেক্টর), ভেক্টর.এডডিন্টিজার্স (এক্স, ওয়াই, জেড, ...) এবং ভেক্টর.এডড্রে (পূর্ণসংখ্যা) ray নামকরণের অনুপ্রেরণার জন্য আপনি সি লাইব্রেরিগুলিতে যেমন ওপেনজিএল দেখতে পারেন।

সম্পাদনা : আমি কোনও বস্তু পাস করার জন্য 'param' in argএবং উভয় ব্যবহার করে অবজেক্টটির জন্য পরীক্ষার জন্য একটি মানদণ্ড যুক্ত করেছিarg.hasOwnProperty('param') , এবং ফাংশন ওভারলোডিং অনেক (অন্তত এই বেঞ্চমার্ক নেই) একটি বস্তু এবং বৈশিষ্ট্যের জন্য পরীক্ষণ ক্ষণস্থায়ী তুলনায় দ্রুততর।

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

আমার উদাহরণটি একটি আয়তক্ষেত্র বাস্তবায়ন থেকে আসে - সুতরাং মাত্রা এবং পয়েন্টের উল্লেখ। সম্ভবত আয়তক্ষেত্র একটি যোগ করতে পারিনি GetRectangle()করার পদ্ধতি Dimensionএবং Pointপ্রোটোটাইপ, এবং তারপর ফাংশন ইস্যু ওভারলোডিং বাছাই হয়। আর আদিমদের সম্পর্কে কী? ঠিক আছে, আমাদের আর্গুমেন্টের দৈর্ঘ্য রয়েছে, যা এখন বৈধ পরীক্ষা হিসাবে বস্তুর একটি GetRectangle()পদ্ধতি রয়েছে।

function Dimension() {}
function Point() {}

var Util = {};

Util.Redirect = function (args, func) {
  'use strict';
  var REDIRECT_ARGUMENT_COUNT = 2;

  if(arguments.length - REDIRECT_ARGUMENT_COUNT !== args.length) {
    return null;
  }

  for(var i = REDIRECT_ARGUMENT_COUNT; i < arguments.length; ++i) {
    var argsIndex = i-REDIRECT_ARGUMENT_COUNT;
    var currentArgument = args[argsIndex];
    var currentType = arguments[i];
    if(typeof(currentType) === 'object') {
      currentType = currentType.constructor;
    }
    if(typeof(currentType) === 'number') {
      currentType = 'number';
    }
    if(typeof(currentType) === 'string' && currentType === '') {
      currentType = 'string';
    }
    if(typeof(currentType) === 'function') {
      if(!(currentArgument instanceof currentType)) {
        return null;
      }
    } else {
      if(typeof(currentArgument) !== currentType) {
        return null;
      }
    } 
  }
  return [func.apply(this, args)];
}

function FuncPoint(point) {}
function FuncDimension(dimension) {}
function FuncDimensionPoint(dimension, point) {}
function FuncXYWidthHeight(x, y, width, height) { }

function Func() {
  Util.Redirect(arguments, FuncPoint, Point);
  Util.Redirect(arguments, FuncDimension, Dimension);
  Util.Redirect(arguments, FuncDimensionPoint, Dimension, Point);
  Util.Redirect(arguments, FuncXYWidthHeight, 0, 0, 0, 0);
}

Func(new Point());
Func(new Dimension());
Func(new Dimension(), new Point());
Func(0, 0, 0, 0);

16

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

  1. Y = y || এর মতো alচ্ছিক আর্গুমেন্ট ব্যবহার করা 'ডিফল্ট'. আপনি এটি করতে পারলে এটি সুবিধাজনক, তবে এটি সর্বদা ব্যবহারিকভাবে কাজ নাও করতে পারে, উদাহরণস্বরূপ যখন 0 / নাল / অপরিজ্ঞাত কোনও বৈধ যুক্তি হতে পারে।

  2. যুক্তি সংখ্যা ব্যবহার করে। শেষ বিকল্পের মতো তবে # 1 কাজ না করলে কাজ করতে পারে।

  3. ধরণের যুক্তি পরীক্ষা করা হচ্ছে। এটি এমন কিছু ক্ষেত্রে কাজ করতে পারে যেখানে আর্গুমেন্টের সংখ্যা একই। আপনি নির্ভরযোগ্যভাবে প্রকারগুলি নির্ধারণ করতে না পারলে আপনাকে বিভিন্ন নাম ব্যবহার করতে হতে পারে।

  4. প্রথম স্থানে বিভিন্ন নাম ব্যবহার করা। অন্য বিকল্পগুলি কার্যকর না হলে, ব্যবহারিক না হলে বা অন্যান্য সম্পর্কিত ফাংশনগুলির সাথে সামঞ্জস্যের জন্য আপনাকে এটি করার দরকার হতে পারে।


14

আমার যদি দুটি ব্যবহার ফু (এক্স) এবং ফু (এক্স, ওয়াই, জেড) এর সাথে একটি ফাংশন প্রয়োজন তবে সবচেয়ে ভাল / পছন্দের উপায়?

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

আমার মনে হয় যে উপায়টি বেশিরভাগ ক্ষেত্রে উপযুক্ত follows

বলুন আপনার পদ্ধতি আছে

function foo(x)
{
} 

জাভাস্ক্রিপ্টে সম্ভব না ওভারলোডিং পদ্ধতির পরিবর্তে আপনি একটি নতুন পদ্ধতি সংজ্ঞায়িত করতে পারেন

fooNew(x,y,z)
{
}

এবং তারপরে নিম্নলিখিত 1 তম কার্যটি সংশোধন করুন -

function foo(arguments)
{
  if(arguments.length==2)
  {
     return fooNew(arguments[0],  arguments[1]);
  }
} 

আপনার যদি এমন অনেক ওভারলোডেড পদ্ধতি switchথাকে তবে কেবল if-elseবিবৃতি ব্যবহারের চেয়ে বিবেচনা করুন ।

( আরও বিশদ )

PS: উপরের লিঙ্কটিতে আমার ব্যক্তিগত ব্লগে অতিরিক্ত বিবরণ রয়েছে।


9

আমি সেরা অনুশীলন সম্পর্কে নিশ্চিত নই, তবে আমি এটি কীভাবে করব তা এখানে:

/*
 * Object Constructor
 */
var foo = function(x) {
    this.x = x;
};

/*
 * Object Protoype
 */
foo.prototype = {
    /*
     * f is the name that is going to be used to call the various overloaded versions
     */
    f: function() {

        /*
         * Save 'this' in order to use it inside the overloaded functions
         * because there 'this' has a different meaning.
         */   
        var that = this;  

        /* 
         * Define three overloaded functions
         */
        var f1 = function(arg1) {
            console.log("f1 called with " + arg1);
            return arg1 + that.x;
        }

        var f2 = function(arg1, arg2) {
             console.log("f2 called with " + arg1 + " and " + arg2);
             return arg1 + arg2 + that.x;
        }

        var f3 = function(arg1) {
             console.log("f3 called with [" + arg1[0] + ", " + arg1[1] + "]");
             return arg1[0] + arg1[1];
        }

        /*
         * Use the arguments array-like object to decide which function to execute when calling f(...)
         */
        if (arguments.length === 1 && !Array.isArray(arguments[0])) {
            return f1(arguments[0]);
        } else if (arguments.length === 2) {
            return f2(arguments[0], arguments[1]);
        } else if (arguments.length === 1 && Array.isArray(arguments[0])) {
            return f3(arguments[0]);
        }
    } 
}

/* 
 * Instantiate an object
 */
var obj = new foo("z");

/*
 * Call the overloaded functions using f(...)
 */
console.log(obj.f("x"));         // executes f1, returns "xz"
console.log(obj.f("x", "y"));    // executes f2, returns "xyz"
console.log(obj.f(["x", "y"]));  // executes f3, returns "xy"

2
@ লুইস: আমি কিছু আশাবাদী সহায়ক মন্তব্য যুক্ত করেছি।
দাবাবেগ

6

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

TEST = {};

TEST.multiFn = function(){
    // function map for our overloads
    var fnMap = {};

    fnMap[0] = function(){
        console.log("nothing here");
        return this;    //    support chaining
    }

    fnMap[1] = function(arg1){
        //    CODE here...
        console.log("1 arg: "+arg1);
        return this;
    };

    fnMap[2] = function(arg1, arg2){
        //    CODE here...
        console.log("2 args: "+arg1+", "+arg2);
        return this;
    };

    fnMap[3] = function(arg1,arg2,arg3){
        //    CODE here...
        console.log("3 args: "+arg1+", "+arg2+", "+arg3);
        return this;
    };

    console.log("multiFn is now initialized");

    //    redefine the function using the fnMap in the closure
    this.multiFn = function(){
        fnMap[arguments.length].apply(this, arguments);
        return this;
    };

    //    call the function since this code will only run once
    this.multiFn.apply(this, arguments);

    return this;    
};

এটা পরীক্ষা করো.

TEST.multiFn("0")
    .multiFn()
    .multiFn("0","1","2");

5

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

    function optionsObjectTest(x, y, opts) {
        opts = opts || {}; // default to an empty options object

        var stringValue = opts.stringValue || "string default value";
        var boolValue = !!opts.boolValue; // coerces value to boolean with a double negation pattern
        var numericValue = opts.numericValue === undefined ? 123 : opts.numericValue;

        return "{x:" + x + ", y:" + y + ", stringValue:'" + stringValue + "', boolValue:" + boolValue + ", numericValue:" + numericValue + "}";

}

বিকল্পগুলির অবজেক্টটি কীভাবে ব্যবহার করতে হয় তার একটি উদাহরণ এখানে


4

জাভাস্ক্রিপ্টে ওভারলোডিংয়ের কোনও উপায় নেই। সুতরাং, আমি typeof()নকল ওভারলোডিংয়ের একাধিক ফাংশনের পরিবর্তে পদ্ধতি অনুসারে নীচের মতো প্রস্তাব দিই ।

function multiTypeFunc(param)
{
    if(typeof param == 'string') {
        alert("I got a string type parameter!!");
     }else if(typeof param == 'number') {
        alert("I got a number type parameter!!");
     }else if(typeof param == 'boolean') {
        alert("I got a boolean type parameter!!");
     }else if(typeof param == 'object') {
        alert("I got a object type parameter!!");
     }else{
        alert("error : the parameter is undefined or null!!");
     }
}

শুভকামনা!


24
আল্লার দোহাই! একটি সুইচ বিবৃতি ব্যবহার করুন!
jedmao

8
এছাড়াও, আপনি যদি স্যুইচ ব্যবহার না করার জন্য জিদ করেন তবে আপনার একবার টাইপফোন একবার কল করা উচিত। var type = typeof param; if (type === 'string') ...
ওয়াল্টার স্ট্যাবোজ

"===" "এর জন্য মন্তব্য করতে +1। যদি (... == ...) এটি টাইপ-সেফ হয় তবে স্যুইচ স্টেটমেন্টের অন্য সুবিধা।
নাথান কুপার

4

সূচনা

এখন পর্যন্ত এতগুলি উত্তর পড়ে যে কারও মাথা ব্যথা হবে। যে কেউ ধারণাটি জানার চেষ্টা করছেন তাদের নীচের পূর্বশর্তগুলি জানতে হবে ।

Function overloading Definition, Function Length property,Function argument property

Function overloadingএর সহজতম ফর্মটির অর্থ একটি ফাংশন এতে যুক্ত হওয়া যুক্তির সংখ্যার ভিত্তিতে বিভিন্ন কার্য সম্পাদন করে। উল্লেখযোগ্যভাবে TASK1, TASK2 এবং TASK3 নীচে হাইলাইট করা argumentsহয়েছে এবং একই ফাংশনে পাসের সংখ্যার ভিত্তিতে সঞ্চালিত হচ্ছে fooYo

// if we have a function defined below
function fooYo(){
     // do something here
}
// on invoking fooYo with different number of arguments it should be capable to do different things

fooYo();  // does TASK1
fooYo('sagar'); // does TASK2
fooYo('sagar','munjal'); // does TAKS3

দ্রষ্টব্য - জেএস ফাংশন ওভারলোডিংয়ের অন্তর্নির্মিত ক্ষমতা সরবরাহ করে না।

বিকল্প

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

নীচের কোডটি ব্যবহার করে if-elseবা switchবিবৃতি দিয়ে সোজাসাপ্টা কিন্তু নিষ্পাপ পদ্ধতির ব্যবহার করে ।

  • argument-lengthসম্পত্তি মূল্যায়ন ।
  • বিভিন্ন মান বিভিন্ন ফাংশন ডাকে ফলাফল।

var ninja = {
  whatever: function() {
       switch (arguments.length) {
         case 0:
           /* do something */
           break;
         case 1:
           /* do something else */
           break;
         case 2:
           /* do yet something else */
           break;
       //and so on ...
    } 
  }
}

অন্য কৌশলটি আরও বেশি পরিচ্ছন্ন এবং গতিশীল। এই কৌশলটির হাইলাইটটি হ'ল addMethodজেনেরিক ফাংশন।

  • আমরা একটি ফাংশন সংজ্ঞায়িত করি addMethodযা একই নামের সাথে আলাদা আলাদা ফাংশন যুক্ত করতে ব্যবহৃত হয় তবে বিভিন্ন কার্যকারিতা

  • addMethodফাংশনটির নীচে তিনটি প্যারামের অবজেক্টের নাম object, ফাংশনের নাম nameএবং যে ফাংশনটি আমরা প্রার্থনা করতে চাই তা গ্রহণ করে fn

  • অভ্যন্তরীণ addMethodসংজ্ঞাটি ক্লোজারের সাহায্যে var oldপূর্ববর্তী রেফারেন্স functionসঞ্চয় করে - একটি প্রতিরক্ষামূলক বুদ্বুদ।

function addMethod(object, name, fn) {
  var old = object[name];
  object[name] = function(){
    if (fn.length == arguments.length)
      return fn.apply(this, arguments)
    else if (typeof old == 'function')
      return old.apply(this, arguments);
  };
};

  • কোড প্রবাহ বুঝতে ডিবাগার ব্যবহার করুন।
  • নীচে addMethodতিনটি ফাংশন যুক্ত করা হয় যা যখন ninja.whatever(x)আর্গুমেন্টগুলির সংখ্যা সহ যে xকোনও কিছু হতে পারে যেমন ফাঁকা বা এক বা একাধিক বিভিন্ন ফাংশনটিকে ফাংশনটির ব্যবহারের সময় সংজ্ঞায়িত হিসাবে অনুরোধ addMethodকরে।

var ninja = {};
debugger;


addMethod(ninja,'whatever',function(){ console.log("I am the one with ZERO arguments supplied") });
addMethod(ninja,'whatever',function(a){ console.log("I am the one with ONE arguments supplied") });
addMethod(ninja,'whatever',function(a,b){ console.log("I am the one with TWO arguments supplied") });


ninja.whatever();
ninja.whatever(1,2);
ninja.whatever(3);


4

এর কাছে যাওয়ার আরও একটি উপায় হল বিশেষ ভেরিয়েবল ব্যবহার করে: আর্গুমেন্টগুলি , এটি একটি বাস্তবায়ন:

function sum() {
    var x = 0;
    for (var i = 0; i < arguments.length; ++i) {
        x += arguments[i];
    }
    return x;
}

সুতরাং আপনি এই কোডটি এতে পরিবর্তন করতে পারেন:

function sum(){
    var s = 0;
    if (typeof arguments[0] !== "undefined") s += arguments[0];
.
.
.
    return s;
}

3

এটা দেখ. এটা খুব দুর্দান্ত। http://ejohn.org/blog/javascript- আদর্শ-ওভারলোডিং / ট্রিক জাভাস্ক্রিপ্ট আপনাকে এই জাতীয় কল করতে অনুমতি দেয়:

var users = new Users();
users.find(); // Finds all
users.find("John"); // Finds users by name
users.find("John", "Resig"); // Finds users by first and last name

হাই जयদার, আমার উত্তরটি দেখুন, এতে প্রকৃত জাভাস্ক্রিপ্ট পদ্ধতি ওভারলোডিংয়ের কোড রয়েছে । আমি কথা বলছি Func(new Point())এবং Func(new Rectangle())বিভিন্ন ফাংশন সম্পাদন করব। তবে আমার অবশ্যই এটি উল্লেখ করতে হবে যে এটি একটি নোংরা হ্যাক, যেহেতু পদ্ধতি ওভারলোডিং সত্যিই একটি সংকলন টাইম টাস্ক সময় চালানো নয়।
কেল্ডন অ্যালেন

3

জাভাস্ক্রিপ্টে ফাংশন ওভারলোডিং:

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

জাভাস্ক্রিপ্ট নেই বিল্ট-ইন আছে ফাংশন ওভারলোডিং। তবে এই আচরণটি বিভিন্ন উপায়ে অনুকরণ করা যায়। এখানে একটি সুবিধাজনক সহজ একটি:

function sayHi(a, b) {
  console.log('hi there ' + a);
  if (b) { console.log('and ' + b) } // if the parameter is present, execute the block
}

sayHi('Frank', 'Willem');

এমন পরিস্থিতিতে যেখানে আপনি জানেন না যে আপনি কতগুলি যুক্তি পাচ্ছেন আপনি তিনটি ডট বিশ্রামের অপারেটরটি ব্যবহার করতে পারবেন ...। এটি যুক্তির বাকী বাক্যগুলিকে অ্যারে রূপান্তরিত করবে। যদিও ব্রাউজারের তুলনায় সাবধান থাকুন। এখানে একটি উদাহরণ:

function foo (a, ...b) {
  console.log(b);
}

foo(1,2,3,4);
foo(1,2);


2

এই পোস্টটিতে ইতিমধ্যে অনেকগুলি সমাধান রয়েছে বলে আমি ভেবেছিলাম যে আমি অন্য একটি পোস্ট করেছি।

function onlyUnique(value, index, self) {
    return self.indexOf(value) === index;
}

function overload() {
   var functions = arguments;
   var nroffunctionsarguments = [arguments.length];
    for (var i = 0; i < arguments.length; i++) {
        nroffunctionsarguments[i] = arguments[i].length;
    }
    var unique = nroffunctionsarguments.filter(onlyUnique);
    if (unique.length === arguments.length) {
        return function () {
            var indexoffunction = nroffunctionsarguments.indexOf(arguments.length);
            return functions[indexoffunction].apply(this, arguments);
        }
    }
    else throw new TypeError("There are multiple functions with the same number of parameters");

}

এটি নীচের প্রদর্শিত হিসাবে ব্যবহার করা যেতে পারে:

var createVector = overload(
        function (length) {
            return { x: length / 1.414, y: length / 1.414 };
        },
        function (a, b) {
            return { x: a, y: b };
        },
        function (a, b,c) {
            return { x: a, y: b, z:c};
        }
    );
console.log(createVector(3, 4));
console.log(createVector(3, 4,5));
console.log(createVector(7.07));

এই সমাধানটি নিখুঁত নয় তবে আমি কীভাবে এটি করা যেতে পারে তা কেবল প্রদর্শন করতে চাই।


2

আপনি জন রেসিগ থেকে 'অ্যাডমেথড' ব্যবহার করতে পারেন। এই পদ্ধতির সাহায্যে আপনি আর্গুমেন্ট গণনার উপর ভিত্তি করে পদ্ধতিগুলি "ওভারলোড" করতে পারেন।

// addMethod - By John Resig (MIT Licensed)
function addMethod(object, name, fn){
    var old = object[ name ];
    object[ name ] = function(){
        if ( fn.length == arguments.length )
            return fn.apply( this, arguments );
        else if ( typeof old == 'function' )
            return old.apply( this, arguments );
    };
}

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

// addMethod - By Stavros Ioannidis
function addMethod(obj, name, fn) {
  obj[name] = obj[name] || function() {
    // get the cached method with arguments.length arguments
    var method = obj[name].cache[arguments.length];

    // if method exists call it 
    if ( !! method)
      return method.apply(this, arguments);
    else throw new Error("Wrong number of arguments");
  };

  // initialize obj[name].cache
  obj[name].cache = obj[name].cache || {};

  // Check if a method with the same number of arguments exists  
  if ( !! obj[name].cache[fn.length])
    throw new Error("Cannot define multiple '" + name +
      "' methods with the same number of arguments!");

  // cache the method with fn.length arguments
  obj[name].cache[fn.length] = function() {
    return fn.apply(this, arguments);
  };
}

2

ফরোয়ার্ডিং প্যাটার্ন => জেএস ওভারলোডিংয়ের সেরা অনুশীলন

তৃতীয় ও চতুর্থ পয়েন্ট থেকে নামটি নির্মিত অন্য কোনও ফাংশনে ফরোয়ার্ড করুন:

  1. যুক্তি সংখ্যা ব্যবহার করে
  2. ধরণের যুক্তি পরীক্ষা করা হচ্ছে
window['foo_'+arguments.length+'_'+Array.from(arguments).map((arg)=>typeof arg).join('_')](...arguments)

আপনার ক্ষেত্রে আবেদন:

 function foo(){
          return window['foo_'+arguments.length+Array.from(arguments).map((arg)=>typeof arg).join('_')](...arguments);

  }
   //------Assuming that `x` , `y` and `z` are String when calling `foo` . 

  /**-- for :  foo(x)*/
  function foo_1_string(){
  }
  /**-- for : foo(x,y,z) ---*/
  function foo_3_string_string_string(){

  }

অন্যান্য জটিল নমুনা:

      function foo(){
          return window['foo_'+arguments.length+Array.from(arguments).map((arg)=>typeof arg).join('_')](...arguments);
       }

        /** one argument & this argument is string */
      function foo_1_string(){

      }
       //------------
       /** one argument & this argument is object */
      function foo_1_object(){

      }
      //----------
      /** two arguments & those arguments are both string */
      function foo_2_string_string(){

      }
       //--------
      /** Three arguments & those arguments are : id(number),name(string), callback(function) */
      function foo_3_number_string_function(){
                let args=arguments;
                  new Person(args[0],args[1]).onReady(args[3]);
      }

       //--- And so on ....   

2

জেএসের 100 টি লাইনে ডায়নামিক পলিমারফিজমের মাধ্যমে ফাংশন ওভারলোডিং

  • ভ্যানিলাজেএস, কোনও বাহ্যিক নির্ভরতা নেই
  • সম্পূর্ণ ব্রাউজার সমর্থন - Array.prototype.slice , Object.prototype.toString
  • 1114 বাইট uglify'd / 744 বাইট জি জিপড

এই কোড এর একটি বিরাট আকৃতির শরীরের যার মধ্যে থেকে isFn, isArrইত্যাদি টাইপ পরীক্ষণ ফাংশন। সমস্ত বাহ্যিক নির্ভরতা অপসারণ করতে নীচের ভ্যানিলাজেএস সংস্করণটি পুনরায় কাজ করা হয়েছে, তবে আপনাকে .add()কলগুলিতে ব্যবহারের জন্য নিজের ধরণের চেক ফাংশনগুলি নির্ধারণ করতে হবে ।

দ্রষ্টব্য: এটি একটি স্ব-সম্পাদনকারী ফাংশন (যাতে আমাদের ক্লোজার / ক্লোড স্কোপ থাকতে পারে), সুতরাং এর window.overloadচেয়ে অ্যাসাইনমেন্ট function overload() {...}

window.overload = function () {
    "use strict"

    var a_fnOverloads = [],
        _Object_prototype_toString = Object.prototype.toString
    ;

    function isFn(f) {
        return (_Object_prototype_toString.call(f) === '[object Function]');
    } //# isFn

    function isObj(o) {
        return !!(o && o === Object(o));
    } //# isObj

    function isArr(a) {
        return (_Object_prototype_toString.call(a) === '[object Array]');
    } //# isArr

    function mkArr(a) {
        return Array.prototype.slice.call(a);
    } //# mkArr

    function fnCall(fn, vContext, vArguments) {
        //# <ES5 Support for array-like objects
        //#     See: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/apply#Browser_compatibility
        vArguments = (isArr(vArguments) ? vArguments : mkArr(vArguments));

        if (isFn(fn)) {
            return fn.apply(vContext || this, vArguments);
        }
    } //# fnCall

    //# 
    function registerAlias(fnOverload, fn, sAlias) {
        //# 
        if (sAlias && !fnOverload[sAlias]) {
            fnOverload[sAlias] = fn;
        }
    } //# registerAlias

    //# 
    function overload(vOptions) {
        var oData = (isFn(vOptions) ?
                { default: vOptions } :
                (isObj(vOptions) ?
                    vOptions :
                    {
                        default: function (/*arguments*/) {
                            throw "Overload not found for arguments: [" + mkArr(arguments) + "]";
                        }
                    }
                )
            ),
            fnOverload = function (/*arguments*/) {
                var oEntry, i, j,
                    a = arguments,
                    oArgumentTests = oData[a.length] || []
                ;

                //# Traverse the oArgumentTests for the number of passed a(rguments), defaulting the oEntry at the beginning of each loop
                for (i = 0; i < oArgumentTests.length; i++) {
                    oEntry = oArgumentTests[i];

                    //# Traverse the passed a(rguments), if a .test for the current oArgumentTests fails, reset oEntry and fall from the a(rgument)s loop
                    for (j = 0; j < a.length; j++) {
                        if (!oArgumentTests[i].tests[j](a[j])) {
                            oEntry = undefined;
                            break;
                        }
                    }

                    //# If all of the a(rgument)s passed the .tests we found our oEntry, so break from the oArgumentTests loop
                    if (oEntry) {
                        break;
                    }
                }

                //# If we found our oEntry above, .fn.call its .fn
                if (oEntry) {
                    oEntry.calls++;
                    return fnCall(oEntry.fn, this, a);
                }
                //# Else we were unable to find a matching oArgumentTests oEntry, so .fn.call our .default
                else {
                    return fnCall(oData.default, this, a);
                }
            } //# fnOverload
        ;

        //# 
        fnOverload.add = function (fn, a_vArgumentTests, sAlias) {
            var i,
                bValid = isFn(fn),
                iLen = (isArr(a_vArgumentTests) ? a_vArgumentTests.length : 0)
            ;

            //# 
            if (bValid) {
                //# Traverse the a_vArgumentTests, processinge each to ensure they are functions (or references to )
                for (i = 0; i < iLen; i++) {
                    if (!isFn(a_vArgumentTests[i])) {
                        bValid = _false;
                    }
                }
            }

            //# If the a_vArgumentTests are bValid, set the info into oData under the a_vArgumentTests's iLen
            if (bValid) {
                oData[iLen] = oData[iLen] || [];
                oData[iLen].push({
                    fn: fn,
                    tests: a_vArgumentTests,
                    calls: 0
                });

                //# 
                registerAlias(fnOverload, fn, sAlias);

                return fnOverload;
            }
            //# Else one of the passed arguments was not bValid, so throw the error
            else {
                throw "poly.overload: All tests must be functions or strings referencing `is.*`.";
            }
        }; //# overload*.add

        //# 
        fnOverload.list = function (iArgumentCount) {
            return (arguments.length > 0 ? oData[iArgumentCount] || [] : oData);
        }; //# overload*.list

        //# 
        a_fnOverloads.push(fnOverload);
        registerAlias(fnOverload, oData.default, "default");

        return fnOverload;
    } //# overload

    //# 
    overload.is = function (fnTarget) {
        return (a_fnOverloads.indexOf(fnTarget) > -1);
    } //# overload.is

    return overload;
}();

ব্যবহার:

কলার তার ওভারলোড হওয়া ফাংশনগুলি এর ফেরতের ক্ষেত্রে একটি ভেরিয়েবল বরাদ্দ করে সংজ্ঞায়িত করে overload()। চেইন করার জন্য ধন্যবাদ, অতিরিক্ত ওভারলোডগুলি সিরিজে সংজ্ঞায়িত করা যায়:

var myOverloadedFn = overload(function(){ console.log("default", arguments) })
    .add(function(){ console.log("noArgs", arguments) }, [], "noArgs")
    .add(function(){ console.log("str", arguments) }, [function(s){ return typeof s === 'string' }], "str")
;

overload()স্বাক্ষর সনাক্ত করতে না পারলে কল করতে "ডিফল্ট" ফাংশন সংজ্ঞায়িত করার একক alচ্ছিক যুক্তি । যুক্তিগুলি হ'ল .add():

  1. fn: functionওভারলোড সংজ্ঞায়িত;
  2. a_vArgumentTests: Arrayএর functionউপর চালানোর জন্য পরীক্ষার সংজ্ঞা দিচ্ছে arguments। প্রত্যেকে functionএকটি একক যুক্তি গ্রহণ trueকরে এবং যুক্তিটি বৈধ কিনা তার ভিত্তিতে আপনার ফিরিয়ে দেয় ;
  3. sAlias(Alচ্ছিক): stringওভারলোড ফাংশনটি অ্যাক্সেসের জন্য উপনামটি সংজ্ঞায়িত করা ( fn) উদাহরণস্বরূপ myOverloadedFn.noArgs(), যুক্তিগুলির গতিশীল পলিমারফিজম পরীক্ষা এড়িয়ে সরাসরি সেই ফাংশনটি কল করবে।

এই বাস্তবায়নটি আসলে দ্বিতীয় a_vArgumentTestsতর্ক হিসাবে কেবল traditionalতিহ্যবাহী ফাংশন ওভারলোডকে বেশি করার অনুমতি দেয়.add()অনুশীলনের কাস্টম ধরণের সংজ্ঞা । সুতরাং, আপনি কেবল প্রকারের ভিত্তিতেই নয়, তবে রেঞ্জ, মান বা মান সংগ্রহের ভিত্তিতে আর্গুমেন্টগুলি গেট করতে পারেন!

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

এখন, কিছু আদেশ সহকারে হয় ... হিসাবে জাভাস্ক্রিপ্ট ঢিলেঢালাভাবে টাইপ করা হয়, আপনি সঙ্গে সতর্কতা অবলম্বন করা হবে আপনার vArgumentTestsএকটি যেমন integerহিসেবে যাচাই করা যায়নিfloat , ইত্যাদি

জেএসকম্প্রেস.কম সংস্করণ (১১১৪ বাইট, 4৪৪ বাইট জি-জিপ):

window.overload=function(){'use strict';function b(n){return'[object Function]'===m.call(n)}function c(n){return!!(n&&n===Object(n))}function d(n){return'[object Array]'===m.call(n)}function e(n){return Array.prototype.slice.call(n)}function g(n,p,q){if(q=d(q)?q:e(q),b(n))return n.apply(p||this,q)}function h(n,p,q){q&&!n[q]&&(n[q]=p)}function k(n){var p=b(n)?{default:n}:c(n)?n:{default:function(){throw'Overload not found for arguments: ['+e(arguments)+']'}},q=function(){var r,s,t,u=arguments,v=p[u.length]||[];for(s=0;s<v.length;s++){for(r=v[s],t=0;t<u.length;t++)if(!v[s].tests[t](u[t])){r=void 0;break}if(r)break}return r?(r.calls++,g(r.fn,this,u)):g(p.default,this,u)};return q.add=function(r,s,t){var u,v=b(r),w=d(s)?s.length:0;if(v)for(u=0;u<w;u++)b(s[u])||(v=_false);if(v)return p[w]=p[w]||[],p[w].push({fn:r,tests:s,calls:0}),h(q,r,t),q;throw'poly.overload: All tests must be functions or strings referencing `is.*`.'},q.list=function(r){return 0<arguments.length?p[r]||[]:p},l.push(q),h(q,p.default,'default'),q}var l=[],m=Object.prototype.toString;return k.is=function(n){return-1<l.indexOf(n)},k}();

2

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

function foo(var1, var2, opts){
  // set default values for parameters
  const defaultOpts = {
    a: [1,2,3],
    b: true,
    c: 0.3289,
    d: "str",
  }
  // merge default and passed-in parameters
  // defaultOpts must go first!
  const mergedOpts = {...defaultOpts, ...opts};

  // you can now refer to parameters like b as mergedOpts.b,
  // or just assign mergedOpts.b to b
  console.log(mergedOpts.a);
  console.log(mergedOpts.b);
  console.log(mergedOpts.c);  
  console.log(mergedOpts.d);
}
// the parameters you passed in override the default ones
// all JS types are supported: primitives, objects, arrays, functions, etc.
let var1, var2="random var";
foo(var1, var2, {a: [1,2], d: "differentString"});

// parameter values inside foo:
//a: [1,2]
//b: true
//c: 0.3289
//d: "differentString"

সিনট্যাক্স স্প্রেড কি?

ইসমাস্ক্রিপ্ট প্রস্তাবের জন্য বিশ্রাম / স্প্রেড বৈশিষ্ট্য (পর্যায় 4) আক্ষরিক বস্তুতে স্প্রেড বৈশিষ্ট্য যুক্ত করে। এটি সরবরাহ করা অবজেক্ট থেকে একটি নতুন অবজেক্টের উপরের অগণিত বৈশিষ্ট্যগুলি অনুলিপি করে। আরও কিছু

দ্রষ্টব্য: অবজেক্ট লিটারেলের মধ্যে ছড়িয়ে পড়া সিনট্যাক্স এজ এবং আইই তে কাজ করে না এবং এটি একটি পরীক্ষামূলক বৈশিষ্ট্য। ব্রাউজারের সামঞ্জস্যতা দেখুন


2

ফাংশন ওভারলোডিংয়ের জন্য এরকম কিছু করা যেতে পারে।

function addCSS(el, prop, val) {
  return {
    2: function() {
      // when two arguments are set
      // now prop is an oject
      for (var i in prop) {
          el.style[i] = prop[i];
      }
    },
    3: function() {
      // when three arguments are set
      el.style[prop] = val;
    }
    }[arguments.length]();
}
// usage
var el = document.getElementById("demo");
addCSS(el, "color", "blue");
addCSS(el, {
    "backgroundColor": "black",
  "padding": "10px"
});

সূত্র


1

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

var foo;

// original 'foo' definition
foo = function(a) {
  console.log("a: " + a);
}

// define 'foo' to accept two arguments
foo = (function() {
  // store a reference to the previous definition of 'foo'
  var old = foo;

  // use inline function so that you can refer to it internally
  return function newFoo(a,b) {

    // check that the arguments.length == the number of arguments 
    // defined for 'newFoo'
    if (arguments.length == newFoo.length) {
      console.log("a: " + a);
      console.log("b: " + b);

    // else if 'old' is a function, apply it to the arguments
    } else if (({}).toString.call(old) === '[object Function]') {
      old.apply(null, arguments);
    }
  }
})();

foo(1);
> a: 1
foo(1,2);
> a: 1
> b: 2
foo(1,2,3)
> a: 1

সংক্ষেপে, আইআইএফই এর ব্যবহার একটি স্থানীয় সুযোগ তৈরি করে, যা আমাদের oldফাংশনের প্রাথমিক সংজ্ঞাটির জন্য একটি রেফারেন্স সংরক্ষণ করার জন্য প্রাইভেট ভেরিয়েবলকে সংজ্ঞায়িত করতে দেয় foo। এই ফাংশনটি তারপরে একটি ইনলাইন ফাংশন দেয় newFooযা দুটি দুটি আর্গুমেন্টের বিষয়বস্তু লগ করে যদি এটি ঠিক দুটি যুক্তি পাস হয় aএবং bঅথবা oldযদি ফাংশনটি কল করে arguments.length !== 2। এই প্যাটার্নটি বেশ কয়েকটি বিভিন্ন ক্রিয়ামূলক ত্রুটিযুক্ত একটি ভেরিয়েবলকে অনুমোদিত করতে বহুবার পুনরাবৃত্তি করতে পারে।


1

আমি অতিরিক্ত লোড-মত পদ্ধতির একটি দরকারী উদাহরণ ভাগ করতে চাই।

function Clear(control)
{
  var o = typeof control !== "undefined" ? control : document.body;
  var children = o.childNodes;
  while (o.childNodes.length > 0)
    o.removeChild(o.firstChild);
}

ব্যবহার: পরিষ্কার (); // সমস্ত নথি সাফ করে

সাফ (myDiv); // মাইডিভ দ্বারা রেফারেন্স প্যানেল সাফ করে


1

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

myFunction = function(a, b, c) {
     if (b === undefined && c === undefined ){
          // do x...
     }
     else {
          // do y...
     }
};

1
কেবলমাত্র খেয়াল করতে চান যে টাইপযুক্ত মানে "প্রকার নয়"।
হামদিয়াকোগুজ

1

জুলাই 2017 পর্যন্ত, নিম্নলিখিতগুলি সাধারণ কৌশল হিসাবে রয়েছে। মনে রাখবেন যে আমরা ফাংশনটির মধ্যে টাইপ চেকিংও করতে পারি।

function f(...rest){   // rest is an array
   console.log(rest.length);
   for (v of rest) if (typeof(v)=="number")console.log(v);
}
f(1,2,3);  // 3 1 2 3

1

আপনার ব্যবহারের ক্ষেত্রে, আমি এটির সাথে এটিই সামাল দেব ES6(যেহেতু এটি ইতিমধ্যে 2017 এর শেষ):

const foo = (x, y, z) => {
  if (y && z) {
    // Do your foo(x, y, z); functionality
    return output;
  }
  // Do your foo(x); functionality
  return output;
}

যে কোনও পরিমাণ প্যারামিটারের সাথে কাজ করার জন্য আপনি স্পষ্টতই এটিকে অভিযোজিত করতে পারেন এবং সেই অনুযায়ী আপনার শর্তাধীন বিবৃতি পরিবর্তন করতে পারেন।


1

জেএসে কোনও প্রকৃত ওভারলোডিং নেই, যাইহোক আমরা এখনও বিভিন্ন উপায়ে পদ্ধতি ওভারলোডিং অনুকরণ করতে পারি:

পদ্ধতি # 1: অবজেক্টটি ব্যবহার করুন

function test(x,options){
  if("a" in options)doSomething();
  else if("b" in options)doSomethingElse();
}
test("ok",{a:1});
test("ok",{b:"string"});

পদ্ধতি # 2: বিশ্রাম (স্প্রেড) পরামিতিগুলি ব্যবহার করুন

function test(x,...p){
 if(p[2])console.log("3 params passed"); //or if(typeof p[2]=="string")
else if (p[1])console.log("2 params passed");
else console.log("1 param passed");
}

পদ্ধতি # 3: অপরিশোধিত ব্যবহার করুন

function test(x, y, z){
 if(typeof(z)=="undefined")doSomething();
}

পদ্ধতি # 4: টাইপ চেকিং

function test(x){
 if(typeof(x)=="string")console.log("a string passed")
 else ...
}

1

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

function transformer(
    firstNumber = 1,
    secondNumber = new Date().getFullYear(),
    transform = function multiply(firstNumber, secondNumber) {
        return firstNumber * secondNumber;
    }
) {
    return transform(firstNumber, secondNumber);
}

console.info(transformer());
console.info(transformer(8));
console.info(transformer(2, 6));
console.info(transformer(undefined, 65));

function add(firstNumber, secondNumber) {
    return firstNumber + secondNumber;
}
console.info(transformer(undefined, undefined, add));
console.info(transformer(3, undefined, add));

ফলাফল (2020 সালের জন্য):

2020
16160
12
65
2021
2023

আরো তথ্য: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/Default_parameters


0

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

  1. প্রথম স্থানে বিভিন্ন নাম ব্যবহার করা

সামান্য তবে প্রয়োজনীয় ইঙ্গিত সহ, কম্পিউটারের জন্য নামগুলি পৃথক হওয়া উচিত, তবে আপনার জন্য নয়। ওভারলোড হওয়া ফাংশনগুলির নাম যেমন: ফানক, ফানক 1, ফানক 2 2


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