क्या जावास्क्रिप्ट कार्यों को स्वीकार करने के लिए अधिकतम तर्क हो सकते हैं?


80

मुझे पता है कि जावास्क्रिप्ट फ़ंक्शन "किसी भी" तर्क को स्वीकार कर सकता है।

function f(){};
f(1,2,3,4 /*...*/);

लेकिन मैं सोच रहा हूं कि क्या वास्तव में कितने "किसी भी" की सीमा हो सकती है?

उदाहरण के लिए, मान लीजिए कि मैं एक लाख तर्क देता हूं f()। क्या इससे काम हो जायेगा? या दुभाषिया उलटना पड़ेगा?

मैं अनुमान लगा रहा हूं कि अधिकतम या तो (ए) कार्यान्वयन-विशिष्ट या (बी) है (2^32)-1, क्योंकि argumentsऑब्जेक्ट सरणी-जैसा है।

मुझे यह भाषा विनिर्देश में उल्लिखित नहीं दिखता है, लेकिन मैं कुछ बिंदुओं को नहीं जोड़ सकता हूं।


3
इसके अलावा, इस तरह के डेटा के किसी भी बड़े अनुक्रम को एक तर्क के रूप में पारित किया जाना चाहिए जो कि एक सरणी है, न कि अलग-अलग तर्कों के रूप में ताकि एक पूरी प्रतिलिपि की आवश्यकता न हो केवल फ़ंक्शन को कॉल करने के लिए निर्धारित बड़े डेटा सेट से। यह एक अकादमिक अभ्यास होना चाहिए, न कि कुछ ऐसा जो अच्छे विकास प्रथाओं के साथ सामना करना होगा।
— १०:४

1
@ jfriend00, के बारे में मत भूलना Function.prototype.apply। stackoverflow.com/questions/1379553/…
— पॉल ड्रेपर

@PaulDraper - मैं इसके बारे में जानता हूं .apply(), लेकिन यह इनपुट ऐरे की भी नकल बना रहा है। मुद्दा यह है कि कोई भी इंटरफ़ेस जो बहुत बड़ी संख्या में तर्कों को स्वीकार करने की अपेक्षा करता है, उन्हें सामान्य तर्क के रूप में पारित करने की आवश्यकता के लिए घोषित नहीं किया जाना चाहिए। एक सरणी को पास करने के लिए बहुत अधिक कुशल ताकि डेटा की कोई प्रतिलिपि न बनाई जाए।
— 18

5
@ IngoBürk यह एक सैद्धांतिक सवाल नहीं है! भले ही आप स्पष्ट रूप से इस तरह के फ़ंक्शन को नहीं लिखते हैं, अगर आप ES 2015 प्रसार ऑपरेटर और फ़ंक्शन का उपयोग करते हैं ( Math.maxया Array.prototype.concat(...arrayOfArrays)सरणी के एक सरणी को समतल करने के लिए) तो आप गतिशील रूप से एक राक्षस फ़ंक्शन लिखे बिना उस सीमा तक पहुंच सकते हैं। Jfriend00 द्वारा उल्लिखित ओवरहेड हमेशा मायने नहीं रखता है - कोड की स्पष्टता स्मृति या सीपीयू चक्रों की कुछ बाइट्स की तुलना में अधिक महत्वपूर्ण है, और प्रसार सिंटैक्स कभी-कभी उस संबंध में सबसे अच्छा विकल्प हो सकता है। मेरे छोटे कोड के लिए "समतल सरणी" के लिए विकल्प देखें ...
— मोरे

@ मोर मेरी टिप्पणी मार्च 2014 से है। ES5015 जून 2015 तक जारी नहीं किया गया था
— इंगो बुर्क

जवाबों:


92

हालाँकि , युक्ति में तर्क की सैद्धांतिक अधिकतम संख्या को सीमित करने के लिए कुछ भी विशिष्ट नहीं है (जैसा कि afortheye का उत्तर बताता है)। बेशक व्यावहारिक सीमाएँ हैं। ये सीमाएं पूरी तरह से कार्यान्वयन पर निर्भर हैं और सबसे अधिक संभावना है, यह इस बात पर भी निर्भर करेगा कि आप फ़ंक्शन को कैसे बुला रहे हैं।


मैंने एक प्रयोग के रूप में इस फिडेल को बनाया ।

function testArgs() {
    console.log(arguments.length);
}

var argLen = 0;
for (var i = 1; i < 32; i++) {
    argLen = (argLen << 1) + 1;
    testArgs.apply(null, new Array(argLen));
}

