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


103

ক্লাসিকাল (নন-জেএস) ওভারলোডিংয়ের পদ্ধতির:

function myFunc(){
 //code
}

function myFunc(overloaded){
 //other code
}

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

function myFunc(options){
 if(options["overloaded"]){
  //code
 }
}

জাভাস্ক্রিপ্টে ফাংশন ওভারলোডিং এর জন্য ওভারলোডগুলির সাথে কোনও বস্তুকে পাশ কাটিয়ে ওঠার জন্য কি আরও ভাল কাজ হতে পারে?

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


1
তারপরে আপনি জাভাস্ক্রিপ্ট ভুল সম্পর্কে চিন্তা করছেন; যদি আপনার ওভারলোডস এবং স্কোপ নিয়ে সমস্যা থাকে তবে আপনার সম্ভবত অন্য কোনও পদ্ধতির নাম থাকা উচিত কারণ মনে হচ্ছে এটি অন্য কাজ করছে
জোশকমলি

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

উত্তর:


126

জাভাস্ক্রিপ্টে যুক্তি ওভারলোডিংয়ের একাধিক দিক রয়েছে:

  1. পরিবর্তনশীল আর্গুমেন্ট - আপনি বিভিন্ন ধরণের আর্গুমেন্ট (উভয় প্রকার এবং পরিমাণে) পাস করতে পারেন এবং ফাংশনটি এমনভাবে আচরণ করবে যা এতে যুক্ত আর্গুমেন্টের সাথে মেলে।

  2. ডিফল্ট আর্গুমেন্ট - যদি কোনও আর্গুমেন্ট পাস না হয় তবে আপনি একটি ডিফল্ট মান নির্ধারণ করতে পারেন।

  3. নামযুক্ত আর্গুমেন্ট - আর্গুমেন্ট অর্ডার অপ্রাসঙ্গিক হয়ে যায় এবং আপনি কোন নামটি যুক্ত করে যে ফাংশনে আপনি যেতে চান।

আর্গুমেন্ট হ্যান্ডলিংয়ের এই বিভাগগুলির প্রতিটিের নীচে একটি বিভাগ দেওয়া আছে।

পরিবর্তনশীল যুক্তি

যেহেতু জাভাস্ক্রিপ্টে আর্গুমেন্ট বা প্রয়োজনীয় myFunc()পরিমাণের তর্কগুলি পরীক্ষা করার কোনও প্রকার নেই, আপনার কেবলমাত্র একটি বাস্তবায়ন থাকতে পারে আর্গুমেন্টের ধরন, উপস্থিতি বা পরিমাণ যাচাই করে এটিতে কী আর্গুমেন্টগুলি পাস করা হয়েছিল তার সাথে খাপ খাইয়ে নিতে পারেন।

jQuery সর্বদা এটি করে। আপনি কিছু আর্গুমেন্টকে alচ্ছিক করতে পারেন বা আপনার পক্ষে কোন যুক্তি প্রেরণ করা হয় তার উপর নির্ভর করে আপনার ফাংশনে শাখা করতে পারেন।

এই ধরণের ওভারলোডগুলি বাস্তবায়িত করার জন্য, আপনি বিভিন্ন ধরণের প্রযুক্তি ব্যবহার করতে পারেন:

  1. ঘোষিত আর্গুমেন্টের নাম মান কিনা তা পরীক্ষা করে আপনি প্রদত্ত যে কোনও যুক্তির উপস্থিতি যাচাই করতে পারেন undefined
  2. আপনি মোট পরিমাণ বা যুক্তি দিয়ে পরীক্ষা করতে পারেন arguments.length
  3. আপনি প্রদত্ত যে কোনও যুক্তির ধরণটি পরীক্ষা করতে পারেন।
  4. পরিবর্তনশীল সংখ্যক আর্গুমেন্টের জন্য, আপনি argumentsকোনও প্রদত্ত যুক্তি অ্যাক্সেসের জন্য সিউডো-অ্যারে ব্যবহার করতে পারেন arguments[i]

এখানে কিছু উদাহরন:

