2016-03-19 10 views
5

के बीच अंतर क्या है जून 2015 को ईसीएमएस्क्रिप्ट 6 की रिहाई के साथ, जावास्क्रिप्ट क्लास सिंटैक्स पेश किया गया था।जावास्क्रिप्ट: फंक्शन और क्लास

इस वाक्य रचना:

function Polygon(width, height) { 
    this.width = width; 
    this.height = height; 
} 

तो पारंपरिक समारोह के बजाय वर्ग का उपयोग कर के लाभ क्या है:

class Polygon { 
     constructor(width, height) { 
     this.width = width; 
     this.height = height; 
     } 
} 

मूलतः एक ही रूप में है? और किस स्थिति में मुझे कार्य के बजाय कक्षा का उपयोग करना चाहिए?

+0

इस तरह, है 'वर एक्स = (कुछ)? 'Var x पर लाभ 1: 0'; अगर (कुछ टिंग) {x = 1; } और {x = 0; } 'पठनीयता हो सकता है। –

+3

यह उत्तर (सटीक डुप्लिकेट नहीं होने पर) अंतरों को बहुत अच्छी तरह से बताता है: http://stackoverflow.com/questions/30783217/why-should-i-use-es6-classes – CodingIntrigue

+2

स्टैक ओवरफ्लो के साथ गलत क्या है, -5 केवल पूछने के लिए सामान्य सवाल मुझे लगता है कि यह पर्याप्त है, खुद को सीखेंगे। उत्तरदाताओं के लिए धन्यवाद जिन्होंने स्पष्टीकरण देने की कोशिश की, मैं इसकी सराहना करता हूं। –

उत्तर

12

कक्षा और कार्य के बीच कुछ अंतर हैं - अधिकांश लोग यह कहकर शुरू करेंगे कि कक्षा "केवल सिंटैक्स चीनी" है, लेकिन चीनी बहुत मायने रखती है। जब जे एस पार्सर जावा स्क्रिप्ट कोड prosessing है पार्सर, अलग एएसटी नोड्स में उन्हें बचा लेगा यहाँ दिखाया गया है ClassDeclaration और तरह ClassExpression resultin एएसटी पेड़ में विभिन्न प्रकार के नोड हैं:

https://github.com/estree/estree/blob/master/es6.md#classes

आप देख सकते हैं कि इस पार्सर के लिए, नई ES6 वर्ग कल्पना वाक्य रचना के लिए नए एएसटी तत्वों के एक नंबर का परिचय:

  • ClassBody
  • MethodDefinition
  • ClassDeclaration
  • ClassExpression
  • MetaProperty

के बाद से एएसटी वाक्य रचना मानक नहीं है, वहाँ कम या ज्यादा प्रकार पार्सर के आधार पर हो सकता है, लेकिन क्या महत्वपूर्ण है सूचना के लिए है कि जब कोड कक्षा घोषणा या कक्षा अभिव्यक्ति में प्रवेश करता है, इसे जावास्क्रिप्ट इंजन द्वारा अलग-अलग घुसपैठ कर दिया जाएगा।

इसका मतलब है कि कक्षा और कार्य घोषणाओं का आदान-प्रदान नहीं किया जा सकता है। आप यह देखते हैं आप

class notWorking { 
    return 1; // <-- creates a parser error 
}; 

इसका कारण यह है जब पार्सर वर्ग -keyword सामना करना पड़ता है, यह या तो ClassDeclaration या ClassExpression की ClassBody के रूप में निम्नलिखित कोड का इलाज शुरू कर देंगे और फिर इसे MethodDefinitions खोजने के लिए expexts लिखने की कोशिश कर सकते हैं।

यह एक छोटी सी समस्या है, क्योंकि निजी चर बनाने से थोड़ा और चुनौतीपूर्ण हो जाता है।समारोह घोषणा इस तरह बड़े करीने से एक निजी चर निर्धारित कर सकते हैं:

function myClass() { 
    var privateVar; 
} 

वर्ग घोषणा इस के लिए नहीं कर सकते हैं:

class myClass { 
    var privateVar; // ERROR: should be a method 
} 

इसका कारण यह है वर्ग की वाक्य रचना की अनुमति देता है केवल तरीकों वर्ग के अंदर घोषित किए जाने की तन। कम से कम अभी।

हालांकि, वहाँ निजी क्षेत्रों बनाने के लिए एक प्रस्ताव मौजूद है: इस प्रकार

https://github.com/zenparsing/es-private-fields

, भविष्य में आप कहने के लिए

class myClass { 
    #privateVar; // maybe this works in the future? 
} 

एक अलग जवाब निजी विचार नहीं है सक्षम हो सकता है ईएस 6 कक्षाओं में गुण, जो प्रतीकों के उपयोग की तरह कुछ कामकाज का सुझाव दे रहे हैं:

Private properties in JavaScript ES6 classes

var property = Symbol(); // private property workaround example 
class Something { 
    constructor(){ 
     this[property] = "test"; 
    } 
} 

स्वाभाविक रूप से वहाँ वर्गों और कार्यों के बीच अधिक अंतर है। उनमें से एक1 उत्थापन है - कार्य के विपरीत, आप दायरे में कहीं भी कक्षा की घोषणा नहीं कर सकते हैं:

समारोह घोषणाओं और वर्ग घोषणाओं के बीच एक महत्वपूर्ण अंतर यह है कि समारोह घोषणाओं फहराया जाता है और वर्ग घोषणाओं है नहीं हैं। आपको सबसे पहले अपनी कक्षा घोषित करने की आवश्यकता है और फिर इसे

