2012-06-07 26 views
9

मैं इस स्क्रिप्ट कहीं और देखा, और यह जाँच करेगा हर एक चेक बॉक्स:"[] .forEach"

[].forEach.call(document.querySelectorAll('input[type="checkbox"]'),function(el){ 
     el.checked=true; 
    } 
);​ 

मैं जानता हूँ कि forEach का उपयोग कैसे करें:

[0,1,2].forEach(function(num){ 
    console.log(num); 
}); 

//0 
//1 
//2 

लेकिन अब , यह [].forEach है, और अंदर कुछ भी नहीं है। तो यह अभी भी क्यों काम करता है? मैं इसके बजाय ऐसा क्यों नहीं कर सकता?

document.querySelectorAll('input[type="checkbox"]').forEach(function(el){ 
     el.checked=true; 
    } 
);​ 
+0

आप कर सकते हैं। प्रतिबिंब के माध्यम से पहला होता है। 'कॉल' और 'लागू करें 'की जांच करें। – entonio

+2

ध्यान दें कि यह '[] .forEach.call (नोडलिस्ट, एफएन)' तकनीक ** IE8 ** में काम नहीं करता है, इसलिए आप सामान्य परिस्थितियों में इसका उपयोग नहीं कर सकते हैं। –

+1

आप * querySelectorAll' के परिणामस्वरूप इसका उपयोग करने के लिए विधि को जोड़ सकते हैं, लेकिन यह खतरे से भरा सड़क है। 'NodeList.prototype.forEach = HTMLCollection.prototype.forEach = Array.prototype.forEach;' –

उत्तर

10

जावास्क्रिप्ट में प्रथम श्रेणी के कार्य हैं; यानी, वे वस्तुओं की तरह व्यवहार कर रहे हैं, और उनके अपने गुण और विधियां हो सकती हैं। Function.call विधि में निर्मित this पैरामीटर के लिए पहला तर्क के रूप में कार्य करता है, और शेष तर्क फ़ंक्शन पर ही पास किए जाते हैं। विधि (कम संक्षिप्त, बहुत कम उपयोग) तक पहुंचने के साधन के अलावा सरणी [] का उपयोग नहीं किया जाता है।

यह मूल रूप से Array.forEach का उपयोग करने के लिए एक सरणी नहीं है, इस मामले में NodeListNodeList एक forEach विधि की पेशकश की है, तो यह के बराबर होगा, और आप, इस रूप में यह पढ़ सकते हैं:

document.querySelectorAll('input[type="checkbox"]').forEach(function(el) { 
    el.checked = true; 
});​ 

तो, गहराई में एक छोटे से अधिक। call एक अलग संदर्भ के साथ एक समारोह निष्पादित करेगा। forEach संदर्भ पर पुनरावृत्त करता है और फ़ंक्शन को कॉल करता है जिसे इसे इसके तर्क के रूप में पारित किया जाता है। इसलिए someFunc.call(thisArg, otherArg) निष्पादित किया जाएगा जैसे कि यह thisArg के संदर्भ में था, जैसे thisArg.someFunc(otherArg)। यहाँ सबसे सरल उदाहरण है:

function callMe(something) { 
    return something + this; 
} 

callMe('Hello'); // Hellonull or Hello[object Window] or something 
callMe.call({}, 'World'); // World[object Object] 

apply() उसी तरह काम करता है, लेकिन आप दूसरा तर्क के रूप में तर्क की एक सरणी गुजरती हैं।

+0

क्या रुको? तो यह 'ऐरे' के बजाय एक 'नोडलिस्ट' है? क्या 'नोडलिस्ट' * * एक 'ऐरे' नहीं है? –

+2

नहीं, एक 'नोडलिस्ट' * नहीं * एक 'ऐरे' है। हालांकि, मूल रूप से, यह सिर्फ 'ऐरे' की तरह व्यवहार करता है - इसमें संख्यात्मक सूचकांक और 'लंबाई' संपत्ति होती है। यह सिर्फ मानक 'ऐरे' विधियों का वारिस नहीं करता है। हालांकि, अगर 'विधि' को केवल अनुक्रमण और 'लंबाई' की आवश्यकता है, तो यह काम करेगा, यही कारण है कि कोड का यह विशेष स्निपेट मान्य है। –

+0

@ टिखोन जेल्विस - तो यह 'ऐरे' के तरीकों के बिना 'ऐरे' है। समझा। –

3

.call पर ध्यान दें। यह document.querySelectorAll से forEach के परिणामों पर लागू होता है (this पर सेट करता है) ताकि यह डॉट के बाईं ओर (खाली) सरणी के बजाय उन परिणामों पर पुनरावृत्त हो सके।

4

यह forEach फ़ंक्शन पाने के लिए बस [] का उपयोग कर रहा है। एक बार यह कार्य हो जाने पर, यह .call का उपयोग करता है ताकि इसे कॉल किया जा सके जैसे कि यह document.querySelectorAll('input[type="checkbox"]') का तरीका था।

यह उपयोगी है क्योंकि document.querySelectorAll का परिणाम Array नहीं है लेकिन एक जैसा व्यवहार करता है, इसलिए हम मानक Array विधियों का पुन: उपयोग कर सकते हैं।

जब आप .call का उपयोग करते हैं, तो पहला तर्क this मान के रूप में उपयोग किया जाता है। यही है, इस विशेष स्निपेट में, हर बार thisforEach के स्रोत के अंदर सामने आया है, यह document.querySelectorAll('input[type="checkbox"]') पर सेट है।

तुम बस document.querySelectorAll('input[type="checkbox"]').forEach(... सीधे कॉल नहीं कर सकते क्योंकि querySelectorAllनहीं वापसी एक Array वस्तु करता है और इसलिए एक forEach विधि नहीं है।.call चीज forEachपर कॉल करके इसे पाने का एक तरीका है जैसे कि यह NodeList का एक तरीका था, जो वास्तव में वापस आ गया है।