আসুন jQuery এর obj.data()পদ্ধতিটি দেখুন। এটি ব্যবহারের চারটি ভিন্ন রূপকে সমর্থন করে:

obj.data("key");
obj.data("key", value);
obj.data();
obj.data(object);

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

এখানে ইংরেজিতে এই সমস্ত বিকল্পগুলির মধ্যে কীভাবে আলাদা করা যায় তা এখানে রয়েছে এবং তারপরে আমি কোডগুলিতে সেগুলি একত্রিত করব:

// get the data element associated with a particular key value
obj.data("key");

প্রথম আর্গুমেন্টটি .data()যদি একটি স্ট্রিং হয় এবং দ্বিতীয় যুক্তিটি হয় undefined, তবে কলার অবশ্যই এই ফর্মটি ব্যবহার করছেন।


// set the value associated with a particular key
obj.data("key", value);

দ্বিতীয় যুক্তি যদি অপরিজ্ঞাত না হয় তবে একটি নির্দিষ্ট কীটির মান নির্ধারণ করুন।


// get all keys/values
obj.data();

যদি কোনও আর্গুমেন্ট পাস করা হয় না, তবে প্রত্যাবর্তিত অবজেক্টে সমস্ত কী / মানটি ফিরিয়ে দিন।


// set all keys/values from the passed in object
obj.data(object);

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


জাভাস্ক্রিপ্ট লজিকের এক সেটে থাকা সমস্তকে কীভাবে আপনি একত্রিত করতে পারেন তা এখানে:

 // method declaration for .data()
 data: function(key, value) {
     if (arguments.length === 0) {
         // .data()
         // no args passed, return all keys/values in an object
     } else if (typeof key === "string") {
         // first arg is a string, look at type of second arg
         if (typeof value !== "undefined") {
             // .data("key", value)
             // set the value for a particular key
         } else {
             // .data("key")
             // retrieve a value for a key
         }
     } else if (typeof key === "object") {
         // .data(object)
         // set all key/value pairs from this object
     } else {
         // unsupported arguments passed
     }
 },

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

উদাহরণস্বরূপ, যদি আপনার এমন কোনও ফাংশন থাকে যা তিনটি স্ট্রিং আর্গুমেন্ট গ্রহণ করে:

obj.query("firstArg", "secondArg", "thirdArg");

আপনি সহজেই তৃতীয় তর্কটি optionচ্ছিক করতে পারেন এবং আপনি সহজেই সেই শর্তটি সনাক্ত করতে পারেন তবে আপনি কেবল দ্বিতীয় যুক্তি optionচ্ছিক করতে পারবেন না কারণ এই কলারটির মধ্যে কোনটি পাস হবে তা আপনি বলতে পারবেন না কারণ দ্বিতীয়টি সনাক্ত করার কোনও উপায় নেই বলে চিহ্নিত করার উপায় নেই আর্গুমেন্টকে দ্বিতীয় যুক্তি বা দ্বিতীয় যুক্তি বাদ দেওয়া হয়েছিল তাই দ্বিতীয় যুক্তির স্পটটিতে আসলে তৃতীয় যুক্তিই রয়েছে:

obj.query("firstArg", "secondArg");
obj.query("firstArg", "thirdArg");

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

obj.query("firstArg", null, "thirdArg");

এখানে Quচ্ছিক আর্গুমেন্টগুলির jQuery উদাহরণ। উভয় যুক্তিই optionচ্ছিক এবং পাস না হলে ডিফল্ট মান গ্রহণ করে:

clone: function( dataAndEvents, deepDataAndEvents ) {
    dataAndEvents = dataAndEvents == null ? false : dataAndEvents;
    deepDataAndEvents = deepDataAndEvents == null ? dataAndEvents : deepDataAndEvents;

    return this.map( function () {
        return jQuery.clone( this, dataAndEvents, deepDataAndEvents );
    });
},

এখানে একটি jQuery উদাহরণ রয়েছে যেখানে আর্গুমেন্টটি অনুপস্থিত বা তিনটি বিভিন্ন ধরণের যে কোনও একটি আপনাকে চারটি আলাদা ওভারলোড দেয়:

