2011-01-14 18 views
46

मैं एक वेक्टर वर्ग बना रहा हूं, जो मूल रूप से तीन संख्यात्मक मान रख सकता है। हालांकि, इस तरह के वेक्टर पर बहुत से ऑपरेशन किए जा सकते हैं - उदा। परिमाण प्राप्त करना, जोड़ना या किसी अन्य वेक्टर इत्यादि को घटा देनाक्या मुझे प्रोटोटाइप का उपयोग करना चाहिए या नहीं?

मैं सोच रहा था कि क्या इन कार्यों को वेक्टर वर्ग के प्रोटोटाइप फ़ंक्शन के रूप में कोड किया जाना चाहिए, या मुझे उन्हें निर्माता में परिभाषित करना चाहिए।

तो इनमें से कौन सा तरीका बेहतर है?

function Vector3D(x, y, z) { 
    this.x = x; 
    this.y = y 
    this.z = z; 
} 

Vector3D.prototype.magnitude = function() { 
    return Math.sqrt(this.x * this.x + this.y * this.y + this.z * this.z); 
}; 

या

function Vector3D(x, y, z) { 
    this.x = x; 
    this.y = y; 
    this.z = z; 

    this.magnitude = function() { 
     return Math.sqrt(this.x * this.x + this.y * this.y + this.z * this.z); 
    }; 
} 

उत्तर

49

प्रोटोटाइप का उपयोग करने के लिए यह बिल्कुल सही स्थिति है।

  1. कार्य नहीं बनाई गई हैं कई बार: मैं ऐसा करने के लिए दो मुख्य लाभ देखना। यदि आप कन्स्ट्रक्टर के अंदर फ़ंक्शंस को परिभाषित करते हैं, तो आपके द्वारा परिभाषित प्रत्येक फ़ंक्शन के लिए एक नया अनाम फ़ंक्शन बनाया जा रहा है, हर बार जब निर्माता को कहा जाता है। प्रोटोटाइप स्थिर वस्तुएं हैं, और वेक्टर 3 डी का प्रत्येक उदाहरण प्रोटोटाइप फ़ंक्शंस को संदर्भ संदर्भित करेगा।
  2. प्रोटोटाइप एक एकल वस्तु है जिसे आसानी से छेड़छाड़ की जा सकती है। यह बहुत लचीलापन प्रदान करता है; दुर्भाग्यवश मैं केवल कुछ उदाहरण प्रदान कर सकता हूं जो यह पेशकश कर सकते हैं:
    1. यदि आप बाल वर्ग बनाना चाहते हैं, उदाहरण के लिए वेक्टर 3DSpecial, तो आप बस Vector3D.prototype क्लोन कर सकते हैं और इसे Vector3DSpecial.prototype पर असाइन कर सकते हैं। जबकि आप इसे Vector3DSpecial.prototype = new Vector3D(); द्वारा रचनाकारों का उपयोग करके भी कर सकते हैं, रचनाकारों में दुष्प्रभाव हो सकते हैं जो उस सरल प्रोटोटाइप असाइनमेंट में निष्पादित किए जाएंगे, और इसलिए इससे बचा जाना चाहिए। प्रोटोटाइप के साथ, आप प्रोटोटाइप में केवल नए कार्यों में प्रतिलिपि बनाने के लिए केवल विशेष कार्य चुन सकते हैं।
    2. Vector3D पर विधियों को जोड़ना प्रोटोटाइप में गुण जोड़ने का विषय है, और आपके कोड को कई फ़ाइलों में आसानी से विभाजित/संगठित करने की अनुमति देता है, या कोड के अन्य हिस्सों में गतिशील रूप से विधियों को जोड़ने की अनुमति देता है। निश्चित रूप से, आप कन्स्ट्रक्टर में और प्रोटोटाइप के माध्यम से विधियों को जोड़ने का संयोजन कर सकते हैं, लेकिन यह असंगत है और ट्रैक के आगे और अधिक जटिलता का कारण बन सकता है।

