'यह' जावास्क्रिप्ट वर्ग विधियों में अपरिभाषित है


84

मैं जावास्क्रिप्ट के लिए नया हूँ। नई जहाँ तक मैंने वास्तव में इसके साथ किया है मौजूदा कोड को ट्विक किया गया है और छोटे बिट्स jQuery के लिखे हैं।

अब मैं विशेषताओं और विधियों के साथ एक "वर्ग" लिखने का प्रयास कर रहा हूं, लेकिन मुझे विधियों से परेशानी हो रही है। मेरा कोड:

function Request(destination, stay_open) {
    this.state = "ready";
    this.xhr = null;
    this.destination = destination;
    this.stay_open = stay_open;

    this.open = function(data) {
        this.xhr = $.ajax({
            url: destination,
            success: this.handle_response,
            error: this.handle_failure,
            timeout: 100000000,
            data: data,
            dataType: 'json',
        });
    };

    /* snip... */

}

Request.prototype.start = function() {
    if( this.stay_open == true ) {
        this.open({msg: 'listen'});
    } else {

    }
};
//all console.log's omitted

समस्या यह है, में Request.prototype.start, thisअपरिभाषित है और इस तरह अगर बयान मूल्यांकन गलत पर है। मुझसे यहां क्या गलत हो रहा है?


क्या आपके पास कोई कारण startहै prototype?
xj9

किसके Request.prototypeलिए निर्धारित है?
मैट बॉल

मेरा यहाँ भी ऐसा ही सवाल था: stackoverflow.com/questions/3198264/… जिसमें सहायक लिंक का एक गुच्छा है। इसका सार यह है कि thisजावास्क्रिप्ट में एक प्रोटोटाइप फ़ंक्शन के 'मालिक' के लिए एक निरंतर संदर्भ नहीं है जिसे बुलाया जा रहा है, जैसे कि यह जावा जैसी अधिकांश ओओ भाषाओं में होगा।
मार्क बोलिंगर 5

1
@ मैट: अनुरोध एक निर्माण कार्य है। Request.prototyp करने के लिए डिफ़ॉल्ट new Object()। जो कुछ भी आप इसे जोड़ते हैं वह स्वचालित रूप से उपयोग की गई वस्तुओं के गुण बन जाते हैं new Request()
चेतन एस

@ मट बॉल Request.prototypeवह जगह है जहां से Requestविरासत मिलती है। इस मामले में यह शायद है Functionया Object
xj9

जवाबों:


68

आप स्टार्ट फंक्शन को कैसे कह रहे हैं?

यह काम करना चाहिए ( नई कुंजी है)

var o = new Request(destination, stay_open);
o.start();

यदि आप सीधे इसे पसंद करते हैं Request.prototype.start(), thisतो वैश्विक संदर्भ ( windowब्राउज़र में) को संदर्भित करेगा ।

इसके अलावा, यदि thisअपरिभाषित है, तो इसका परिणाम त्रुटि है। अगर अभिव्यक्ति झूठ का मूल्यांकन नहीं करती है।

अद्यतन : thisवस्तु घोषणा के आधार पर निर्धारित नहीं है, लेकिन मंगलाचरण द्वारा । इसका अर्थ यह है कि यदि आप फ़ंक्शन प्रॉपर्टी को किसी वैरिएबल को x = o.startकॉल और कॉल की तरह असाइन करते हैं x(), तो thisस्टार्ट के अंदर अब कोई संदर्भ नहीं है o। यह तब होता है जब आप करते हैं setTimeout। इसे काम करने के लिए, इसके बजाय यह करें:

 var o = new Request(...);
 setTimeout(function() { o.start(); }, 1000);

मैं सेटटाइमआउट का उपयोग कर रहा हूं:var listen = new Request(destination, stay_open); setTimeout(listen.start, 500);
कार्सन मायर्स

इसने मेरे जीवन को बचाया, यह समझने की कोशिश करने के लिए कि मैं जिस फ़ंक्शन को व्यक्त करने के लिए गुजर रहा था, वह यह था कि ' ऑउटल ' उसी आउटपुट के साथ काम नहीं कर रहा था।
एडीसन स्पेंसर

या करते हैं o.start.bind(o)x = o.start; x()काम क्यों नहीं करता?
Theonlygusti

.bind()एक नया कार्य देता है, जगह में काम नहीं कर रहा है। तो आपको करना होगा x = o.start.bind(o); x()याo.start = o.start.bind(o); x=o.start; x()
ceedob

38