html: function( value ) {
    if ( value === undefined ) {
        return this[0] && this[0].nodeType === 1 ?
            this[0].innerHTML.replace(rinlinejQuery, "") :
            null;

    // See if we can take a shortcut and just use innerHTML
    } else if ( typeof value === "string" && !rnoInnerhtml.test( value ) &&
        (jQuery.support.leadingWhitespace || !rleadingWhitespace.test( value )) &&
        !wrapMap[ (rtagName.exec( value ) || ["", ""])[1].toLowerCase() ] ) {

        value = value.replace(rxhtmlTag, "<$1></$2>");

        try {
            for ( var i = 0, l = this.length; i < l; i++ ) {
                // Remove element nodes and prevent memory leaks
                if ( this[i].nodeType === 1 ) {
                    jQuery.cleanData( this[i].getElementsByTagName("*") );
                    this[i].innerHTML = value;
                }
            }

        // If using innerHTML throws an exception, use the fallback method
        } catch(e) {
            this.empty().append( value );
        }

    } else if ( jQuery.isFunction( value ) ) {
        this.each(function(i){
            var self = jQuery( this );

            self.html( value.call(this, i, self.html()) );
        });

    } else {
        this.empty().append( value );
    }

    return this;
},

নাম যুক্তি

অন্যান্য ভাষাগুলি (পাইথনের মতো) কেবল কিছু আর্গুমেন্ট পাস করার এবং আর্গুমেন্টগুলিকে যে ক্রমে পাস করা হয়েছে তার চেয়ে আলাদা করে দেওয়ার উপায় হিসাবে একটি নামকৃত তর্কগুলি পাস করার অনুমতি দেয় J জাভাস্ক্রিপ্ট নামক যুক্তির বৈশিষ্ট্যটিকে সরাসরি সমর্থন করে না support একটি নকশার প্যাটার্ন যা সাধারণত তার জায়গায় ব্যবহৃত হয় তা হল বৈশিষ্ট্য / মানগুলির মানচিত্র পাস করা pass এটি বৈশিষ্ট্য এবং মানগুলির সাথে বা ES6 এবং এর উপরের কোনও বস্তুটি পাস করার মাধ্যমে করা যেতে পারে, আপনি আসলে কোনও মানচিত্র অবজেক্টটি নিজেই পাস করতে পারেন।

এখানে একটি সহজ ES5 উদাহরণ রয়েছে:

jQuery এর $.ajax()ব্যবহারের এমন একটি রূপ গ্রহণ করে যেখানে আপনি কেবল এটি একটি একক প্যারামিটারটি পাস করেন যা বৈশিষ্ট্য এবং মানগুলির সাথে নিয়মিত জাভাস্ক্রিপ্ট অবজেক্ট। আপনি কোন বৈশিষ্ট্যগুলি এটি পাস করেন তা নির্ধারণ করে যে কোন আর্গুমেন্ট / অপশনগুলি আজাক্স কলটিতে পাস করা হচ্ছে। কিছু প্রয়োজন হতে পারে, অনেক alচ্ছিক। যেহেতু এগুলি কোনও বস্তুর বৈশিষ্ট্য, তাই কোনও নির্দিষ্ট আদেশ নেই। প্রকৃতপক্ষে, 30 টিরও বেশি আলাদা বৈশিষ্ট্য রয়েছে যা সেই বস্তুটিতে পাস হতে পারে, কেবলমাত্র একটি (ইউআরএল) প্রয়োজন।

এখানে একটি উদাহরণ:

$.ajax({url: "http://www.example.com/somepath", data: myArgs, dataType: "json"}).then(function(result) {
    // process result here
});

এর ভিতর $.ajax()বাস্তবায়ন, তারপর শুধু জিজ্ঞাসাবাদ বৈশিষ্ট্যাবলী ইনকামিং বস্তুর উপর গৃহীত হয় যা করতে পারেন এবং নামে আর্গুমেন্ট হিসাবে যারা ব্যবহার করেন। এটি হয় for (prop in obj)বা দিয়ে সমস্ত বৈশিষ্ট্যগুলি একটি অ্যারের সাথে পেয়ে Object.keys(obj)এবং তারপরে সেই অ্যারেটি পুনরায় করা যায়।

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

