2013-05-14 5 views
8

मान लीजिए मैं है निम्नलिखित कोड (पूरी तरह से बेकार, मुझे पता है)इसे सुरक्षित '(लागू)'

function add(a, b, c, d) { 
    alert(a+b+c+d); 
} 

function proxy() { 
    add.apply(window, arguments); 
} 

proxy(1,2,3,4); 

असल में, हम जानते हैं कि लागू दूसरा पैरामीटर के रूप में एक सरणी की उम्मीद करने के लिए 'तर्क' पारित करने के लिए है , लेकिन हम यह भी जानते हैं कि arguments एक उचित सरणी नहीं है। कोड अपेक्षा के अनुसार काम करता है, तो क्या यह कहना सुरक्षित है कि मैं किसी भी सरणी जैसी वस्तु को apply() में दूसरे पैरामीटर के रूप में पास कर सकता हूं?

निम्नलिखित भी (क्रोम में कम से कम) काम करेगा:

function proxy() { 
    add.apply(window, { 
    0: arguments[0], 
    1: arguments[1], 
    2: arguments[2], 
    3: arguments[3], 
    length: 4 
    }); 
} 

अद्यतन: ऐसा लगता है कि मेरी दूसरी कोड ब्लॉक आईई < 9 में विफल रहता है, जबकि पहले एक (arguments गुजर) काम करता है। त्रुटि Array or arguments object expected है, इसलिए हम निष्कर्ष निकालेंगे कि arguments पास करना हमेशा सुरक्षित है, जबकि पुरानी आईई में एक सरणी जैसी वस्तु को पास करना सुरक्षित नहीं है।

+1

क्यों _wouldn't_ "सुरक्षित" नहीं होगा? – Neal

+0

@ नील अच्छी तरह से 'तर्क' एक सुंदर अजीब जानवर है, इसलिए इसके उपयोग के बारे में कुछ भयावहता अनुचित नहीं है। इस मामले में मैं कल्पना नहीं कर सकता कि यह एक समस्या कैसे होगी। – Pointy

+0

@Neal, शायद क्योंकि 'तर्क' में सामान्य ऐरे के कई तरीके नहीं हैं, और '.apply' उनका उपयोग करना चाह सकता है? – Dogbert

उत्तर

3

ईसीएमएस्क्रिप्ट 5.1 मानते हैं: हां। ईसीएमए -262, 10.6 के अनुसार, तर्क वस्तु में length और सूचकांक गुण हैं जो 15.3.4.3 (Function.prototype.apply) की आवश्यकता है।

+0

यह सबसे छोटा जवाब है लेकिन वास्तव में सुरक्षितता के मामले पर बहुत ही स्पॉट-ऑन है .. क्या आप जानते हैं कि मेरा दूसरा टेस्ट कोड गैर- ECMASCRIPT 5 आईई (

+2

ओह आईई स्पष्ट रूप से कहता है: 'ऐरे या तर्क ऑब्जेक्ट अपेक्षित' तो मुझे लगता है कि 'तर्क' पास करना सुरक्षित है, सरणी जैसी वस्तुओं को पास करने के लिए सुरक्षित नहीं है –

7

Function.prototype.apply की परिभाषा से में MDN:

fun.apply(thisArg[, argsArray])

तुम भी argsArray पैरामीटर के लिए arguments उपयोग कर सकते हैं। arguments एक एक समारोह के स्थानीय चर है। इसका उपयोग ऑब्जेक्ट के सभी अनिर्दिष्ट तर्कों के लिए किया जा सकता है। इस प्रकार, जब आप apply विधि का उपयोग करते हैं तो आपको कॉल किए गए ऑब्जेक्ट के तर्कों को जानने की आवश्यकता नहीं है। आप कॉल किए गए ऑब्जेक्ट के सभी तर्कों को पारित करने के लिए arguments का उपयोग कर सकते हैं। ऑब्जेक्ट कहलाता है तो तर्कों को संभालने के लिए जिम्मेदार होता है।

REF:https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Function/apply

दूसरा तर्क apply रूप "तर्कों जिसके साथ समारोह बुलाया जाना चाहिए निर्दिष्ट करने, वस्तु की तरह एक सरणी" स्वीकार करता है। मेरी समझ के लिए, इस सरणी जैसी वस्तु में length आंतरिक पुनरावृत्ति के लिए संपत्ति होनी चाहिए, और मूल्यों तक पहुंचने के लिए संख्यात्मक रूप से परिभाषित गुण (शून्य-अनुक्रमित) होना चाहिए।

और एक ही मेरी कल्पना की पुष्टि की है: http://www.ecma-international.org/ecma-262/5.1/#sec-15.3.4.3, के रूप में किया गया था कृपया @Pointy से बताया।

+2

भी [spec के खंड 15.3.4.3] (http://www.ecma-international.org/ecma-262/5.1/#sec-15.3.4.3) यह स्पष्ट रूप से स्पष्ट करता है कि 'लागू' केवल 'लंबाई' और क्रमांकित (अनुक्रमित) गुणों के मान को देखता है। – Pointy

+0

@ पॉइंटी मुझे यह चाहिए * * इस तरह से काम करना चाहिए:: ' – VisioN

1

एमडीएन केवल मोज़िला कार्यान्वयन के लिए बात कर सकता है।

15.3.4.3 Function.prototype.apply (thisArg, argArray) 

When the apply method is called on an object func with arguments thisArg and 
argArray, the following steps are taken: 

1. If IsCallable(func) is false, then throw a TypeError exception. 
2. If argArray is null or undefined, then 
     Return the result of calling the [[Call]] internal method of func, 
     providing thisArg as the this value and an empty list of arguments. 
3. If Type(argArray) is not Object, then throw a TypeError exception. 
4. Let len be the result of calling the [[Get]] internal method of argArray 
     with argument "length". 
5. If len is null or undefined, then throw a TypeError exception. 
6. Let n be ToUint32(len). 
7. If n is not equal to ToNumber(len), then throw a TypeError exception. 
8. Let argList be an empty List. 
9. Let index be 0. 
10. Repeat while index < n 
     a. Let indexName be ToString(index). 
     b. Let nextArg be the result of calling the [[Get]] internal method of 
     argArray with indexName as the argument. 
     c. Append nextArg as the last element of argList. 
     d. Set index to index + 1. 
11. Return the result of calling the [[Call]] internal method of func, 
     providing thisArg as the this value and argList as the list of arguments. 

The length property of the apply method is 2. 

NOTE The thisArg value is passed without modification as the this value. This 
    is a change from Edition 3, where an undefined or null thisArg is replaced 
    with the global object and ToObject is applied to all other values and that 
    result is passed as the this value. 

ऐसा लगता है कि संपत्ति length और संख्यात्मक इंडेक्स मान केवल आवश्यक शर्तें हैं: वास्तविक spec जो करने के लिए सभी कार्यान्वयन का पालन करना चाहिए निम्नलिखित कहते हैं।

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