জেএসের 100 টি লাইনে ডায়নামিক পলিমারফিজমের মাধ্যমে ফাংশন ওভারলোডিং
এই কোড এর একটি বিরাট আকৃতির শরীরের যার মধ্যে থেকে 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():
fn: functionওভারলোড সংজ্ঞায়িত;
a_vArgumentTests: Arrayএর functionউপর চালানোর জন্য পরীক্ষার সংজ্ঞা দিচ্ছে arguments। প্রত্যেকে functionএকটি একক যুক্তি গ্রহণ trueকরে এবং যুক্তিটি বৈধ কিনা তার ভিত্তিতে আপনার ফিরিয়ে দেয় ;
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}();