2012-11-22 11 views
7

मान लिया जाये कि मैं इस समारोह है, जो (कुछ अजीब कारण के लिए) फोन करने वाले के लिए अपनी arguments ऑब्जेक्ट था:क्या तर्क लीक ऑब्जेक्ट करता है?

function example(a, b/* ...*/) { 
    var c = // some processing 
    return arguments; 
} 

एक मंगलाचरण (var d=example();) example की चर वातावरण को रोकने का परिणाम भंडारण करता है (a युक्त, b, c आदि) कचरे से एकत्र होने से? Arguments object के आंतरिक सेटर्स और गेटर्स अभी भी इसे बंद कर सकते हैं, जैसे बंद होने से वापस किए गए फ़ंक्शन की तरह।

मुझे पता है कि शायद ही कभी उपयोग का मामला है (और तर्कों के चारों ओर गुजरना बुरा अभ्यास माना जाता है, अधिकांशतः सरणी की समानता के कारण), लेकिन यह एक सैद्धांतिक सवाल है। विभिन्न EcmaScript कार्यान्वयन कैसे संभालते हैं?

+0

'तर्क' के बारे में अजीब चीज यह है कि नामित पैरामीटर वास्तव में छद्म-सरणी के तत्वों के लिए ** उपनाम ** हैं। कोशिश करो! यदि आप 'तर्क [0]' बदलते हैं, तो 'ए' भी बदल जाएगा! मुझे नहीं लगता कि यह उस कारण से लीक है। – Pointy

+1