ES6 পরিবেশে উপরোক্ত পাস করা অবজেক্টের জন্য ডিফল্ট বৈশিষ্ট্য / মান তৈরি করতে ডিস্ট্রাকচার ব্যবহার করা সম্ভব। এই রেফারেন্স নিবন্ধে এটি আরও বিশদে আলোচনা করা হয়েছে ।

এই নিবন্ধ থেকে একটি উদাহরণ এখানে:

function selectEntries({ start=0, end=-1, step=1 } = {}) {
    ···
};

এই জন্য ডিফল্ট বৈশিষ্ট্য ও মূল্যবোধ সৃষ্টি start, endএবং stepএকটি বস্তু প্রেরণ উপর বৈশিষ্ট্য selectEntries()ফাংশন।

ফাংশন আর্গুমেন্টের জন্য ডিফল্ট মান

ES6 এ, জাভাস্ক্রিপ্ট আর্গুমেন্টগুলির জন্য ডিফল্ট মানগুলির জন্য অন্তর্নির্মিত ভাষা সমর্থন যুক্ত করে।

উদাহরণ স্বরূপ:

function multiply(a, b = 1) {
  return a*b;
}

multiply(5); // 5

এটি এমডিএন-এ কীভাবে ব্যবহার করা যেতে পারে তার আরও বিবরণ ।


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

2
@ ট্র্যাভিজেজে - হ্যাঁ, জাভাস্ক্রিপ্টে ওভারলোডগুলি যেভাবে করা হয় তা অভিযোজ্য ফাংশন। আপনার অন্য বিকল্পটি হ'ল পৃথক যুক্তিযুক্ত ফাংশনটি বিভিন্ন যুক্তি সহ ব্যবহার করা। দুটি বাস্তবায়নের যদি সাধারণ কিছু না হয় তবে তা হয় একটি গ্রহণযোগ্য অনুশীলন। যদি দুটি বাস্তবায়ন মূলত একই জিনিসটি করে, তবে কেবল বিভিন্ন যুক্তি দিয়ে শুরু হয়, তবে আমি মনে করি এটি আপনার ইন্টারফেসটিকে অভিযোজ্য ফাংশনটি ব্যবহার করার জন্য আরও কমপ্যাক্ট করে তোলে এবং এটি আপনাকে দুটি সম্পর্কিত বাস্তবায়নের মধ্যে কোড ভাগ করার সুযোগ দেয় gives
jr.00

কিছু কোড উদাহরণ যুক্ত হয়েছে, উভয় ইংরেজি এবং প্রকৃত কোডে ব্যাখ্যা করা হয়েছে।
jਫਰ00

আমি যখন এটি চেষ্টা করি তখন সাফারির সর্বশেষতম সংস্করণে আমি একটি ত্রুটি, অপ্রত্যাশিত টোকেন '=' পাচ্ছি resetProgressBar: function(display_errors, lockout = false)
নিক

@ নিক - এই ES6 সামঞ্জস্যতা টেবিল অনুযায়ী , ডিফল্ট প্যারামিটার মানগুলি সাফারি 10 এবং তারপরে কাজ করা উচিত। প্রতি এই MDN পৃষ্ঠা করে তা "কোন সমর্থন" সাফারিতে বলেছেন। আমার কাছে ম্যাক নেই তাই আমি নিজেই এটি পরীক্ষা করতে পারি না। এটি সাধারণত অনেকগুলি ব্রাউজার জুড়ে পরে প্রয়োগ করা ES6 বৈশিষ্ট্যগুলির মধ্যে একটি বলে মনে হয়। উদাহরণস্বরূপ, এটি এখনও iOS9 এ দেখায় না।
jender00

33

জাভাস্ক্রিপ্টে একটি ফাংশন ওভারলোডিং বিভিন্ন উপায়ে করা যেতে পারে। তাদের সকলেরই একটি একক মাস্টার ফাংশন জড়িত যা হয় হয় সমস্ত প্রক্রিয়া সম্পাদন করে, বা উপ-ফাংশন / প্রক্রিয়াগুলিতে প্রতিনিধিত্ব করে।

