जावास्क्रिप्ट में [] .slice.call की व्याख्या?


197

मैं डोम नॉडलिस्ट को एक नियमित सरणी में परिवर्तित करने के लिए इस साफ-सुथरे शॉर्टकट पर अड़ गया, लेकिन मुझे मानना ​​होगा कि मैं पूरी तरह से नहीं समझता कि यह कैसे काम करता है:

[].slice.call(document.querySelectorAll('a'), 0)

तो यह एक खाली सरणी से शुरू होता है [], फिर एक नए सरणी sliceके परिणाम को callहां करने के लिए परिवर्तित करने के लिए उपयोग किया जाता है ?

बिट मुझे समझ में नहीं आता है call। यह document.querySelectorAll('a')एक नोडलिस्ट से एक नियमित सरणी में कैसे परिवर्तित होता है ?


5
Array.prototype.slice.call(document.querySelectorAll('a'));आपके द्वारा लिखे गए कोड का हिस्सा लिखने का एक उचित तरीका है।
vdegenne

4
BTW, उसी के लिए आधुनिक (और सहज ज्ञान युक्त) ES6 विधि है Array.from। तो जैसे यह वही करेगा: Array.from (document.querySelectorAll ('a'));
रग

जवाबों:


158

यहाँ क्या हो रहा है कि आप कॉल करते हैं slice()जैसे कि यह NodeListउपयोग करने का एक फ़ंक्शन था call()slice()इस मामले में जो करता है वह एक खाली सरणी बनाता है, फिर उस ऑब्जेक्ट के माध्यम से पुनरावृत्त करें जो मूल रूप से चल रहा है (मूल रूप से एक सरणी, अब एक NodeList) और उस ऑब्जेक्ट के तत्वों को उसके द्वारा बनाए गए खाली सरणी में जोड़े रखना, जो अंततः वापस आ गया है। यहाँ इस पर एक लेख है

संपादित करें:

तो यह एक खाली सरणी के साथ शुरू होता है [], फिर स्लाइस का उपयोग कॉल के परिणाम को एक नई सरणी में बदलने में किया जाता है?

यह सही नहीं है। [].sliceएक फ़ंक्शन ऑब्जेक्ट देता है। एक फ़ंक्शन ऑब्जेक्ट में एक फ़ंक्शन होता है call()जो फ़ंक्शन को पहले पैरामीटर को निर्दिष्ट करता call()है this; दूसरे शब्दों में, फ़ंक्शन को लगता है कि यह किसी सरणी के बजाय पैरामीटर ( NodeListद्वारा लौटाया गया document.querySelectorAll('a')) से बुलाया जा रहा है ।


59
यहाँ यह भी ध्यान दें कि यद्यपि यह शब्द कहने के बराबर है Array.prototype.slice.call(...), यह वास्तव में एक सरणी ऑब्जेक्ट ( []) को केवल अपने प्रोटोटाइप स्लोट विधि तक पहुंचने के लिए प्रेरित करता है। यह एक व्यर्थ की तात्कालिकता है। Array.prototype.slice.call(...)इसके बजाय कहना क्लीनर है, हालाँकि आप अपने जेएस में कई अक्षर जोड़ते हैं अगर आप गिनती कर रहे हैं ...
बेन झोट्टो

ध्यान दें कि आईई 8 में और नीचे केवल सरणी वस्तुओं पर यह काम करता है, तो आप नहीं कर क्लोन करने के लिए हो जाएगा NodeListरों
लिविंगस्टन शमूएल

5
@quixoto []अधिक विश्वसनीय है क्योंकि Arrayकुछ और के लिए ओवरराइट किया जा सकता है। यदि आपको पुन: उपयोग करने की आवश्यकता है Array#slice, तो इसे कैश करना एक अच्छा विचार है।
मथियास बिएनेंस

2
मामले में किसी और के लिए IE8 में ऐसा करने के लिए एक रास्ता देख रहा है, इस सवाल बाहर की जाँच करें stackoverflow.com/questions/3199588/…
Liam Newmarch

1
मैंने वास्तव में इस पैटर्न को backbone.js स्रोत कोड में देखा था: var array = []; var push = array.push; var slice = array.slice; var splice = array.splice;क्या वह सुरक्षा मुद्दे @MathiasBynens उल्लेख के लिए ऐसा करता है?
ओवेन्समार्टिन

125

जावास्क्रिप्ट में, किसी वस्तु के तरीके रनटाइम पर किसी अन्य वस्तु से बंधे हो सकते हैं। संक्षेप में, जावास्क्रिप्ट किसी वस्तु को किसी अन्य वस्तु की विधि को "उधार" लेने की अनुमति देता है:

object1 = {
    name: 'Frank',
    greet() {
        alert(`Hello ${this.name}`);
    }
};

object2 = {
    name: 'Andy'
};

// Note that object2 has no greet method,
// but we may "borrow" from object1:

object1.greet.call(object2); // Will show an alert with 'Hello Andy'