वास्तव में? मैंने सोचा कि यह दूसरा रास्ता था: 'तर्क' [0] '''' के लिए उपनाम है :-) spec में वर्णित एल्गोरिदम इंगित करता है कि 'तर्क' के सूचकांक" पैरामीटर मैप "के साथ सेटर्स और गेटर्स थे आमंत्रण के पर्यावरण रिकॉर्ड से लिंक - इमो को रिसाव करने का एक संभावित कारण। यही कारण है कि मैं वास्तविक कार्यान्वयन के बारे में भी पूछ रहा हूं ... – Bergi

+0

ठीक है मुझे लगता है कि यह एक रहस्य है जो एक उपनाम है जिसके लिए :-) मैं जो सोच रहा हूं वह यह है कि तर्क मूल रूप से ** ** ** है पैरामीटर का सेट, इसे बंद करने या किसी भी संदर्भ के संदर्भ की आवश्यकता नहीं है, इसलिए स्मृति का उपयोग करने के अलावा यह सीधे कुछ भी "पिन" नहीं करता है। हालांकि, यह सिर्फ एक झटका है, और मुझे असली कहानी नहीं पता है। – Pointy

उत्तर

3

इस पर विचार करें:

var x = function() { 
    return arguments; 
} 
console.log(x() === x()); 

यह गलत है क्योंकि यह एक ही arguments वस्तु नहीं है: यह है सब के भीतर संग्रहीत पैरामीटर के है कि मूल्यों एक नवनिर्मित वस्तु (x से प्रत्येक invokation के लिए)। अभी तक यह arguments का गुण है:

var y = x([]); 
console.log(y instanceof Object); // true 
console.log(y instanceof Array); // false 
console.log(y.length); // 1 
console.log(y.callee + '');  // function() { return arguments; } 

फिर भी वहाँ यह करने के लिए अधिक है। जाहिर है, वस्तुओं समारोह में भेजा के रूप में अपनी परम जी सी द्वारा एकत्र नहीं किया जाएगा अगर arguments लौटा दिए जाते हैं:

var z = x({some: 'value'}); 
console.log(z[0]); // {some:'value'} 

यह आशा की जाती है: सब के बाद, आप, समारोह के अंदर कुछ स्थानीय वस्तु की घोषणा के द्वारा समान परिणाम प्राप्त कर सकते हैं बताए फ़ंक्शन के पहले पैरामीटर का मान अपनी ऑब्जेक्ट '0' प्रॉपर्टी के रूप में, फिर इस ऑब्जेक्ट को वापस कर रहा है। दोनों स्थितियों में संदर्भित वस्तु अभी भी "उपयोग में" होगी, इसलिए मुझे लगता है कि कोई बड़ा सौदा नहीं है।

लेकिन इसके बारे में क्या?

var globalArgs; 
var returnArguments = function() { 
    var localArgs = arguments; 
    console.log('Local arguments: '); 
    console.log(localArgs.callee.arguments); 
    if (globalArgs) { // not the first run 
    console.log('Global arguments inside function: '); 
    console.log(globalArgs.callee.arguments); 
    } 
    return arguments; 
} 
globalArgs = returnArguments('foo'); 
console.log('Global arguments outside function #1: '); 
console.log(globalArgs.callee.arguments); 
globalArgs = returnArguments('bar'); 
console.log('Global arguments outside function #2: '); 
console.log(globalArgs.callee.arguments); 

आउटपुट:

Local arguments: ["foo"] 
Global arguments outside function #1: null 
Local arguments: ["bar"] 
Global arguments inside function: ["bar"] 
Global arguments outside function #2: null 

जैसा कि आप देख, आप arguments खुद के रूप में डेटा का एक ही सेट करने के लिए arguments वस्तु लौट सकते हैं और अपने callee.argument संपत्ति अंक, कुछ चर के लिए असाइन करें समारोह के अंदर अगर; यह फिर से, उम्मीद है। लेकिन फ़ंक्शन variable.callee.arguments के बाहर शून्य (अपरिभाषित) के बराबर है।

+0

'variable.callee.arguments'' तर्क 'के समान नहीं है, यह एक गैर-मानक निर्माण है। [इस सवाल] का मेरा जवाब देखें (http://stackoverflow.com/q/11939736/825789)। – bfavaretto

0

किसी विशेष जावास्क्रिप्ट इंजन में कोई शोध किए बिना इसे निष्कर्ष निकालना मुश्किल है। हालांकि मैं तर्क दूंगा कि argumentsObject और example द्वारा निर्मित संदर्भ किसी अन्य स्थानीय चर और उसके होस्ट संदर्भ के समान है।

यह कहने के लिए, मूल्य को संग्रहीत करने के लिए इसके संदर्भ को भी संग्रहीत करने की आवश्यकता नहीं है।

एक चेतावनी arguments.callee संपत्ति जो संदर्भ (अर्थात Function) जो किसी दिए गए argumentsObject के लिए बाध्य है के लिए एक संदर्भ है।हालांकि यह संपत्ति सख्त मोड में मौजूद नहीं है और has been deprecated भी मौजूद नहीं है।

इसके अलावा मुझे लगता है कि यह मानना ​​सुरक्षित है कि argumentsObject लौटने और संग्रहीत करने से स्मृति रिसाव नहीं होगा।

+0

'argument.callee' सिर्फ 'example' फ़ंक्शन का संदर्भ देता है, है ना? मैं 'उदाहरण' के निष्पादन संदर्भ में केवल अन्य मूल्यों के बारे में पूछ रहा था, जैसे 'सी'। – Bergi

+0

हां यही वह करता है। मुझे सच में यकीन नहीं है कि आपका बिंदु क्या है। एक स्थानीय चर (जैसे 'c') को 'तर्क' ऑब्जेक्ट' में संदर्भित नहीं किया जाएगा। – FK82

+0

निश्चित रूप से, लेकिन यह सवाल है। 'तर्क' ऑब्जेक्ट के बारे में [spec] पढ़ना [http://es5.github.com/#x10.6), तर्क ऑब्जेक्ट के आंतरिक गेटर्स/सेटर्स वेरिएबल पर्यावरण रिकॉर्ड ('c' सहित) का संदर्भ देते हैं। – Bergi

संबंधित मुद्दे