यहाँ मेरे परिणाम हैं:

  • Chrome 33.0.1750.154 m: अंतिम सफल परीक्षण 65535 तर्क था । उसके बाद यह विफल रहा:

    अनक्रेन्डेड रेंज: अधिकतम कॉल स्टैक आकार को पार कर गया

  • फ़ायरफ़ॉक्स 27.0.1: अंतिम सफल परीक्षण 262143 तर्क था । उसके बाद यह विफल रहा:

    RangeError: Function.prototyp.apply को दिए गए तर्क सरणी बहुत बड़े हैं

  • इंटरनेट एक्सप्लोरर 11: अंतिम सफल परीक्षण 131071 तर्क थे। उसके बाद यह विफल रहा:

    RangeError: SCRIPT28: स्टैक स्पेस से बाहर

  • ओपेरा 12.17: अंतिम सफल परीक्षण 1048576 तर्क था । उसके बाद यह विफल रहा:

    त्रुटि: Function.prototyp.apply: argArray बहुत बड़ी है

बेशक, यहां खेलने के अन्य कारक हो सकते हैं और आपके अलग-अलग परिणाम हो सकते हैं।


और यहाँ एक वैकल्पिक फिडेल का उपयोग करके बनाया गया है eval। फिर, आप अलग परिणाम प्राप्त कर सकते हैं।

  • Chrome 33.0.1750.154 m: अंतिम सफल परीक्षण 32767 तर्क था । उसके बाद यह विफल रहा:

    बिना सिंटैक्स ई-कार्ड: फ़ंक्शन कॉल में बहुत सारे तर्क (केवल 32766 अनुमत)

    यह एक विशेष रूप से दिलचस्प है क्योंकि क्रोम खुद को उलझन में लगता है कि वास्तव में कितने तर्कों की अनुमति है।

  • फ़ायरफ़ॉक्स 27.0.1: अंतिम सफल परीक्षण 32767 तर्क था । उसके बाद यह विफल रहा:

    स्क्रिप्ट बहुत बड़ी है

  • इंटरनेट एक्सप्लोरर 11: अंतिम सफल परीक्षण 32767 तर्क थे। उसके बाद यह विफल रहा:

    रेंजर्र: SCRIPT7: मेमोरी से बाहर

  • ओपेरा 12.17: अंतिम सफल परीक्षण 4194303 तर्क था । उसके बाद यह विफल रहा:

    स्मृति से बाहर; स्क्रिप्ट समाप्त हो गई।


यह भी खूब रही। यद्यपि यदि आप applyतर्क के रूप में उपयोग कर रहे हैं और भेज रहे हैं Array, तो प्रति युक्ति सैद्धांतिक अधिकतम 4,294,967,295 तत्व होंगे चाहे कोई भी व्यावहारिक सीमा हो (?)।
— ग्लैडस्टोन

1
आपका उदाहरण .apply()प्रश्न में दिखाए गए फ़ंक्शन तर्कों से अधिक से अधिक परीक्षण कर रहा है। वे जरूरी समान नहीं हैं। यहां एक डेमो है जहां मैंने Functionकंस्ट्रक्टर का उपयोग करके स्ट्रिंग से एक फ़ंक्शन बनाया है । फ़ंक्शन आपके फ़ंक्शन को आमंत्रित testArgs()करता है, यह 100,000 तर्कों को पारित करता है। उस फंक्शन को बनाने के साथ ही इसमें फेल हो जाता हैSyntaxError: too many function arguments
— कुकी राक्षस

@ cookiemonster आप सही हैं। कई अलग-अलग कारक हैं जो अधिकतम संख्या को सीमित कर सकते हैं, और इसे कॉल करने के लिए अलग-अलग तरीकों से अलग-अलग परिणाम मिल सकते हैं। मुझे लगता है कि मुझे पहले वाक्य पर थोड़ा और जोर देना चाहिए।
— 18

हाँ, यह सब निर्भर करता है कि ओपी के मन में क्या है। मैं एक समारोह में 100,000 तर्कों को टाइप करने की कल्पना नहीं कर सकता, इसलिए .apply()अधिक संभावना प्रतीत होगी। लेकिन तब उसने उल्लेख नहीं किया .apply(), इसलिए शायद वह कुछ काम करने की योजना बना evalरहा है।
— कुकी राक्षस

@ गोल्डस्टोनकीप सही। मेरे परीक्षण किसी दिए गए ब्राउज़र में अनुमानित व्यावहारिक सीमा का पता लगाने के बारे में हैं।
— 31

22

ECMAScript 5.1, भाग 8.8

सूची प्रकार का उपयोग फ़ंक्शन कॉल में, नई अभिव्यक्तियों में तर्क सूचियों (11.2.4 देखें) के मूल्यांकन की व्याख्या करने के लिए किया जाता है, और अन्य एल्गोरिदम में जहां मूल्यों की एक सरल सूची की आवश्यकता होती है .... ये क्रम किसी भी लम्बाई के हो सकते हैं।

इसलिए मानक में कोई सीमा नहीं है। बेशक, यदि आपका कोड वास्तविक दुनिया में चलता है, मानकों-भूमि में नहीं, तो स्पष्ट रूप से कुछ सीमा है (जैसे ब्रह्मांड में कणों की संख्या)।

