2011-05-11 18 views
38

क्या आप किसी ऑब्जेक्ट को ऑब्जेक्ट के रूप में कॉल कर सकते हैं?जावास्क्रिप्ट: कार्य और वस्तु ...?

function Tip(txt){  
    this.content = txt; 
    this.shown = false; 
} 

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

var tip = new Tip(elem.attr('title')); 
मेरे सवालों का

:

  1. आप एक समारोह के लिए new फोन कर सकते हैं, एक वस्तु के लिए के रूप में?
  2. "यह" का उपयोग संभव हो गया है, क्योंकि हम का उपयोग करते हैं जो किसी ऑब्जेक्ट के रूप में कार्य करता है?

उत्तर

108

आप constructor अवधारणा की तलाश में हैं। , आदेश (कि कहने के लिए है, एक विशेष प्रकार का नई वस्तुओं है कि एक प्रोटोटाइप के वारिस बनाने के लिए,

function make_person(firstname, lastname, age) { 
    person = {}; 
    person.firstname = firstname; 
    person.lastname = lastname; 
    person.age = age; 
    return person; 
} 
make_person("Joe", "Smith", 23); 
// {firstname: "Joe", lastname: "Smith", age: 23} 

हालांकि एक निर्माता है:

जावास्क्रिप्ट are objects में सभी कार्यों और वस्तुओं बनाने के लिए इस्तेमाल किया जा सकता है , आदि), एक समारोह this संदर्भ और कर सकते हैं अगर यह new ऑपरेटर साथ कहा जाता है तो यह गुण है कि समारोह में this पर परिभाषित कर रहे हैं के सभी के साथ एक वस्तु वापस आ जाएगी - ऐसे मामलों में this का संदर्भ नई वस्तु हम कर रहे हैं बनाना।

function make_person_object(firstname, lastname, age) { 
    this.firstname = firstname; 
    this.lastname = lastname; 
    this.age = age; 
    // Note, we did not include a return statement 
} 

मुख्य अंतर यह नोट करने के लिए make_person और make_person_object के बीच है कि new make_person() बुला कुछ अलग काम नहीं चलेगा (के रूप में बस make_person() के खिलाफ) ... दोनों एक ही वस्तु का उत्पादन करेगा। इसके अलावा

var Joe = make_person_object("Joe", "Smith", 23); 
console.log(Joe); // undefined 
console.log(window.firstname) // "Joe" (oops) 

var John = new make_person_object("John", "Smith", 45); 
console.log(John); // {firstname: "John", lastname: "Smith", age: 45} 

, के रूप में @RobG बताते हैं: हालांकि new ऑपरेटर के बिना make_person_object() कॉलिंग, होगा वर्तमान this वस्तु पर अपने this विशेषताएं निर्धारित

इस प्रकार है (यदि आप ब्राउज़र में काम कर रहे हैं आम तौर पर window।) , चीजों को करने का यह तरीका हमारे द्वारा बनाए गए प्रत्येक "व्यक्ति" पर make_person_object की prototype संपत्ति का संदर्भ बनाता है। इस तरीके जोड़ के लिए सक्षम बनाता है और इस तथ्य के बाद लोगों को जिम्मेदार बताते हैं:

// Assuming all that came before 
make_person_object.prototype.full_name = "N/A"; 
make_person_object.prototype.greet = function(){ 
    console.log("Hello! I'm", this.full_name, "Call me", this.firstname); 
}; 
John.full_name // "N/A" 
John.full_name = "John Smith"; 
make_person_object.full_name // Still "N/A" 
John.greet(); // "Hello! I'm John Smith Call me John" 

कन्वेंशन यह make_person_object की तरह है कि निर्माता कार्य करता है बड़ा किया जाता है, singularized और "nouned" (एक बेहतर शब्द की कमी के लिए) - इस प्रकार हम हैं के बजाय Person कन्स्ट्रक्टर है, जो सामान्य कार्य के लिए गलत हो सकता है।

यह भी देखें:

+6

आपने सबसे अधिक आयात हिस्सा छोड़ा: कन्स्ट्रक्टर के 'यह' द्वारा संदर्भित नई वस्तु कन्स्ट्रक्टर के प्रोटोटाइप से गुण प्राप्त करती है। – RobG

+2

@RobG - ठीक है कि मैंने * किया *! मैंने इसका कुछ उदाहरण शामिल करने के लिए उत्तर अपडेट किया है - इसे बेहतर बनाने में मदद के लिए धन्यवाद! –

+1

शानदार जवाब। वास्तव में महान क्या करना है, और फिर मुझे सिखाया कि इसे कैसे समझें। मैंने जो भी सवाल पढ़ा था, उसके बाद निम्नलिखित खंड में उत्तर दिया गया था। धन्यवाद!! – redfox05

15

