पृष्ठभूमि
यह देखना दिलचस्प है कि ब्राउज़र कंसोल/डीबगर में बैकबोन ऑब्जेक्ट्स के प्रकार को प्रदर्शित करने के लिए "बच्चे" का उपयोग क्यों करता है।
सभी जावास्क्रिप्ट ऑब्जेक्ट्स में एक कन्स्ट्रक्टर प्रॉपर्टी है, जो ऑब्जेक्ट बनाने के लिए प्रयुक्त फ़ंक्शन का संदर्भ है। कंसोल/डीबगर में ऑब्जेक्ट के "प्रकार" को प्रदर्शित करने के लिए ब्राउज़र द्वारा कन्स्ट्रक्टर का उपयोग किया जाता है। कन्स्ट्रक्टर फ़ंक्शन की नाम संपत्ति का मान उपयोग नहीं किया जाएगा यदि यह खाली नहीं है।
function A() { }
console.log(A.name); // 'A'
बेनामी कार्यों एक खाली नाम संपत्ति है: हालांकि, केवल कार्यों नामित समारोह भाव एक उपयोगी नाम संपत्ति पाने का उपयोग करके परिभाषित
var B = function() { };
console.log(B.name); // ''
तो, क्या गुमनाम कार्यों के साथ क्या होता है? क्रोम वैरिएबल या प्रॉपर्टी के नाम से अनाम कार्यों का नाम बताता है जिस पर फ़ंक्शन को पहले असाइन किया गया था।यहाँ कुछ उदाहरण हैं:
// 1. named function expression - objects will show as “a” in the console
function a() { … }
// 2. anonymous function assigned to variable - objects will show as “b” in the console
var b = function(){ … };
// 3. anonymous function assigned to property of object - objects will show as “container.c” in the debugger
var container = {
c: function() { … }
};
एक अधिक विस्तृत स्क्रिप्ट यहाँ उपलब्ध है: http://jsfiddle.net/danmalcolm/Xa7ma/6/
ब्राउज़र स्रोत कोड से यह नाम प्राप्त करने के लिए प्रकट होता है - वहाँ एक जावास्क्रिप्ट सुविधा है जो आपको कार्यावधि में बता सकते हैं नहीं है पहले चर का नाम जिसे एक फ़ंक्शन सौंपा गया था। अन्य ब्राउज़र एक ऐसे सम्मेलन का समर्थन करते हैं जहां अज्ञात कन्स्ट्रक्टर फ़ंक्शंस पर परिभाषित डिस्प्लेनाम गुण का उपयोग किया जाता है, लेकिन यह वर्तमान में क्रोम में नहीं होता है: http://code.google.com/p/chromium/issues/detail?id=17356।
रीढ़ में लौटने के बाद आप एक कस्टम निर्माता (देखें नीचे) उपयोग नहीं कर रहे संभालने, अपने प्रकार एक गुमनाम निर्माता समारोह के साथ खत्म हो जाएगा, Backbone's extend function के रूप में मॉडल, देखें, संग्रह और मार्ग द्वारा प्रयोग किया जाता में बनाए गए इस प्रकार है:
child = function(){ return parent.apply(this, arguments); };
यही कारण है कि आप कंसोल/डीबगर में अपनी बैकबोन ऑब्जेक्ट्स के बगल में "बच्चा" देखते हैं। यह आपके ऑब्जेक्ट के कन्स्ट्रक्टर के लिए उपयुक्त नाम पर ब्राउजर का सबसे अच्छा अनुमान है।
समाधान
अपने वस्तुओं के लिए एक बेहतर प्रकार का नाम है जब आप अपने रीढ़ प्रकार को परिभाषित आप पहली बार "protoProps" तर्क माध्यम से एक नामित निर्माता की आपूर्ति कर सकते देने के लिए,। इस प्रकार बस एक निर्माता संपत्ति है कि "जनक" निर्माता के लिए एक कॉल लपेटता जोड़ें:
var Product = Backbone.Model.extend({
constructor: function Product() {
Backbone.Model.prototype.constructor.apply(this, arguments);
}
});
अपने उत्पाद मॉडल उदाहरणों अब डीबगर में दिखेगा वास्तव में अच्छा।
यह आपके द्वारा परिभाषित प्रत्येक दृश्य, मॉडल, संग्रह और मार्ग के लिए ऐसा करने के लिए थोड़ा बोझिल है। आप बंदर पैच बैकबोन का विस्तार कार्य आपके लिए काम करने के लिए कर सकते हैं।
आपको सबसे पहले अपने प्रकार के नाम परिभाषित करने के लिए एक सम्मेलन स्थापित करने की आवश्यकता है।
var Product = Backbone.Model.extend({
__name__: 'Product'
// other props
});
फिर आप मॉडल, देखें, संग्रह और रूट के द्वारा प्रयोग किया इस संपत्ति पढ़ सकते हैं और अपने प्रकार के लिए एक नामित निर्माता जोड़ने के लिए विस्तार समारोह की जगह: यहाँ हम एक __name__
संपत्ति है, जो आपको इस प्रकार निर्दिष्ट उपयोग कर रहे हैं। आपको backbone.js को स्वयं संशोधित करने की आवश्यकता नहीं है, बस बैकबोन.जेएस के बाद लोड की गई एक अलग स्क्रिप्ट में निम्न शामिल करें।
(function() {
function createNamedConstructor(name, constructor) {
var fn = new Function('constructor', 'return function ' + name + '()\n'
+ '{\n'
+ ' // wrapper function created dynamically for "' + name + '" constructor to allow instances to be identified in the debugger\n'
+ ' constructor.apply(this, arguments);\n'
+ '};');
return fn(constructor);
}
var originalExtend = Backbone.View.extend; // Model, Collection, Router and View shared the same extend function
var nameProp = '__name__';
var newExtend = function (protoProps, classProps) {
if (protoProps && protoProps.hasOwnProperty(nameProp)) {
// TODO - check that name is a valid identifier
var name = protoProps[nameProp];
// wrap constructor from protoProps if supplied or 'this' (the function we are extending)
var constructor = protoProps.hasOwnProperty('constructor') ? protoProps.constructor : this;
protoProps = _.extend(protoProps, {
constructor: createNamedConstructor(name, constructor)
});
}
return originalExtend.call(this, protoProps, classProps);
};
Backbone.Model.extend = Backbone.Collection.extend = Backbone.Router.extend = Backbone.View.extend = newExtend;
})();
वाह, इसे डिफ़ॉल्ट रूप से रीढ़ की हड्डी में शामिल किया जाना चाहिए ....एक लाख दान धन्यवाद, यह बहुत अच्छा है। – MattyP