जब मैं उपयोग नहीं प्रोटोटाइप होता? सिंगलटन ऑब्जेक्ट्स के लिए, उदाहरण के लिए एक नियंत्रक जो किसी पृष्ठ से इंटरैक्ट करता है और अन्य ऑब्जेक्ट्स को काम सौंप सकता है। एक वैश्विक "अधिसूचना" वस्तु एक ऐसा उदाहरण है। यहां, विस्तार की संभावना नहीं है, और ऑब्जेक्ट केवल एक बार बनाया गया है, प्रोटोटाइप को एक अतिरिक्त (वैचारिक) जटिलता बनाते हैं।

8

नमूने के तरीकों केवल, सार्वजनिक संपत्तियों के लिए काम करता है, तो आप एक्स, वाई, के रूप में "निजी" चर प्रोटोटाइप कार्य नहीं करेगा जेड का ट्रैक रखने होगा।

मैं बाद वाले का उपयोग करूंगा, क्योंकि आप केवल उन विधियों को चाहते हैं जो केवल निजी/आंतरिक चर के साथ काम करते हैं, लेकिन यह सब संदर्भ पर निर्भर करता है।

function Vector3D(x, y, z) { 
    // x, y, z is automatically in this scope now, but as private members. 
    this.magnitude = function() { 
     return Math.sqrt(x * x + y * y + z *z); 
    } 
} 
+1

आपकी प्रतिक्रिया के लिए धन्यवाद। एक्स, वाई और जेड को वेक्टर 3 डी के उदाहरण से निकाला जा सकता है, इसलिए उन्हें सार्वजनिक होना चाहिए। इस मामले में, प्रोटोटाइप सबसे अच्छा विकल्प होगा? सही जवाब के लिए – pimvdb

+3

+1, लेकिन मैं प्रोटोटाइप पसंद करता हूं, क्योंकि जेएस में निजी कुछ भी एक पाइपड्रीम है, और आम तौर पर आपके कोड को यूनिट करने के लिए केवल कठिन बना देगा - आप खुद को छोड़कर सामान छुपा रहे हैं :) –

+0

मैं सहमत हूं आपके साथ, इसलिए मेरे पास केवल सार्वजनिक चर हैं। Google क्रोम के डेवलपर टूल्स फ़ंक्शंस में सदस्यों के रूप में दिखाए जाते हैं यदि कन्स्ट्रक्टर के बावजूद पास किया जाता है, जबकि यह अधिक व्यावहारिक होगा यदि वे प्रोटोटाइप में 'छुपा' होंगे और केवल एक्स, वाई और जेड वहां दिखाई देंगे। – pimvdb

0

ECMA 6 http://es6-features.org/#BaseClassAccess

class Shape { 
    … 
    toString() { 
     return `Shape(${this.id})` 
    } 
} 
class Rectangle extends Shape { 
    constructor (id, x, y, width, height) { 
     super(id, x, y) 
     … 
    } 
    toString() { 
     return "Rectangle > " + super.toString() 
    } 
} 
class Circle extends Shape { 
    constructor (id, x, y, radius) { 
     super(id, x, y) 
     … 
    } 
    toString() { 
     return "Circle > " + super.toString() 
    } 
} 

ECMA 5

var Shape = function (id, x, y) { 
    … 
}; 
Shape.prototype.toString = function (x, y) { 
    return "Shape(" + this.id + ")" 
}; 
var Rectangle = function (id, x, y, width, height) { 
    Shape.call(this, id, x, y); 
    … 
}; 
Rectangle.prototype.toString = function() { 
    return "Rectangle > " + Shape.prototype.toString.call(this); 
}; 
var Circle = function (id, x, y, radius) { 
    Shape.call(this, id, x, y); 
    … 
}; 
Circle.prototype.toString = function() { 
    return "Circle > " + Shape.prototype.toString.call(this); 
}; 
संबंधित मुद्दे