प्रत्येक समारोह में this का संदर्भ है। यदि आप Tip() पर कॉल करते हैं, this वैश्विक वस्तु का संदर्भ लेंगे। यदि आप new Tip() पर कॉल करते हैं, तो Tip.prototype के संदर्भ वाला एक नया ऑब्जेक्ट बनाया गया है और this उस नई ऑब्जेक्ट को संदर्भित करेगा।

आप वस्तुओं पर new का उपयोग नहीं कर सकते हैं, उदाहरण के लिए new {}TypeError: object is not a function फेंकता है। यदि आप new Object() पर प्रतिक्रिया दे रहे हैं तो यह Object के बाद से कार्य करता है।

1

फ़ंक्शन एक कक्षा पर एक निर्माता के रूप में कार्य कर रहा है। वैकल्पिक रूप से, तुम कर सकते हो:

function Tip(txt) { 
return { 
content: txt, 
shown: false 
} 
} 

और साथ एक नया उदाहरण मिलता है: var myTip = new Tip("my epic tip"); यह समान है, कहते हैं, सी #:

public class Tip { 
string text = ""; 
public Tip(string txt) { 
text = txt; 
} 
} 

तो, एक तरह से। 1) आप नए कॉल कर रहे हैं क्योंकि फ़ंक्शन अनिवार्य रूप से कक्षा के रूप में कार्य कर रहा है, और 2) this कक्षा के वर्तमान उदाहरण का जिक्र कर रहा है।

+2

समारोह एक वस्तु के रूप में इस्तेमाल नहीं कर रहा है। 'New' का उपयोग करते समय एक नई वस्तु बनाई जाती है और फ़ंक्शन को उस फ़ंक्शन के दायरे में –

+0

@Adam दाएं कहा जाता है। मैंने अपने प्रश्न की सटीक वाक्यांशविज्ञान को स्किम किया। सबक सीखा। ;-) –

+0

@Adam: किसी ऑब्जेक्ट को बनाने का दूसरा तरीका ऑब्जेक्ट शाब्दिक वाक्यविन्यास का उपयोग करना है जैसे थॉमस ने किया था। "नया" का उपयोग करना ऑब्जेक्ट बनाने के तरीकों में से एक है। – user670800

1
# 1 के लिए

: ("वापसी x * y," "एक्स", "वाई",) एक वस्तु बुलाया समारोह (राजधानी एफ)

वर च = नया फंक्शन नहीं है;

# 2 के लिए: "यह" innvocation पैटर्न (जैसा कि डगलस क्रॉकफोर्ड द्वारा कहा जाता है) के आधार पर अलग है। क्रॉकफोर्ड ने कहा कि 4 पैटर्न (विधि पैटर्न, फ़ंक्शन पैटर्न, कन्स्ट्रक्टर पैटर्न और "लागू" पैटर्न हैं)

+0

जो eval को कॉल करता है और आपको नियमित रूप से कार्य करने वाले कार्यों की तुलना में अधिक शक्ति नहीं देता है। प्रश्न के लिए अप्रासंगिक भी लगता है। –

+0

यह सुनिश्चित नहीं है कि ओपी के साथ क्या करना है (शायद यह सिर्फ मुझे था)। डाउनवॉट्स डालने से पहले स्पष्टीकरण देना चाहेंगे। –

+0

@Adam: यह eval को कॉल नहीं कर रहा है। यदि आप ध्यान से पढ़ते हैं तो उत्तर उनके # 1 प्रश्न से प्रासंगिक है। – user670800

5

हां। जावास्क्रिप्ट में, तकनीकी रूप से सबकुछ एक वस्तु है। जब आप नए का उपयोग करते हैं, तो यह टिप ऑब्जेक्ट का एक उदाहरण बनाता है और फिर टिप फ़ंक्शन को कॉल करता है जैसे कि यह एक कन्स्ट्रक्टर था। यह

var tip = new Tip("this is my content."); 
alert(tip.getContent()); 

:

आप टिप वस्तु के लिए कार्यों को जोड़ना चाहते हैं, तो आप उन्हें टिप के प्रोटोटाइप के लिए इतना की तरह जोड़ना चाहिए:

Tip.prototype.getContent = function() { 
    return this.content; 
}; 

आपको लगता है कि है, और उसके बाद आप करते हैं एक संदेश दिखाएगा "यह मेरी सामग्री है।"

आप केवल नए का उपयोग कर सकते हैं, हालांकि, यदि ऑब्जेक्ट में कार्यात्मक कार्यान्वयन है। तो यह काम नहीं करेगा:

var Tip = { content: txt, show: false }; 
var tipObj = new Tip(); 
0
  1. वास्तव में, हर डेटा प्रकार सरणी की तरह, कार्यों वस्तुओं रहे हैं।
  2. जब हम कक्षा घोषणा के रूप में कार्य करते हैं, तो यह काम करता है।