একটি সাধারণ সাধারণ কৌশলগুলির মধ্যে একটি সাধারণ সুইচ জড়িত:

function foo(a, b) {
    switch (arguments.length) {
    case 0:
        //do basic code
        break;
    case 1:
        //do code with `a`
        break;
    case 2:
    default:
        //do code with `a` & `b`
        break;
    }
}

আরও মার্জিত কৌশল হ'ল অ্যারে ব্যবহার করা (বা আপনি যদি প্রতিটি আর্গুমেন্ট গণনার জন্য ওভারলোড না করে থাকেন তবে অবজেক্ট ):

fooArr = [
    function () {
    },
    function (a) {
    },
    function (a,b) {
    }
];
function foo(a, b) {
    return fooArr[arguments.length](a, b);
}

পূর্ববর্তী উদাহরণটি খুব মার্জিত নয়, যে কেউ পরিবর্তন করতে পারে fooArr, এবং যদি কেউ 2 টিরও বেশি যুক্তিতে পাস করে তবে এটি ব্যর্থ হয় foo, সুতরাং মডিউল প্যাটার্ন এবং কয়েকটি চেক ব্যবহার করা আরও ভাল ফর্ম হতে পারে:

var foo = (function () {
    var fns;
    fns = [
        function () {
        },
        function (a) {
        },
        function (a, b) {
        }
    ];
    function foo(a, b) {
        var fnIndex;
        fnIndex = arguments.length;
        if (fnIndex > foo.length) {
            fnIndex = foo.length;
        }
        return fns[fnIndex].call(this, a, b);
    }
    return foo;
}());

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

var foo = (function () {
    var fns;
    fns = {};
    fns[0] = function () {
    };
    fns[1] = function (a) {
    };
    fns[2] = function (a, b) {
    };
    fns.params = function (a, b /*, params */) {
    };
    function foo(a, b) {
        var fnIndex;
        fnIndex = arguments.length;
        if (fnIndex > foo.length) {
            fnIndex = 'params';
        }
        return fns[fnIndex].apply(this, Array.prototype.slice.call(arguments));
    }
    return foo;
}());

আমার ব্যক্তিগত অগ্রাধিকারটি প্রবণতা রয়েছে switch, যদিও এটি মাস্টার ফাংশনটি বড় করে তোলে। আমি যেখানে এই কৌশলটি ব্যবহার করছিলাম তার একটি সাধারণ উদাহরণ হ'ল অ্যাক্সেসর / মিউটর পদ্ধতি:

function Foo() {} //constructor
Foo.prototype = {
    bar: function (val) {
        switch (arguments.length) {
        case 0:
            return this._bar;
        case 1:
            this._bar = val;
            return this;
        }
    }
}

এটি বিকল্পের একটি চমৎকার উদাহরণ :)
ট্র্যাভিস জে

1
ভাল লাগল, আমি সেই দ্বিতীয় কৌশলটি পছন্দ করি
নিক রোল্যান্ডো

8

আপনি কঠোর অর্থে পদ্ধতিতে ওভারলোডিং করতে পারবেন না। এটি যেমন সমর্থন করে javaবা তেমনভাবে পছন্দ করে না c#

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

আমি বেশিরভাগ ক্ষেত্রে কেসের জন্য উপযুক্ত বলে মনে করি তার একটি অনুসরণ করে -

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

function foo(x)
{
} 

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

fooNew(x,y,z)
{
}

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

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

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

( আরও বিশদ ) পিএস: উপরের লিঙ্কটি আমার ব্যক্তিগত ব্লগে যায় এতে অতিরিক্ত বিবরণ রয়েছে।


এটি কোনও সমস্যা নয়, এটি একটি বৈশিষ্ট্য।
অনাহার

4

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

// o = existing object, n = function name, f = function.
    function overload(o, n, f){
        var old = o[n];
        o[n] = function(){
            if(f.length == arguments.length){
                return f.apply(this, arguments);
            }
            else if(typeof o == 'function'){
                return old.apply(this, arguments);
            }
        };
    }

