2012-02-27 12 views
35

मैं बहुत उलझन में हूं कि कैसे रचनाकार जावस्क्रेट में काम करते हैं; कई वर्षों तक भाषा का उपयोग करने के बावजूद (ज्यादातर जैसे कि यह एलआईएसपी के अर्द्ध अनिवार्य संस्करण की तरह था) मैं इस बारे में अधिक जानना चाहता हूं कि वस्तुओं को कैसे काम करना चाहिए।जावास्क्रिप्ट में 'नया' क्या करता है, वैसे भी?

function Foo(x) { 
    return { 
     bar: function() { return x; } 
    }; 
} 

myFoo = Foo(5) और myFoo = new Foo(5) बुला बीच क्या अंतर है:

इस कोड को देखते हुए? या, दूसरे शब्दों में, जावास्क्रिप्ट में कोई कन्स्ट्रक्टर वास्तव में क्या करता है?

+13

और यदि वे उन Google खोज परिणामों को समझ में नहीं आये, और यहां एक बेहतर स्पष्टीकरण की उम्मीद कर रहे थे, तो आपकी स्नैकी टिप्पणी उन्हें कितनी अच्छी तरह से करती है? –

+0

@ChrisSobolewski क्योंकि अगर हम नहीं जानते कि ओपी इसके बारे में क्या समझ में नहीं आता है, तो हम उसकी मदद कैसे कर सकते हैं? अगर हम नहीं जानते कि अस्पष्ट क्या है तो हम चीजों को कैसे स्पष्ट कर सकते हैं? – Jeff

+0

@ChrisSobolewski, कुछ लोग भूल जाते हैं कि इस साइट का उद्देश्य उन चीजों को साफ़ करना है जिन्हें आप समझ में नहीं आते हैं। सिर्फ इसलिए कि सटीक जानकारी उपलब्ध है और आप इसे समझते हैं। यह साइट चीजों को साफ़ करने के लिए मेरे लिए पूरी तरह से काम करती है। –

उत्तर

44

myFoo = Foo(5) और myFoo = new Foo(5) पर कॉल करने के बीच क्या अंतर है?

उस कोड के लिए कोई फर्क नहीं है, क्योंकि यह एक वस्तु देता है, और spec का कहना है:

  • परिणाम [[कॉल]] आंतरिक बुला का नतीजा हो चलो एफ की संपत्ति, objthis मूल्य के रूप में प्रदान करते हुए और तर्क सूची प्रदान करते हुए [[निर्माण]] तर्क के रूप में प्रदान किया गया।
  • यदि Type(result)Object है तो परिणाम पर लौटें।

के बाद से है कि समारोह एक परिणाम के एक वस्तु है कि देता है, उसके परिणाम प्रयोग किया जाता है। आप एक अंतर नोटिस होगा अगर यह एक वस्तु वापस नहीं किया था, या यदि वह this जाँच की, उदाहरण के लिए आप के रूप में यह दुबारा लिखा है:

function Foo(x) { 
    if (!(this instanceof Foo)) { return new Foo(x); } 
    this.bar = function() { return x; }; 
} 
// Now instanceof works. 
alert((new Foo) instanceof Foo); 

क्या जावास्क्रिप्ट में new करता है, वैसे भी?

new ऑपरेटर का कारण बनता है कार्य करने के लिए एक नव Object जिसका प्रोटोटाइप कि समारोह के prototype संपत्ति है बनाया बाध्य this साथ कहा जाता है।

उपयोगकर्ता परिभाषित कार्यों के लिए,

new f(a, b, c) 

को

// Create a new instance using f's prototype. 
var newInstance = Object.create(f.prototype), result; 

// Call the function 
result = f.call(newInstance, a, b, c), 

// If the result is a non-null object, use it, otherwise use the new instance. 
result && typeof result === 'object' ? result : newInstance 

