2009-11-30 14 views
20

this question के उत्तरों में, हम पढ़ते हैं कि function f() {} स्थानीय रूप से नाम परिभाषित करता है, जबकि [var] f = function() {} इसे विश्व स्तर पर परिभाषित करता है। यह मेरे लिए सही मायने रखता है, लेकिन कुछ अजीब व्यवहार है जो दो घोषणाओं के बीच अलग है।जावास्क्रिप्ट: "ऑनलोड = फ़ंक्शन() {}" से अलग "फ़ंक्शन ऑनलोड() {}" कैसे है?

मैं स्क्रिप्ट

onload = function() { 
    alert("hello"); 
} 

साथ एक HTML पृष्ठ बना दिया है और यह उम्मीद के रूप में काम किया। जब मैंने इसे

function onload() { 
    alert("hello"); 
} 

कुछ भी नहीं हुआ। (फ़ायरफ़ॉक्स ने अभी भी घटना को निकाल दिया है, लेकिन वेबकिट, ओपेरा और इंटरनेट एक्सप्लोरर ने नहीं किया है, हालांकि स्पष्ट रूप से मुझे नहीं पता कि कौन सा सही है।)

दोनों मामलों में (सभी ब्राउज़रों में), मैं सत्यापित कर सकता हूं कि window.onload दोनों और onload फ़ंक्शन पर सेट किए गए थे। दोनों स्थितियों में, वैश्विक वस्तु this विंडो पर सेट है, और कोई फर्क नहीं पड़ता कि मैं घोषणा कैसे लिखता हूं, window ऑब्जेक्ट संपत्ति को ठीक से प्राप्त कर रहा है।

यहां क्या हो रहा है? एक घोषणा दूसरे से अलग क्यों काम करती है? क्या यह जावास्क्रिप्ट भाषा, डीओएम, या दोनों के बीच बातचीत का एक quirk है?

+1

मुझे संदेह है कि यह वेबकिट/ओपेरा में एक बग है और फ़ायरफ़ॉक्स का सही व्यवहार है। – Wogan

+0

न तो सही है। वैश्विक वस्तु (जिस पर 'विंडो' संदर्भित है) में होस्ट परिभाषित गुण हो सकते हैं (जैसे कि' ऑनलोड') और एक ईसीएमएस्क्रिप्ट 3 कार्यान्वयन ऐसी संपत्ति के व्यवहार को लागू करने के लिए स्वतंत्र है, जैसा कि यह उपयुक्त दिखता है, जिसमें आंतरिक '[[Put ]] 'विधि जिसे कहा जाता है जब संपत्ति का मूल्य असाइन किया जाता है। –

+0

फ़ायरफ़ॉक्स 3.5.5 में, अगर मैं 'onload = function() {...} का उपयोग करता हूं, तो मुझे अलर्ट दिखाई देता है, लेकिन' var onload = function() {...}; ' –

उत्तर

4

यह दो स्निपेट वर्तमान कॉल में "ऑनलोड" नामक एक फ़ंक्शन घोषित करते हैं। कोई बाध्यकारी नहीं किया जाता है।

function onload() { ... } 

var onload = function() { ... } 

यह टुकड़ा एक संपत्ति/चर/वर्तमान क्षेत्र पर "ऑनलोड" नाम क्षेत्र के लिए एक समारोह प्रदान करती है:

onload = function() { ... } 

कारण है कि फ़ायरफ़ॉक्स 1 पर बाध्यकारी प्रदर्शन किया और ऑनलोड घटना उठाया स्निपेट और अन्य नहीं हो सकते थे क्योंकि फ़ायरफ़ॉक्स क्रोम (इसका यूजर इंटरफेस) स्वयं जावास्क्रिप्ट का उपयोग करके लिखा और स्वचालित है - यही कारण है कि यह इतना लचीला और विस्तार करने के लिए आसान है। किसी भी तरह, जब आपने स्थानीय रूप से स्कॉप्ड onload फ़ंक्शन को इस तरह से फ़ंक्शन किया, तो फ़ायरफ़ॉक्स ने window (उस समय स्थानीय संदर्भ में उस समय स्थानीय संदर्भ) onload (उस समय, एक खाली फ़ंक्शन या अपरिभाषित) के कार्यान्वयन को प्रतिस्थापित किया, जबकि दूसरा ब्राउज़र एक और दायरे में घोषणा "सैंडबॉक्स" सही ढंग से (कहते हैं, global या कुछ)।

foo(); 
var foo = function(){}; 

यह नहीं करता है::

foo(); 
function foo(){} 

दूसरा वाक्य रचना इसलिए अच्छे है जब आप modularize और अपने कोड को व्यवस्थित करने के कार्यों का उपयोग कर रहे हैं, जबकि पहले

+0

अच्छा अवलोकन कि फ़ायरफ़ॉक्स * जावास्क्रिप्ट में लिखा गया है। –