कक्षा घोषणाएं और फ़ंक्शन घोषणाएं समान हैं;

function foo1() {} // can be used before declaration 
class foo2{}  // new foo2(); works only after this declaration 

वर्ग भाव काफी समान ही कार्य exressions कार्य करने के लिए, उदाहरण के लिए वे एक चर को सौंपा जा सकता:

var myClass = class foobar {}; 

अधिक मतभेद 1

  1. कक्षा exression/घोषणा शरीर हैं हमेशा सख्त मोड में निष्पादित किया जाता है - निर्दिष्ट करने की आवश्यकता नहीं है कि मैन्युअल रूप से
  2. कक्षाओं में विशेष कीवर्ड कन्स्ट्रक्टर है - उनमें से केवल एक ही हो सकता है, या त्रुटि फेंक दी जाती है। फ़ंक्शंस में "कन्स्ट्रक्टर" नामक फ़ंक्शन के चर की कई परिभाषाएं हो सकती हैं
  3. कक्षाओं में विशेष कीवर्ड सुपर है जो अभिभावक वर्ग कन्स्ट्रक्टर से संबंधित है। यदि आप कन्स्ट्रक्टर के अंदर हैं तो आप सुपर (एक्स, वाई) पर कॉल कर सकते हैं; अभिभावक वर्ग कन्स्ट्रक्टर को कॉल करने के लिए, लेकिन विधि के अंदर आप किसी भी पैरेंट क्लास फ़ंक्शन पर कॉल बनाने के लिए super.foobar() पर कॉल कर सकते हैं। इस तरह की कार्यक्षमता मानक कार्यों के लिए उपलब्ध नहीं है हालांकि आप इसे कुछ कस्टम हैकिंग के साथ अनुकरण कर सकते हैं।
  4. अंदर वर्ग शरीर आप तो यह केवल ClassName.FunctionName() -syntax का उपयोग कर कहा जा सकता है के साथ स्थिर कीवर्ड समारोह को परिभाषित कर सकते हैं।
  5. दोनों वर्ग घोषणाओं और भाव फैली वर्ग कुत्तातरह कीवर्ड फैली पशु उपयोग कर सकते हैं
  6. MethodDeclaration इस तरह वर्ग "एम" के अंदर समारोह -prefix की जरूरत नहीं है, इस प्रकार आप समारोह "ठीक है" को परिभाषित कर सकते हैं: कक्षा एम {ठीक() {}}। असल में तो यह और भी बाद पार्सर यह काम है पूरा कर लिया है, वर्ग उदाहरण अनिवार्य रूप से किसी अन्य के रूप में एक ही तरह से चल रहा है वर्ग मीटर {समारोह ठीक() {}}

हालांकि के रूप में समारोह को परिभाषित करने की अनुमति नहीं है वस्तु।

नया ईएस 6 कक्षा वाक्यविन्यास पारंपरिक ओओपी तरीके से वस्तुओं को व्यक्त करने का अनिवार्य रूप से अधिक स्पष्ट तरीका है और यदि आपको यह पसंद है, तो आपको इसका उपयोग करना चाहिए।

संपादित करें: भी, ईएस 6 कक्षा वाक्यविन्यास में एक और सीमा भी है: यह सदस्य कार्यों को वसा तीर का उपयोग करके लंबवत रूप से बाध्य करने की अनुमति नहीं देता है। ऐसा लगता है कि ES7 में experimental feature है। यह उदाहरण के लिए उपयोगी हो सकता है जब ईवेंट हैंडलर को बाध्यकारी विधियां, संबंधित प्रश्न here है।

1https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Classes

+0

स्पष्टीकरण और संदर्भों के लिए धन्यवाद, बहुत मदद करता है। –

+0

मैंने ईएस 6 कक्षा घोषणा के लिए गायब वसा-तीर वाक्यविन्यास के बारे में भी एक नोटिस जोड़ा। –

+0

@TeroTolonen: यह शायद ही कभी "फीचर" है जो कक्षाओं को कार्यों से अलग करेगा। आप कन्स्ट्रक्टर के अंदर तीर फ़ंक्शंस का उपयोग कर सकते हैं, न कि प्रोटोटाइप पर। – Bergi

0

classfunction का उपयोग कर जावास्क्रिप्ट लॉजिक क्लास निर्माण पर एक वाक्य रचनात्मक चीनी के अलावा कुछ भी नहीं है। यदि आप functionclass के रूप में उपयोग कर रहे हैं, तो संपूर्ण फ़ंक्शन एक कन्स्ट्रक्टर के रूप में कार्य करता है, यदि आप अन्य सदस्यों के कार्यों को रखना चाहते हैं तो आपको this.something = ..., या var something = ... जैसे निजी सदस्यों के मामले में कन्स्ट्रक्टर में ऐसा करने की आवश्यकता है (यदि आप बाहर से इंजेक्शन नहीं दे रहे हैं , मान लीजिए कि आप अन्य विधियों/गुणों के साथ ऑब्जेक्ट बना रहे हैं), लेकिन कक्षा के मामले में पूरा फ़ंक्शन वास्तव में एक कन्स्ट्रक्टर नहीं कार्य करता है, आप स्पष्ट रूप से इसे अन्य सदस्य फ़ंक्शंस और डेटा से अलग कर सकते हैं।

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