नोट बराबर है, उस भाषा विनिर्देश वास्तव में दो संचालन, [[Call]] और [[Construct]] साथ कार्यों को परिभाषित करता है, इसलिए कुछ कोने मामलों रहे हैं जहां new अजीब व्यवहार करता है।

उदाहरण के लिए, बाध्य और बिल्ट-इन कार्य:

var g = f.call.bind(f); 

एक समारोह है कि जब कहा जाता है परिभाषित करना चाहिए, बस f कहता है, तो g सभी मामलों में f के रूप में ही होना चाहिए, लेकिन

new g() 

पैदा करता

TypeError: function call() { [native code] } is not a constructor 

क्योंकि बिल्टिन फ़ंक्शन Function.prototype.callका समर्थन करता है [[कॉल]] लेकिन [[निर्माण]]

Function.prototype.bindnew और नियमित कॉल के आसपास अलग-अलग व्यवहार करता है। this मान हमेशा कॉल किया जाता है जब इसे बुलाया जाता है, लेकिन जब आप new का उपयोग करते हैं तो एक नया निर्मित उदाहरण है।

+1

यह जानकारीपूर्ण है, लेकिन वास्तव में सवाल का जवाब नहीं देता है। – benekastah

+3

@ बेनेकास्टा, दो प्रश्न हैं। शीर्षक में से एक, और पाठ में से एक। मैंने पहले शीर्षक का उत्तर दिया, और अब पाठ में से किसी एक का जवाब देने के लिए संपादित किया है। –

+1

तो आपने किया। मैं अपना आपत्ति वापस लेता हूं :) – benekastah

12

इस विशेष उदाहरण में, अंतिम परिणाम में कोई अंतर नहीं है।

ऐसा इसलिए है क्योंकि आपका Foo फ़ंक्शन ऑब्जेक्ट इंस्टेंस लौटा रहा है।

new ऑपरेटर एक नव निर्मित वस्तु है कि निर्माता के प्रोटोटाइप केवल जब समारोह एक आदिम मूल्य रिटर्न से विरासत रिटर्न (या यह कुछ भी वापस नहीं करता है, जो तकनीकी रूप से है undefined मूल्य)।

उदाहरण के लिए:

function Foo() { 
    return 5; // or "", or null, or no return statement at all (undefined) 
} 

var foo = new Foo(); 
typeof foo; // "object" 
foo instanceof Foo; // true 
Foo.prototype.isPrototypeOf(foo); // true 

जब आप एक वस्तु, नव निर्मित वस्तु है कि निर्माता के प्रोटोटाइप से विरासत बस त्याग दिया जाता है वापसी:

function Foo() { 
    return {}; 
} 

var foo = new Foo(); 
typeof foo; // "object" 
foo instanceof Foo; // false 
Foo.prototype.isPrototypeOf(foo); // false 

यह भी देखें:

5

इस उदाहरण में कोई नई वस्तु लौटने पर कोई फर्क नहीं पड़ता है। यह फिर से लिखा जा सकता है के रूप में:

function Foo(x){ 
    this._x = x; 
} 

Foo.prototype.bar = function() { 
    return this._x; 
} 
इस वाक्य के साथ

हर बार जब आप फोन new Foo यह _x की संपत्ति के साथ एक नई वस्तु का निर्माण करेगा। लाभ यह है कि bar फ़ंक्शन एक बार संग्रहीत किया जाएगा और Foo के कई उदाहरणों के लिए पुन: उपयोग किया जाएगा। Foo() पर कॉल करने वाले प्रश्न में कोड के साथ कई बार प्रत्येक उदाहरण के लिए एक बार फ़ंक्शन तैयार करेगा। इसलिए ऑब्जेक्ट पर सीधे रखने के बजाए प्रोटोटाइप में फ़ंक्शंस को जोड़ना स्मृति में हल्का होगा।

प्रोटोटाइप कार्यों को MDC पर कैसे पाया जा सकता है इसका एक पूर्ण ब्रेक डाउन।

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