0

मैं इन अवधारणाओं को लगभग 8 साल (2008-2016) के लिए (वस्तुओं, प्रोटोटाइप वस्तुओं, __proto__ संपत्ति, निर्माता संपत्ति के रूप में कार्य करता है) को समझने के लिए संघर्ष किया है। सबसे पहले मैंने अध्याय 6,8,9 के कई रीडिंग के बाद 4-5 साल के लिए डेविड फ़्लानागन "जावास्क्रिप्ट डेफिनिटिव गाइड 5/6 वां एड" शुरू किया; यह मेरे लिए कोई समझ नहीं आया लेकिन इंटरनेट पर संघर्ष करने के बाद मैं कुछ वस्तुओं के रूप में कार्यों (सामान्य सी ++ गुणों के साथ समारोह) का प्रबंधन करने में सक्षम है; क्योंकि ऑब्जेक्ट में विधियां भी हो सकती हैं। और सौभाग्य से 7 वें वर्ष 2015 में, मैंने व्रॉक्स निकोलस सी शुरू किया।जाकस "वेब डेवलपर्स के लिए पेशेवर जावास्क्रिप्ट 3 डी एड" अध्याय 6,7; और चार अवधारणाओं को समझना वास्तव में बहुत उपयोगी था। पारंपरिक रूप से सी/सी ++/सी # कार्यों में किसी ऑब्जेक्ट को संशोधित करने के बारे में सोचा जाता है; या दूसरे शब्दों में वे "कुछ करने" के लिए बने होते हैं, जहां ऑब्जेक्ट्स को वैश्विक ऑब्जेक्ट स्टेटस को बदलने के तरीकों के साथ वैश्विक चल रहे संदर्भ की स्थिति को बनाए रखने के लिए बनाया जाता है। तो यदि कार्य प्रथम श्रेणी की वस्तुएं हो सकती हैं तो वस्तुएं फ़ंक्शंस की तरह क्यों नहीं हो सकती हैं?

मुख्य मुख्य प्रश्न यहां क्यों होना चाहिए? क्यों नहीं एक वैचारिक इकाई "सहयोगी-कार्य" या "जंजीर-तर्क" की तरह? और यहां मेरी समझ है: ब्राउज़र एक्सई एक एकल थ्रेडेड एप्लिकेशन है और यह एक्सई पूर्व परिभाषित स्कोप श्रृंखला (कुछ तर्कों के साथ कमांड की स्ट्रिंग के समान) के साथ जेएस दुभाषिया को कॉल करने पर नियंत्रण करता है; अब रनटाइम पर जेएस इंजन (दुभाषिया नहीं) उछालते हुए फैशन में कोड लोड करता है (चूंकि अच्छी तरह से परिभाषित कीवर्ड कोड और इसकी कॉल को ऊपर उठाने की कोई मुख्य विधि नहीं है)। इस फिसलने वाले कोड में यदि फ़ंक्शंस को ऑब्जेक्ट्स के रूप में नहीं माना जाता है तो उन्हें अलग-अलग कॉल संदर्भ (स्कोप चेन से बाहर) पर बनाए रखा जाना चाहिए जो सी/सी ++/सी # (बहु थ्रेड और असीमित मेमोरी का बोक्ज़) में आसानी से संभव है लेकिन जेएस में नहीं । इसलिए "जंजीर वस्तु पर करने के लिए smth" पहली जावा वस्तु के रूप में एक जावा स्क्रिप्ट समारोह बनाता है। वास्तव में जेएस ऑब्जेक्ट भी वही काम करते हैं; एकमात्र अंतर "ऑब्जेक्ट को कॉल करना" उन वस्तुओं में नहीं है जहां "फ़ंक्शन कॉल करना" जंजीर संदर्भ है जो समझ में आता है। कार्यों को "लिंक लिंक (चेन) के साथ असेंबली भाषा निर्देशों के साथ चर के समूह के रूप में भी सोचा जा सकता है। लिंकिंग हिस्सा शीर्ष-> नीचे लिंकिंग (प्रोटोटाइप ऑब्जेक्ट) बनाम नीचे-> शीर्ष लिंकिंग (__ proto__ प्रॉपर्टी) बनाम ऑब्जेक्ट ब्लू प्रिंट-> ऑब्जेक्ट इंस्टेंस (कन्स्ट्रक्टर प्रॉपर्टी) के रूप में कहानी का एक और पक्ष है। कुछ महीने पहले मुझे निम्नलिखित छवि को जोड़ने के लिए सहायक के रूप में उपयोगी पाया गया।

http://judis.me/wordpress/wp-content/uploads/2015/08/JavaScriptDiagram.png "जे एस ऑब्जेक्ट मॉडल"

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