2010-02-14 17 views
24

मूल स्रोत: http://twitter.com/tobeytailor/status/8998006366क्या कोई इस जावास्क्रिप्ट विधि को समझा सकता है?

(x=[].reverse)() === window // true 

मैंने देखा है कि इस व्यवहार सभी देशी प्रकार प्रभावित करता है। यहाँ क्या हो रहा है?

+1

'[] .reverse.call (y) === y' सभी स्केलर्स' y' के लिए। – kennytm

+4

* मैंने देखा है कि यह व्यवहार ... * क्या व्यवहार? – Cheeso

उत्तर

40

यह अजीब तरीके से this जावास्क्रिप्ट में बाध्यकारी कार्यों के साथ करना है।

[].reverse 

एक खाली सूची पर reverse विधि है। आप, इसे कहते में से एक के माध्यम से हैं:

[].reverse(); 
[]['reverse'](); 
([].reverse)(); 

तो यह this सूची उदाहरण [] करने के लिए बाध्य के साथ निष्पादित करता है। लेकिन आप इसे अलग करता है, तो:

x= [].reverse; 
x(); 

यह, कोई this -binding साथ निष्पादित करता है तो वैश्विक (window) वस्तु के लिए समारोह अंक में this, जावास्क्रिप्ट का सबसे खराब, सबसे भ्रामक डिजाइन गलतियों में से एक में।

(x=[].reverse)() 

भी अलग करना है। असाइनमेंट ऑपरेटर वही फ़ंक्शन ऑब्जेक्ट देता है जो इसे पारित किया गया था, ऐसा लगता है कि यह कुछ भी नहीं कर रहा है, लेकिन इसका सीमित विशेष मामला तोड़ने का दुष्प्रभाव है जो जावास्क्रिप्ट को this से बांधने का कारण बनता है।

तो तुम कह रहे हैं:

Array.prototype.reverse.call(window) 

reverse, कई अन्य Array.prototype तरीकों की तरह, किसी भी देशी अनुक्रम जैसी वस्तु पर काम करने के ECMAScript द्वारा परिभाषित किया गया है। यह संख्या-स्ट्रिंग कुंजियों के साथ आइटम को उलट देता है (object.length तक) और ऑब्जेक्ट देता है। तो यह किसी भी प्रकार के लिए पारित ऑब्जेक्ट को वापस कर देगा जिसमें length संपत्ति है।

window लंबाई संपत्ति है, जो window.frames.length से मेल खाती है, तो window पर this की ओर इशारा करते के साथ इस विधि बुला काम करते हैं और window वापस आ जाएगी है। सिद्धांत में यह अभी भी असफल हो सकता है, क्योंकि:

  1. window को "मूल वस्तु" के बजाय "होस्ट ऑब्जेक्ट" होने की अनुमति है; इस मामले में आप अन्य प्रोटोटाइप के तरीकों से गुजरने के बारे में गारंटी जरूरी नहीं है; और
  2. यदि खिड़की में वास्तव में फ्रेम/आइफ्रेम हैं, तो यह उनके आदेश को उलट करने का प्रयास करेगा, जो काम नहीं करेगा क्योंकि फ्रेम संग्रह केवल पढ़ने के लिए है।

हालांकि, वर्तमान ब्राउज़र में पूर्व केस काम करता है और बाद में बिना किसी त्रुटि के चुपचाप विफल रहता है, इसलिए आपको अभी भी ===window व्यवहार प्राप्त होता है और अपवाद नहीं होता है।

+1

क्या आपको पता है कि ऐसा क्यों है कि कोई इसे कोड करेगा? मेरा मतलब है, मैं समझता हूं कि प्रभाव क्यों होता है, लेकिन मैं इसे अपने कोड में क्यों रखूंगा? यह क्या हासिल करता है? – Pointy

+3

बिलकुल कुछ भी नहीं। यह सिर्फ जावास्क्रिप्ट के कई अप्रत्याशित व्यवहारों में से एक दिखा रहा है।अगर मुझे यह वास्तविक कोड में मिला तो मुझे चिंता होगी! – bobince

+2

ऐसा करने का एक संभावित कारण यह जांचना हो सकता है कि विंडो ऑब्जेक्ट के साथ गड़बड़ की गई कुछ अन्य स्क्रिप्ट ('window = open ('http://google.com/') 'पर्याप्त है)। 'var window = (x = []। रिवर्स)(); 'इसे स्थानीय रूप से पुनर्स्थापित कर सकता है। – silviot

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