ব্যবহারযোগ্যতা:

var obj = {};
overload(obj, 'function_name', function(){ /* what we will do if no args passed? */});
overload(obj, 'function_name', function(first){ /* what we will do if 1 arg passed? */});
overload(obj, 'function_name', function(first, second){ /* what we will do if 2 args passed? */});
overload(obj, 'function_name', function(first,second,third){ /* what we will do if 3 args passed? */});
//... etc :)

4

জাভাস্ক্রিপ্টে আপনি একবারে ফাংশনটি প্রয়োগ করতে পারেন এবং পরামিতিগুলি ছাড়াই ফাংশনটি শুরু myFunc() করতে পারেন তারপর বিকল্পগুলি 'অপরিজ্ঞাত' আছে কিনা তা পরীক্ষা করে দেখুন

function myFunc(options){
 if(typeof options != 'undefined'){
  //code
 }
}

3

আমি এখানে বর্ণিত এই সমস্যার একটি মার্জিত সমাধান বিকাশের চেষ্টা করেছি । এবং আপনি এখানে ডেমো খুঁজে পেতে পারেন । ব্যবহার এর মতো দেখাচ্ছে:

var out = def({
    'int': function(a) {
        alert('Here is int '+a);
    },

    'float': function(a) {
        alert('Here is float '+a);
    },

    'string': function(a) {
        alert('Here is string '+a);
    },

    'int,string': function(a, b) {
        alert('Here is an int '+a+' and a string '+b);
    },
    'default': function(obj) {
        alert('Here is some other value '+ obj);
    }

});

out('ten');
out(1);
out(2, 'robot');
out(2.5);
out(true);

এটি অর্জনের জন্য ব্যবহৃত পদ্ধতিগুলি:

var def = function(functions, parent) {
 return function() {
    var types = [];
    var args = [];
    eachArg(arguments, function(i, elem) {
        args.push(elem);
        types.push(whatis(elem));
    });
    if(functions.hasOwnProperty(types.join())) {
        return functions[types.join()].apply(parent, args);
    } else {
        if (typeof functions === 'function')
            return functions.apply(parent, args);
        if (functions.hasOwnProperty('default'))
            return functions['default'].apply(parent, args);        
    }
  };
};

var eachArg = function(args, fn) {
 var i = 0;
 while (args.hasOwnProperty(i)) {
    if(fn !== undefined)
        fn(i, args[i]);
    i++;
 }
 return i-1;
};

var whatis = function(val) {

 if(val === undefined)
    return 'undefined';
 if(val === null)
    return 'null';

 var type = typeof val;

 if(type === 'object') {
    if(val.hasOwnProperty('length') && val.hasOwnProperty('push'))
        return 'array';
    if(val.hasOwnProperty('getDate') && val.hasOwnProperty('toLocaleTimeString'))
        return 'date';
    if(val.hasOwnProperty('toExponential'))
        type = 'number';
    if(val.hasOwnProperty('substring') && val.hasOwnProperty('length'))
        return 'string';
 }

 if(type === 'number') {
    if(val.toString().indexOf('.') > 0)
        return 'float';
    else
        return 'int';
 }

 return type;
};

1
ইনপুটগুলি পরিচালনা করার জন্য একটি ফাংশন, খুব চালাক।
ট্র্যাভিস জে

3

https://github.com/jrf0110/leFunc

var getItems = leFunc({
  "string": function(id){
    // Do something
  },
  "string,object": function(id, options){
    // Do something else
  },
  "string,object,function": function(id, options, callback){
    // Do something different
    callback();
  },
  "object,string,function": function(options, message, callback){
    // Do something ca-raaaaazzzy
    callback();
  }
});

getItems("123abc"); // Calls the first function - "string"
getItems("123abc", {poop: true}); // Calls the second function - "string,object"
getItems("123abc", {butt: true}, function(){}); // Calls the third function - "string,object,function"
getItems({butt: true}, "What what?" function(){}); // Calls the fourth function - "object,string,function"

3

