Chrome में "बिना पढ़ा हुआ टाइपर्रर: अवैध मंगलाचरण"


137

जब मैं requestAnimationFrameनीचे कोड के साथ कुछ देशी समर्थित एनीमेशन करने के लिए उपयोग करता हूं:

var support = {
    animationFrame: window.requestAnimationFrame ||
        window.mozRequestAnimationFrame ||
        window.webkitRequestAnimationFrame ||
        window.msRequestAnimationFrame ||
        window.oRequestAnimationFrame
};

support.animationFrame(function() {}); //error

support.animationFrame.call(window, function() {}); //right

सीधे बुलावा support.animationFrameदेगा ...

अनियोजित टाइपरोर: अवैध मंगलाचरण

क्रोम में। क्यों?

जवाबों:


195

अपने कोड में आप एक मूल विधि को कस्टम ऑब्जेक्ट की संपत्ति में असाइन कर रहे हैं। जब आप कॉल करते हैं support.animationFrame(function () {}), तो इसे वर्तमान ऑब्जेक्ट (यानी समर्थन) के संदर्भ में निष्पादित किया जाता है। नेटिव रिक्वेस्टएनिमेशनफ्रेम फ़ंक्शन को ठीक से काम करने के लिए, इसके संदर्भ में निष्पादित किया जाना चाहिए window

तो यहाँ सही उपयोग है support.animationFrame.call(window, function() {});

ऐसा ही अलर्ट के साथ भी होता है:

var myObj = {
  myAlert : alert //copying native alert to an object
};

myObj.myAlert('this is an alert'); //is illegal
myObj.myAlert.call(window, 'this is an alert'); // executing in context of window 

एक अन्य विकल्प फ़ंक्शन.प्रोटोटाइप.बिंद () का उपयोग करना है जो ईएस 5 मानक का हिस्सा है और सभी आधुनिक ब्राउज़रों में उपलब्ध है।

var _raf = window.requestAnimationFrame ||
        window.mozRequestAnimationFrame ||
        window.webkitRequestAnimationFrame ||
        window.msRequestAnimationFrame ||
        window.oRequestAnimationFrame;

var support = {
   animationFrame: _raf ? _raf.bind(window) : null
};

1
Chrome 33 के रूप में, दूसरा कॉल "अवैध मंगलाचरण" के साथ विफल हो जाता है। उत्तर अपडेट होने के बाद डाउनवोट को हटाकर हैप्पी !
Dan Dascalescu

@DanDascalescu: मैं क्रोम 33 का उपयोग कर रहा हूं और यह मेरे लिए काम कर रहा है।
नेमोय

1
मैंने अभी आपके कोड को कॉपी-पेस्ट किया है और अवैध आमंत्रण त्रुटि प्राप्त की है। यहां पर पेंचकस है।
डेन डैस्कलेस्कु

24
आप निश्चित रूप से अवैध मंगलाचरण त्रुटि प्राप्त करेंगे, क्योंकि पहला हकलाना myObj.myAlert('this is an alert');अवैध है। सही उपयोग है myObj.myAlert.call(window, 'this is an alert')। कृपया उत्तरों को ठीक से पढ़ें और उसे समझने की कोशिश करें।
नेमोय

3
अगर मैं यहाँ केवल एक ही नहीं हो रहा हूँ, तो सांत्वना पाने की कोशिश में फंस गया हूँ। उसी तरह से काम करने के लिए। "यह" कंसोल होना चाहिए, खिड़की नहीं: stackoverflow.com/questions/8159233/…
एलेक्स

17

आप भी उपयोग कर सकते हैं:

var obj = {
    alert: alert.bind(window)
};
obj.alert('I´m an alert!!');

2
यह पूरी तरह से सवाल का जवाब नहीं देता है। मुझे लगता है कि यह एक टिप्पणी नहीं बल्कि एक उत्तर होना चाहिए।
मिशैल पेरोलाकोव्स्की

2
इसके अलावा, उपयुक्त वस्तु को बांधना महत्वपूर्ण है, जैसे जब history.replaceState के साथ काम करना हो, तो किसी को इसका उपयोग करना चाहिए: var realReplaceState = history.replaceState.bind(history);
DeeY