callऔर applyसमारोह वस्तुओं के तरीकों (जावास्क्रिप्ट में, कार्यों वस्तुओं रहे हैं और साथ ही) यदि आप ऐसा करने की अनुमति देता है। तो, अपने कोड में आप कह सकते हैं कि नोडलिस्ट एक सरणी के स्लाइस विधि को उधार ले रहा है। .slice()इसके परिणाम के रूप में एक और सरणी देता है, जो "परिवर्तित" सरणी बन जाएगा जिसे आप तब उपयोग कर सकते हैं।


जावास्क्रिप्ट वस्तु के कार्यों के लिए explanation अमूर्त अवधारणा स्पष्टीकरण पर बैंग। अब, आप स्वयं उर्फ के callकार्य के लिए इसे लागू कर सकते हैं । Array.prototype[].prototype
सौरभ

29

यह sliceएक से फ़ंक्शन को पुनः प्राप्त करता है Array। यह तब उस फ़ंक्शन को कॉल करता है, लेकिन वास्तविक सरणी के बजाय ऑब्जेक्ट के document.querySelectorAllरूप में परिणाम का उपयोग करता है this


19

यह सरणी-जैसी वस्तुओं को वास्तविक सरणियों में बदलने की एक तकनीक है।

इनमें से कुछ वस्तुओं में शामिल हैं:

  • arguments कार्यों में
  • नोडलिस्ट (याद रखें कि उनकी सामग्री लाने के बाद बदल सकती है! इसलिए उन्हें सरणी में परिवर्तित करना उन्हें फ्रीज करने का एक तरीका है)
  • jQuery के संग्रह, उर्फ ​​jQuery की वस्तुएं (कुछ डॉक्टर: एपीआई , प्रकार , सीखें )

यह कई उद्देश्यों को पूरा करता है, उदाहरण के लिए वस्तुओं को संदर्भ द्वारा पारित किया जाता है जबकि सरणियों को मूल्य से पारित किया जाता है।

इसके अलावा, ध्यान दें कि पहले तर्क को छोड़ दिया 0जा सकता है, पूरी तरह से यहाँ स्पष्टीकरण

और पूर्णता के लिए, jQuery.makeArray () भी है ।


15

कैसे document.querySelectorAll('a')एक NodeList से एक नियमित सरणी में परिवर्तित करता है ?

यह वह कोड है जो हमारे पास है,

[].slice.call(document.querySelectorAll('a'), 0)

पहले इसे नष्ट करने दें,

  []    // Array object
.slice // Accessing the function 'slice' present in the prototype of Array
.call // Accessing the function 'call' present in the prototype of function object(slice)
(document.querySelectorAll('a'),0) 
    // 'call' can have arguments like, (thisArg, arg1,arg2...n). 
   // So here we are passing the 'thisArg' as an array like object,
  // that is a 'nodeList'. It will be served as 'this' object inside of slice function.
 // And finally setting 'start' argument of slice as '0' and leaving the 'end' 
// argument as 'undefined'

चरण: 1 callकार्य का निष्पादन

  • अंदर call, के अलावा thisArg, बाकी तर्कों को एक तर्क सूची में जोड़ा जाएगा।
  • अब फ़ंक्शन sliceको इसके thisमान के रूप में बाध्य करके लागू किया जाएगा thisArg(जैसे ऑब्जेक्ट ऑब्जेक्ट से आया था document.querySelector) और तर्क सूची के साथ। यानी] तर्क startजिसमें सम्‍मिलित है0

चरण: 2 sliceकार्य का निष्पादन अंदर दर्ज किया गयाcall

  • startके sरूप में एक चर को सौंपा जाएगा0
  • के बाद endसे undefined, this.lengthमें संग्रहीत किया जाएगाe
  • एक खाली सरणी को एक चर में संग्रहीत किया जाएगा a
  • उपरोक्त सेटिंग्स करने के बाद निम्नलिखित पुनरावृत्ति होगी

    while(s < e) {
      a.push(this[s]);
      s++;
    }
  • भरे हुए सरणी aको परिणाम के रूप में लौटाया जाएगा।

PS हमारे परिदृश्य की बेहतर समझ के लिए हमारे संदर्भ के लिए आवश्यक कुछ कदमों को कॉल और स्लाइस के मूल एल्गोरिदम से अनदेखा किया गया है ।


1
बहुत अच्छा कदम से कदम स्पष्टीकरण। बहुत बढ़िया! धन्यवाद :)
किट्टू

1
अच्छी व्याख्या।
नवीन

7
[].slice.call(document.querySelectorAll('.slide'));

1. The querySelectorAll() method returns all elements in the document that matches a specified selector(s). 

2. The call() method calls a function with a given this value and arguments provided individually.

3. The slice() method returns the selected elements in an array, as a new array object.

  so this line return the array of [object HTMLDivElement]. Here is the six div with classname "slide" so array length will be 6.

<div class="slideshow">

  <div class="slide">
    first slider1
  </div>
  <div class="slide">
    first slider2
  </div>
  <div class="slide">
    first slider3
  </div>
  <div class="slide">
    first slider4
  </div>
  <div class="slide">
    first slider5
  </div>
  <div class="slide">
    first slider6
  </div>

</div>

<script type="text/javascript">

  var arraylist = [].slice.call(document.querySelectorAll('.slide'));

  alert(arraylist);

</script>

4

ES6 से: Array.from (element.children) या Array.from ({लंबाई: 5% ) के साथ बस सरणी बनाएं

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