জেএস-তে ওভারলোডিং নিয়ে কোনও সমস্যা নেই, ওভারলোডিং ফাংশন করার সময় কীভাবে ক্লিন কোড বজায় রাখবেন পিবি?

আপনি দুটি বিষয়ের উপর ভিত্তি করে ক্লিন কোডের জন্য একটি ফরোয়ার্ড ব্যবহার করতে পারেন :

  1. আর্গুমেন্টের সংখ্যা (ফাংশনটি কল করার সময়)।
  2. আর্গুমেন্টের ধরণ (ফাংশন কল করার সময়)

      function myFunc(){
          return window['myFunc_'+arguments.length+Array.from(arguments).map((arg)=>typeof arg).join('_')](...arguments);
       }
    
        /** one argument & this argument is string */
      function myFunc_1_string(){
    
      }
       //------------
       /** one argument & this argument is object */
      function myFunc_1_object(){
    
      }
      //----------
      /** two arguments & those arguments are both string */
      function myFunc_2_string_string(){
    
      }
       //--------
      /** Three arguments & those arguments are : id(number),name(string), callback(function) */
      function myFunc_3_number_string_function(){
                let args=arguments;
                  new Person(args[0],args[1]).onReady(args[3]);
      }
    
       //--- And so on ....   

2

এটা দেখ:

http://www.codeproject.com/Articles/688869/Overloading-JavaScript-Functions

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


2

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

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 + "}";

}

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


2

এর জন্য আপনাকে একটি ফাংশন তৈরি করতে হবে যা কোনও বস্তুর সাথে ফাংশন যুক্ত করে, তারপরে এটি ফাংশনে আপনি যে পরিমাণ আর্গুমেন্ট প্রেরণ করেছেন তার উপর নির্ভর করে এটি কার্যকর করা হবে:

<script > 
//Main function to add the methods
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);
  };
}


  var ninjas = {
   values: ["Dean Edwards", "Sam Stephenson", "Alex Russell"]
};

//Here we declare the first function with no arguments passed
  addMethod(ninjas, "find", function(){
    return this.values;
});

//Second function with one argument
  addMethod(ninjas, "find", function(name){
    var ret = [];
    for (var i = 0; i < this.values.length; i++)
      if (this.values[i].indexOf(name) == 0)
        ret.push(this.values[i]);
    return ret;
  });

//Third function with two arguments
  addMethod(ninjas, "find", function(first, last){
    var ret = [];
    for (var i = 0; i < this.values.length; i++)
      if (this.values[i] == (first + " " + last))
        ret.push(this.values[i]);
    return ret;
  });


//Now you can do:
ninjas.find();
ninjas.find("Sam");
ninjas.find("Dean", "Edwards")
</script>

0

একই কার্যকারিতাটির জন্য আর্গুমেন্ট গ্রুপগুলির মধ্যে পার্থক্য করার ক্ষমতা অর্জন করতে আমি পিতামাতার ফাংশনের মধ্যে উপ ফাংশন যুক্ত করতে চাই।

var doSomething = function() {
    var foo;
    var bar;
};

doSomething.withArgSet1 = function(arg0, arg1) {
    var obj = new doSomething();
    // do something the first way
    return obj;
};

doSomething.withArgSet2 = function(arg2, arg3) {
    var obj = new doSomething();
    // do something the second way
    return obj;
};

0

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

function foo() {
    if (arguments.length === 0) {
        //do something
    }
    if (arguments.length === 1) {
        //do something else
    }
}

foo(); //do something
foo('one'); //do something else

এটি এখানে কীভাবে কাজ করে তার একটি আরও ভাল ব্যাখ্যা আপনি খুঁজে পেতে পারেন ।


এবং সংঘর্ষ সনাক্তকরণ সম্পর্কে কী? এটি প্যারামিটারলেস ফাংশনগুলি ব্যবহার করার বা অস্তিত্বের জন্য যাচাই করার একটি দুর্দান্ত উপায়, তবে যখন ওভারলোডিংয়ের বিষয়টি আসে তখন এটি সর্বোত্তম অনুশীলন নয়।
ট্র্যাভিস জে
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.