2011-03-17 15 views
10

मैंने अभी जावास्क्रिप्ट में ओओपी का उपयोग करना शुरू कर दिया है और मैं किसी अन्य विधि के अंदर से किसी विधि को प्राप्त करने की कोशिश करने वाली कुछ समस्याओं में भाग गया।जावास्क्रिप्ट ऑब्जेक्ट, स्वयं संदर्भ समस्या

यहाँ कोड मैं था है:

var Game = { 
initialize: function() { 
    if (canvas.isSupported()) { 
     sprites[0] = new Player(); 

     this.update(); 
    } 
}, 

update: function() { 
    for (var i = 0; i < sprites.length; i++) { 
     sprites[i].update(); 
    } 

    this.draw(); 
}, 

draw: function() { 
    this.clear(); 

    for (var i = 0; i < sprites.length; i++) { 
     sprites[i].draw(); 
    } 

    setTimeout(this.update, 10); 
}, 

clear: function() { 
    canvas.context.clearRect(0, 0, canvas.element.width, canvas.element.height); 
} 

}

लेकिन Game.update() कॉल करने में त्रुटि है कि ड्रॉ विधि से परिभाषित नहीं है देता है। मुझे इसके लिए एक वास्तविक समाधान नहीं मिला। अंत में मैं इस How to call a method inside a javascript object जवाब लगता है जहां पाया जा करने के लिए है कि मैं सुरक्षित करने की जरूरत है इस संदर्भ की तरह: var _this = this; लेकिन मुझे लगता है कि शाब्दिक अंकन में काम करने के लिए नहीं मिल सका, तो मैं निर्माता आपत्ति उठाने का कोड बदल (मुझे लगता है कि इस तरह इसे कहा जाता है) और चर जोड़ा गया।

मैं तो

_this.draw(); 

को

this.draw(); 

बदल गया और यह काम किया।

हालांकि

this.clear(); 

और this.update() अभी भी वही कर रहे हैं, वे पहली जगह में त्रुटियों देने के लिए लग रहा था कभी नहीं।

क्या कोई यह समझा सकता है कि यह क्यों है? और शायद मुझे एक बेहतर समाधान के लिए इंगित करें? अग्रिम धन्यवाद।

अद्यतन

यहाँ यह क्या होना चाहिए:

var Game = function() { 
var _this = this; 

this.initialize = function() { 
    if (canvas.isSupported()) { 
     sprites[0] = new Player(); 

     this.update(); 
    } 
} 

this.update = function() { 
    for (var i = 0; i < sprites.length; i++) { 
     sprites[i].update(); 
    } 

    this.draw(); 
} 

this.draw = function() { 
    this.clear(); 

    for (var i = 0; i < sprites.length; i++) { 
     sprites[i].draw(); 
    } 


    setTimeout(function() { _this.update(); }, 10); 
} 

this.clear = function() { 
    canvas.context.clearRect(0, 0, canvas.element.width, canvas.element.height); 
} 

}

+0

क्या आप पूरा कोड दिखा सकते हैं? –

+3

+1 शानदार होने और अपना अपडेट पोस्ट करने के लिए +1। इस पोस्ट ने अंततः वैकल्पिक नेमस्पेसिंग विधियों में मतभेदों को ठोस बना दिया। आपने आज मुझे एक बेहतर कोडर बनाया है। :) – Evildonald

उत्तर

14

जब आप ऐसा करते:

setTimeout(this.update, 10); 

कि सही ढंग से संदर्भ के लिए अपने "अद्यतन" कार्य करने के लिए व्यवस्था करने के लिए पारित करता है, लेकिन जब ब्राउज़र वास्तव में कॉल बाद में समारोह, यह नहीं पता होगा कि this होना चाहिए। क्या आप के बजाय क्या कर सकते हैं निम्नलिखित:

var me = this; 
setTimeout(function() { me.update(); }, 10); 

यह सुनिश्चित करेंगे कि कि जब "अद्यतन" कहा जाता है, यह this अपने ऑब्जेक्ट के लिए एक संदर्भ के रूप सही तरीके से सेट के साथ बुलाया जाएगा।

कुछ अन्य भाषाओं के विपरीत, तथ्य यह है कि किसी ऑब्जेक्ट की प्रॉपर्टी के रूप में प्रारंभ में एक फ़ंक्शन को परिभाषित किया जाता है, वह उस कार्य को आंतरिक रूप से फ़ंक्शन को बाध्य नहीं करता है। ठीक वैसे ही है कि एक साधारण संख्या है अगर आप एक propertly के साथ एक वस्तु की थी में:

maxLength: 25, 

अच्छी तरह से मूल्य "25" विशेष रूप से कुछ भी वस्तु से कोई लेना देना नहीं होगा; यह सिर्फ एक मूल्य है। जावास्क्रिप्ट में, फ़ंक्शंस केवल वैल्यू ही हैं। इस प्रकार यह सुनिश्चित करने के लिए प्रोग्रामर पर निर्भर है कि this कुछ "विशेष" तरीके से किसी फ़ंक्शन को बुलाए जाने पर उचित कुछ सेट किया जाएगा।

+0

अरे ड्राइव के लिए धन्यवाद, दोस्त! – Pointy

+0

उम्म, इसके बारे में खेद है। मैं तुम्हें वोट देने को याद नहीं कर सकता। यह एक गलत जगह होनी चाहिए। – RoToRa

+0

यह आप नहीं हो सकता है, @RoToRa - यह शायद एक रहस्य रहेगा :-) – Pointy

0

आप समस्या है आप एक वस्तु एक instantiated वस्तु

करने की कोशिश करने के बजाय शाब्दिक का उपयोग करने वाले इसके बजाए इस प्रकार:

var Game = function() { 
    this.initialize = function() { 
    if (canvas.isSupported()) { 
     sprites[0] = new Player(); 
     this.update(); 
    } 
    }; 
    this.update = function() { 
    for (var i = 0; i < sprites.length; i++) { 
     sprites[i].update(); 
    } 

    this.draw(); 
    }; 

    this.draw = function() { 
    this.clear(); 

    for (var i = 0; i < sprites.length; i++) { 
     sprites[i].draw(); 
    } 

    setTimeout(this.update, 10); 
    }; 

    this.clear = function() { 
    canvas.context.clearRect(0, 0, canvas.element.width, canvas.element.height); 
    }; 
} 

अब का उपयोग करें:

var myGame = new Game(); 
+0

मुझे लगता है कि समस्या का सिर्फ एक हिस्सा ... – Pointy

+2

'इस' के लिए वास्तव में एक अच्छा संदर्भ: http://bonsaiden.github.com/JavaScript-Garden/#function.this – adrian

+1

@Pointy: true, setTimeout है असफल होने के लिए बाध्य है, लेकिन ऐसा लगता है कि आप इसे कवर कर रहे हैं :) –

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