मैं केवल यह बताना चाहता था कि कभी-कभी यह त्रुटि होती है क्योंकि एक फ़ंक्शन का उपयोग उच्च आदेश फ़ंक्शन (एक तर्क के रूप में पारित) के रूप में किया जाता है और फिर thisखो जाने की गुंजाइश होती है । ऐसे मामलों में, मैं इस तरह के समारोह के लिए बाध्य होने की सिफारिश करूंगा this। उदाहरण के लिए

this.myFunction.bind(this);

3
अच्छे खर्च !! मुझे इसी की तो तलाश थी।
वंडर्सडॉन्फ

1
वहाँ कोई बता नहीं है कि आपने मुझे कितना सिरदर्द बचाया है
मूल निवासी कोडर

thisखो जाने की गुंजाइश क्यों है ?
theonlygusti

17

जावास्क्रिप्ट का OOP थोड़ा फंकी (या बहुत) है और इसका उपयोग करने में कुछ समय लगता है। यह पहली बात जो आपको ध्यान में रखने की जरूरत है वह यह है कि कोई भी वर्ग नहीं है और कक्षाओं के संदर्भ में सोच आपको यात्रा करा सकती है। और एक कंस्ट्रक्टर (एक वर्ग परिभाषा के जावास्क्रिप्ट के बराबर) से जुड़ी एक विधि का उपयोग करने के लिए आपको अपनी वस्तु को तत्काल करने की आवश्यकता है। उदाहरण के लिए:

Ninja = function (name) {
    this.name = name;
};
aNinja = new Ninja('foxy');
aNinja.name; //-> 'foxy'

enemyNinja = new Ninja('boggis');
enemyNinja.name; //=> 'boggis'

ध्यान दें कि Ninjaउदाहरणों में समान गुण हैं, लेकिन aNinjaके गुणों तक नहीं पहुंच सकते हैं enemyNinja। (यह हिस्सा वास्तव में आसान / सरल होना चाहिए) जब आप सामान जोड़ना शुरू करते हैं तो चीजें थोड़ी अलग हो जाती हैं prototype:

Ninja.prototype.jump = function () {
   return this.name + ' jumped!';
};
Ninja.prototype.jump(); //-> Error.
aNinja.jump(); //-> 'foxy jumped!'
enemyNinja.jump(); //-> 'boggis jumped!'

इसे सीधे कॉल करना एक त्रुटि है क्योंकि thisकेवल सही ऑब्जेक्ट (आपका "क्लास") को इंगित करता है जब कंस्ट्रक्टर को तत्काल किया जाता है (अन्यथा यह वैश्विक ऑब्जेक्ट को इंगित करता है, windowएक ब्राउज़र में)


6

ES2015 उर्फ ​​ईएस 6 में, के classलिए एक सिंटैक्टिक चीनी है functions

यदि आप एक संदर्भ सेट करने के लिए बाध्य करना चाहते हैं तो आप विधि का thisउपयोग कर सकते हैं bind()। जैसा कि @ चेतन ने बताया, मंगलाचरण पर आप संदर्भ भी सेट कर सकते हैं! नीचे दिए गए उदाहरण की जाँच करें:

class Form extends React.Component {
constructor() {
    super();
  }
  handleChange(e) {
    switch (e.target.id) {
      case 'owner':
        this.setState({owner: e.target.value});
        break;
      default:
    }
  }
  render() {
    return (
      <form onSubmit={this.handleNewCodeBlock}>
        <p>Owner:</p> <input onChange={this.handleChange.bind(this)} />
      </form>
    );
  }
}

यहाँ हम अंदर संदर्भ मजबूर handleChange()करने के लिए Form


6
आपको कंस्ट्रक्टर में फ़ंक्शन को बांधना चाहिए। अन्यथा आप इसे हर बार बाँध रहे हैं renderजब कक्षा को तत्काल किया जाता है तो एक बार के बजाय इसे बुलाया जाता है। साथ ही, आपका अधिकांश उदाहरण वास्तव में प्रश्न के लिए प्रासंगिक नहीं है।
erich2k8

या handleChange()
नितिन

0

इस सवाल का जवाब दिया गया है, लेकिन हो सकता है कि यह कोई और यहां आ रहा हो।

मेरे पास एक मुद्दा भी है जहां thisअपरिभाषित है, जब मैं मूर्खतापूर्ण तरीके से एक वर्ग के तरीकों को नष्ट करने की कोशिश कर रहा था, जब इसे कमजोर किया जा रहा था:

import MyClass from "./myClass"

// 'this' is not defined here:
const { aMethod } = new MyClass()
aMethod() // error: 'this' is not defined

// So instead, init as you would normally:
const myClass = new MyClass()
myClass.aMethod() // OK


0

तीर फ़ंक्शन का उपयोग करें:

Request.prototype.start = () => {
    if( this.stay_open == true ) {
        this.open({msg: 'listen'});
    } else {

    }
};
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.