+1

अच्छा, पूरी तरह से नहीं, लेकिन उसके अधिकांश क्रोम (उपयोगकर्ता इंटरफ़ेस) है। –

0
var onload = function() { 
    alert("hello"); 
} 

इसे स्थानीय रूप से भी घोषित करेगा।

मेरा सुझाव है कि आप इस बहुत उपयोगी लेख पढ़ने के लिए: http://kangax.github.io/nfe/

+2

यह एक अच्छा लेख है, लेकिन यह सवाल का जवाब नहीं देता है। –

4

बहुत से लोग सही ढंग से (अद्यतन: उन जवाब ज्यादातर उनके लेखकों द्वारा हटा दिया गया है अब) के बीच वैश्विक/स्थानीय अंतर बाहर ओर इशारा करते हैं

var x = function() { 

और

function x() { 

लेकिन वह वास्तव में उत्तर नहीं मिलता है अपने विशिष्ट सवाल यह है कि आप वास्तव में इनमें से पहला नहीं कर रहे हैं।

अपने उदाहरण में दोनों के बीच अंतर यह है:

// Adds a function to the onload event 
onload = function() { 
    alert("hello"); 
} 

जबकि

// Declares a new function called "onload" 
function onload() { 
    alert("hello"); 
} 
+0

शायद ऐसा इसलिए है क्योंकि उत्तरार्द्ध पार्स टाइम पर मूल्यांकन किया जाता है, इसलिए 'विंडो' ऑब्जेक्ट अभी तक ईवेंट स्वीकार करने के लिए तैयार नहीं है? –

+0

"ऑनलोड" नामक फ़ंक्शन को स्पष्ट रूप से ऑनलोड ईवेंट से बाध्य नहीं करता है - इसलिए आपको "ऑनलोड" ईवेंट होने पर फ़ंक्शन को "ऑनलोड" कॉल करने के लिए अभी भी ब्राउज़र को बताना होगा (हालांकि कुछ ऐसा करने के लिए मान सकते हैं) । – Fenton

+0

वास्तव में? 'Window.onload' पर फ़ंक्शन असाइन करना मेरे अनुभव में अच्छी तरह से काम करता है। –

1

यहाँ मैं क्या सोचते हैं, पर जा रहा है टिम डाउन मददगार टिप्पणियाँ और जोनाथन पेन के साथ एक संक्षिप्त चर्चा के आधार पर :

जब जावास्क्रिप्ट दुभाषिया window.onload संपत्ति को असाइन करता है, तो यह उस ऑब्जेक्ट से बात कर रहा है जिसे ब्राउज़र ने दिया है। वह सेटर जो यह नोटिस करता है कि संपत्ति को onload कहा जाता है, और इसलिए बाकी ब्राउज़र पर जाता है और उपयुक्त घटना को तार देता है। यह सब जावास्क्रिप्ट के दायरे से बाहर है - स्क्रिप्ट सिर्फ यह देखती है कि संपत्ति सेट की गई है।

जब आप एक घोषणा function onload() {} लिखते हैं, तो सेटटर को उसी तरह से नहीं बुलाया जाता है।चूंकि घोषणा पार्स समय पर मूल्यांकन करने का कारण बनती है, मूल्यांकन समय नहीं, स्क्रिप्ट दुभाषिया आगे बढ़ता है और ब्राउज़र को बताए बिना चर बनाता है; या फिर विंडो ऑब्जेक्ट घटनाओं को प्राप्त करने के लिए तैयार नहीं है। जो भी हो, ब्राउजर को असाइनमेंट देखने का मौका नहीं मिलता है जब आप onload = function() {} लिखते हैं, जो सामान्य सेटर रूटीन के माध्यम से जाता है।

-1

यह एक त्रुटि उत्पन्न करता है सिंटैक्स फ़ंक्शन-ए-डेटा प्रतिमान के लिए अच्छा है।

+0

यह [var functionName = function() {} बनाम फ़ंक्शन फ़ंक्शननाम() {}] का एक उत्तर है (http://stackoverflow.com/questions/336859/var-functionname-function-vs-function-Functionname); यह * इस * प्रश्न का उत्तर नहीं देता है, जो 'विंडो' पर ईवेंट बाइंडिंग के बारे में है। – apsillers

0

सरल व्याख्या:

function aaaaaaa(){ 

पहले यह declarated है इस्तेमाल किया जा सकता:

aaaaaaa(); 
function aaaaaaa(){ 

} 

लेकिन यह काम नहीं करता:

aaaaaaa(); 
aaaaaaa=function(){ 

} 

ऐसा इसलिए है क्योंकि तीसरे कोड में है , आप एक अज्ञात फ़ंक्शन को aaaaaaa असाइन कर रहे हैं, इसे फ़ंक्शन के रूप में घोषित नहीं कर रहे हैं।

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