किसी फ़ंक्शन को पैरामीटर पास करने के दो तरीके हैं।

  • "सचमुच": f(a, b, c)
  • आवेदन के साथ (): f.apply(null, [a, b, c])

यह उत्तरार्द्ध तरीका बड़े तर्क सूचियों के लिए अधिक यथार्थवादी परिदृश्य है।

अपने वर्तमान ब्राउज़र के लिए इनमें से प्रत्येक के लिए सीमाएँ देखने के लिए इस JSField पर जाएँ ।

मैंने स्वयं कुछ ब्राउज़र आज़माए:

           | apply() | literal
 ----------------------------
Chrome 14  | 131155  |  32767
Chrome 35  | 126213  |  65535
Firefox 30 | 500001  |  65535
IE 9       | 254335  |  65533
IE 10      | 253667  |  65533
IE 11      | 252447  |  65533
Opera 22   | 126063  |  65535
Safari 4   | 524215  | 524205
Safari 7   |  65537  | 522159

मैंने विभिन्न मशीनों पर इनमें से कई नंबरों में अंतर देखा, इसलिए मेरा मानना ​​है कि केवल ब्राउज़र (ओएस) के अलावा अन्य कारक भी हैं।


यह एक वास्तविक मुद्दा है, कुछ सामान्य ज्ञान नहीं है। एक वास्तविक दुनिया उदाहरण:

Google क्लोजर लाइब्रेरी ने निम्नलिखित फ़ंक्शन को परिभाषित किया।

goog.crypt.byteArrayToString = function(array) {
  return String.fromCharCode.apply(null, array);
};

यह केवल तभी काम करता है जब स्ट्रिंग की लंबाई तर्क की संख्या के लिए ब्राउज़र सीमा के भीतर थी जिसे साथ पारित किया जा सकता है Function.prototype.apply।

फ़ंक्शन को बाद में पैच किया गया था , जिससे फ़ंक्शन काफी जटिल हो गया था।


FYI करें, मार्च 2012 में एक खुला Webkit मुद्दा दायर किया गया है जो तर्क सीमा पर चर्चा करता है।


6

ईसीएमए स्क्रिप्ट केList अनुसार 5.1 मानक विशिष्टता ,

सूची प्रकार का उपयोग तर्क की सूची के मूल्यांकन (11.2.4 देखें) को नई अभिव्यक्तियों में, फ़ंक्शन कॉल में, और अन्य एल्गोरिदम में किया जाता है जहां मूल्यों की एक सरल सूची की आवश्यकता होती है। सूची प्रकार के मानों को केवल मूल्यों के क्रम का आदेश दिया जाता है। ये क्रम किसी भी लम्बाई के हो सकते हैं।

इसलिए, मानक में तर्कों की संख्या की कोई सीमा नहीं है और केवल मेमोरी द्वारा सीमित है।



1

यह पूरी तरह से निर्भर करता है कि ग्राहक कितना शक्तिशाली है।

क्योंकि ब्राउजर अपनी मेमोरी खो देगा, अगर आप लाखों तर्क पास करने वाले हैं।

प्रत्येक चर कुछ स्मृति रखता है। इसलिए ब्राउज़र को प्रत्येक चर को कुछ मेमोरी आवंटित करने में कोई समस्या नहीं होगी, जब तक कि उसके पास चलाने के लिए कोई मेमोरी न हो।


1

बस एक ही पैरामीटर के रूप में एक नक्शे (सिर्फ एक वस्तु) का उपयोग करें। आपको अभी भी पैरामीटर नामों का उपयोग करना है और आपके जितने चाहें उतने तर्क हो सकते हैं। यह आपको एक सैद्धांतिक अनंत संख्या के तर्क की गारंटी देता है जिसमें आप पास हो सकते हैं, हालांकि आप स्पष्ट रूप से अभी भी ढेर जगह से बंधे हुए हैं।

let infiniteParameters = (w) => console.table(w);

infiniteParameters({
  name1 : "value1",
  name2 : "value2",
  // ...
});

0

यहां बताया गया है कि मैं इसे कैसे जांचता हूं।

let args = [];

while(true){
    try{
        (() => {})(...args);
        args.push(0);
    }catch(e){
        console.log(e.message);
        console.log(`Number of arguments: ${args.length}`);
        break;
    }
}

0

एमडीएन के जावास्क्रिप्ट फंक्शन सेक्शन के अनुसार, किसी फंक्शन को स्वीकार करने वाले मापदंडों की अधिकतम मात्रा 255 हो सकती है ।

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions#Defining_functions

param The name of an argument to be passed to the function. A function can have up to 255 arguments.


उस अनुभाग को तब से हटा दिया गया है। शायद यह गलत था
— Drenai
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.