@DeeY: मेरे प्रश्न का उत्तर देने के लिए धन्यवाद! भविष्य के लोगों के लिए, localStorage.clear आपको इसकी आवश्यकता है .bind(localStorage), नहीं .bind(window)
सम्यक नेपाल

13

जब आप किसी विधि को निष्पादित करते हैं (यानी किसी ऑब्जेक्ट को सौंपा गया कार्य), तो इसके अंदर आप thisइस ऑब्जेक्ट को संदर्भित करने के लिए चर का उपयोग कर सकते हैं , उदाहरण के लिए:

var obj = {
  someProperty: true,
  someMethod: function() {
    console.log(this.someProperty);
  }
};
obj.someMethod(); // logs true

यदि आप एक ऑब्जेक्ट से दूसरे ऑब्जेक्ट को असाइन करते हैं, तो इसका thisवेरिएबल उदाहरण के लिए नई ऑब्जेक्ट को संदर्भित करता है:

var obj = {
  someProperty: true,
  someMethod: function() {
    console.log(this.someProperty);
  }
};

var anotherObj = {
  someProperty: false,
  someMethod: obj.someMethod
};

anotherObj.someMethod(); // logs false

जब आप किसी अन्य ऑब्जेक्ट requestAnimationFrameकी विधि असाइन करते हैं तो वही बात होती है window। इस तरह के मूल कार्य, अन्य संदर्भ में इसे निष्पादित करने से निर्माण-सुरक्षा है।

एक Function.prototype.call()फ़ंक्शन है, जो आपको किसी अन्य संदर्भ में फ़ंक्शन को कॉल करने की अनुमति देता है। आपको बस इस विधि के पहले पैरामीटर के रूप में इसे (जो वस्तु संदर्भ के रूप में इस्तेमाल किया जाएगा) पास करना होगा। उदाहरण के लिए alert.call({})देता है TypeError: Illegal invocation। हालांकि, alert.call(window)ठीक काम करता है, क्योंकि अब alertअपने मूल दायरे में निष्पादित होता है।

यदि आप .call()अपनी वस्तु का उपयोग इस तरह करते हैं:

support.animationFrame.call(window, function() {});

यह ठीक काम करता है, क्योंकि आपकी वस्तु requestAnimationFrameके windowबजाय दायरे में निष्पादित होता है ।

हालाँकि, .call()हर बार जब आप इस पद्धति को कॉल करना चाहते हैं, तो यह बहुत ही सुंदर समाधान नहीं है। इसके बजाय, आप उपयोग कर सकते हैं Function.prototype.bind()। इसका समान प्रभाव पड़ता है .call(), लेकिन फ़ंक्शन को कॉल करने के बजाय, यह एक नया फ़ंक्शन बनाता है जिसे हमेशा निर्दिष्ट संदर्भ में कहा जाएगा। उदाहरण के लिए:

window.someProperty = true;
var obj = {
  someProperty: false,
  someMethod: function() {
    console.log(this.someProperty);
  }
};

var someMethodInWindowContext = obj.someMethod.bind(window);
someMethodInWindowContext(); // logs true

केवल नकारात्मक पक्ष Function.prototype.bind()यह है कि यह ECMAScript 5 का एक हिस्सा है, जो IE <= 8 में समर्थित नहीं है । सौभाग्य से, एमडीएन पर एक पॉलीफ़िल है

जैसा कि आप शायद पहले से ही पता लगा चुके हैं, आप .bind()हमेशा के requestAnimationFrameसंदर्भ में निष्पादित करने के लिए उपयोग कर सकते हैं window। आपका कोड इस तरह दिख सकता है:

var support = {
    animationFrame: (window.requestAnimationFrame ||
        window.mozRequestAnimationFrame ||
        window.webkitRequestAnimationFrame ||
        window.msRequestAnimationFrame ||
        window.oRequestAnimationFrame).bind(window)
};

तो आप बस का उपयोग कर सकते हैं support.animationFrame(function() {});

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