javascript - Var me=this का मूल्य क्या है;




extjs (9)

मुझे यह पैटर्न सभी ExtJS स्रोत कोड पर मिलता है।

method: function() {
  var me = this;
  ...
  me.someOtherMethod();
}

वे इसका उपयोग क्यों नहीं करते? क्या me हमेशा परिभाषित करने के लिए कुछ फायदा होता me (बाहर 2 अक्षर टाइप करने के बाहर)? मैं समझ सकता हूं कि क्या वे बंद होने के माध्यम से संदर्भ को बनाए रखने की कोशिश कर रहे हैं, लेकिन यह उन जगहों पर किया जाता है जहां कोई बंद नहीं होता है।

Ext.panel.Panel से एक उदाहरण:

disable: function(silent) {
    var me = this;

    if (me.rendered) {
        me.el.addCls(me.disabledCls);
        me.el.dom.disabled = true;
        me.onDisable();
    }

    me.disabled = true;

    if (silent !== true) {
        me.fireEvent('disable', me);
    }

    return me;
},

Answers

यदि आपकी लाइब्रेरी ऐसी जगहों पर ऐसा कर रही है जहां कोई एम्बेडेड क्लोजर / कॉलबैक नहीं है जिसके पास इसका अपना मूल्य हो, तो यह सिर्फ एक "अभ्यास" या "शैली" या "सम्मेलन" है जिसे उन्होंने अपने तरीकों का पालन करने का फैसला किया। हमेशा ऐसा करने के लिए कोई प्रोग्रामिंग कारण नहीं है।

विशिष्ट कोडिंग उदाहरण में अब आपने अपने प्रश्न में जोड़ा है, मुझे कोई सामान्य कोडिंग शैली के अलावा अन्य के बारे में पता नहीं है। यह कोड एक ही परिणाम को थोड़ा छोटा कोड उत्पन्न करेगा:

disable: function(silent) {

    if (this.rendered) {
        this.el.addCls(this.disabledCls);
        this.el.dom.disabled = true;
        this.onDisable();
    }

    this.disabled = true;

    if (silent !== true) {
        this.fireEvent('disable', this);
    }

    return this;
},

जब कॉलबैक या क्लोजर शामिल होता है, तो अक्सर ऐसा किया जाता है क्योंकि विधि के अंदर कॉलबैक का उपयोग किया जाता है जहां वे अभी भी इसका संदर्भ चाहते हैं, लेकिन उन कॉलबैक के पास इसका अपना मूल्य this ताकि असाइन किया जा सके:

var me = this;

या आमतौर पर मैंने देखा है कि दूसरे कोड में:

var self = this;

उस ऑब्जेक्ट तक पहुंच को बनाए रखने का एक तरीका है, यहां तक ​​कि कॉलबैक में इसका एक अलग मूल्य है।

यहां एक सामान्य उदाहरण दिया गया है:

document.getElementById("myButton").onclick = function () {
    var self = this;       // save reference to button object use later
    setTimeout(function() {
        // "this" is not set to the button inside this callback function (it's set to window)
        // but, we can access "self" here 
        self.style.display = "none";    // make button disappear 2 seconds after it was clicked
    }, 2000);
};

Ext.panel.Panel उदाहरण के आधार पर आपने अभी जोड़ा है, जब तक कि जावास्क्रिप्ट चर की मेरी समझ काफी गलत न हो, यहां तक ​​कि असाइनमेंट न करने से कोड पर क्या असर नहीं पड़ेगा।

छोड़ दिया एकमात्र संभावना शैली है।

जबकि मैं इसे ओवेरिनियरिंग के रूप में स्थापित करता हूं, यह इस हद तक उपयोगी है कि यदि आप कभी भी उस कॉलबैक को जोड़ना चाहते हैं जिसके लिए इस संदर्भ में इसका उपयोग करना आवश्यक है, तो आपको यह सब me लिए बदलने के लिए वापस जाने की आवश्यकता नहीं होगी। रों। आखिरकार, टाइपिंग :s/ कठिन है।


एक्स्टजेस काम करते समय मुझे यह सम्मेलन उपयोगी नहीं मिला। मैंने अक्सर बंद करने का उपयोग नहीं किया। AngularJs जैसे अन्य ढांचे में काम करते समय इस सम्मेलन ने मुझे बहुत दर्द और पीड़ा बचाई है। अपना गुंजाइश गलत प्राप्त करना एक समय लेने वाली बग को ट्रैक करने के लिए है। एक बार जब मैंने इस सम्मेलन का उपयोग शुरू किया, तो मुझे फिर से गुंजाइश गलत नहीं मिली।


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


समस्या सबसे अधिक संभावना बंद करने के कार्यों से जुड़ा हुआ है, उदाहरण के लिए जब आप कॉलबैक पंजीकृत करते हैं तो एक तर्क के रूप में। उस स्थिति में "इस" का एक अलग मूल्य हो सकता है, इसलिए उन्हें इसके बजाय "मुझे" उपयोग करने की आवश्यकता है।


बंद करने में उपयोग के लिए एक संदर्भ बनाए रखने के बाहर मुझे उस पैटर्न का उपयोग करने के साथ किसी भी प्रोग्रामेटिक अंतर से अवगत नहीं है। शायद यह सिर्फ एक सम्मेलन है जो एक्स्टजेस का उपयोग कर रहा है।

इसके अतिरिक्त, जैसा कि डैनियल द्वारा उल्लेख किया गया है, यह छोटाकरण के दौरान भी कोड को छोटा करना हो सकता है। एक्स्टजेस, jQuery, आदि जैसे पुस्तकालय फ़ाइल आकारों के बारे में बहुत अधिक ध्यान देते हैं और इस तकनीक का उपयोग करने से पर्याप्त फ़ाइल आकार बचत मिल सकती है

उदाहरण के लिए 1000 'यह', 1 char = 1 बाइट मानते हुए, 4kb है। ऊपर की तकनीक का उपयोग संभवतः 2 या 3 केबी बंद कर सकते हैं।

अद्यतन: आगे बढ़ गया और एक छोटा प्रयोग किया ..

var test = {
  a : function() {
     this.x='';
     this.x='';
     this.x='';
      this.x='';
     this.x='';
     this.x='';
     this.x='';
     this.x='';
     this.x='';
      this.x='';
     this.x='';
     this.x='';
  },
  b : function() {
      this.x='';
     this.x='';
     this.x='';
      this.x='';
     this.x='';
     this.x='';
     this.x='';
     this.x='';
     this.x='';
      this.x='';
     this.x='';
     this.x='';
  },
  c : function() {
      this.x='';
     this.x='';
     this.x='';
      this.x='';
     this.x='';
     this.x='';
     this.x='';
     this.x='';
     this.x='';
      this.x='';
     this.x='';
     this.x='';
  }
}

में कमी

var test={a:function(){this.x="";this.x="";this.x="";this.x="";this.x="";this.x="";this.x="";this.x="";this.x="";this.x="";this.x="";this.x=""},b:function(){this.x="";this.x="";this.x="";this.x="";this.x="";this.x="";this.x="";this.x="";this.x="";this.x="";this.x="";this.x=""},c:function(){this.x="";this.x="";this.x="";this.x="";this.x="";this.x="";this.x="";this.x="";this.x="";this.x="";this.x="";this.x=""}}

जबकि

var test = {
  a : function() {
     var me=this;
     me.x='';
     me.x='';
     me.x='';
      me.x='';
     me.x='';
     me.x='';
     me.x='';
     me.x='';
     me.x='';
      me.x='';
     me.x='';
     me.x='';
  },
  b : function() {
      var me=this;
     me.x='';
     me.x='';
     me.x='';
      me.x='';
     me.x='';
     me.x='';
     me.x='';
     me.x='';
     me.x='';
      me.x='';
     me.x='';
     me.x='';
  },
  c : function() {
      var me=this;
     me.x='';
     me.x='';
     me.x='';
      me.x='';
     me.x='';
     me.x='';
     me.x='';
     me.x='';
     me.x='';
      me.x='';
     me.x='';
     me.x='';
  }
}

में कमी

var test={a:function(){var a=this;a.x="";a.x="";a.x="";a.x="";a.x="";a.x="";a.x="";a.x="";a.x="";a.x="";a.x="";a.x=""},b:function(){var a=this;a.x="";a.x="";a.x="";a.x="";a.x="";a.x="";a.x="";a.x="";a.x="";a.x="";a.x="";a.x=""},c:function(){var a=this;a.x="";a.x="";a.x="";a.x="";a.x="";a.x="";a.x="";a.x="";a.x="";a.x="";a.x="";a.x=""}}

जो लगभग 10% अधिक या कम वर्णों का अनुवाद करता है (बेशक यह इस बात पर निर्भर करता है कि आपके कोड के ब्लॉक स्कोप में यह 'दोहराया जाता है)।


शैली के कारणों और खनन कारणों के अलावा, मैंने यह देखने के लिए प्रदर्शन को देखने का फैसला किया कि this या self कोई तेज़ था या नहीं। मैंने यह जेएसपीआरएफ परीक्षण बनाया है।

जैसा कि मैं सबसे अच्छा कह सकता हूं, मेरे द्वारा किए गए किसी भी आधुनिक ब्राउज़र में प्रदर्शन में कोई अंतर नहीं है या मैंने आईई 6 भी this बनाम उपयोग के माध्यम से self या me जैसे स्थानीय चर का उपयोग करके किया है। क्रोम self साथ इतनी तेज तेज है और अन्य कॉल के बहुत करीब हैं। मुझे लगता है कि हम किसी भी प्रदर्शन कारणों से इंकार कर सकते हैं। मैंने देखा परिणामों के एक स्क्रीन शॉट यहाँ दिया गया है:


असल में, हालांकि यह शायद प्रेरणा नहीं है, शैली के लिए ऐसा करने से कुछ समझ आता है। बहुत से स्टाइल सम्मेलन कुछ भूलना मुश्किल बनाते हैं, जैसे कि हमेशा एक और बयान के बावजूद {} को किसी अन्य ब्लॉक के आस-पास रखना। "इस" को पुन: असाइन करना उस शुरुआत में समान प्रभाव डालेगा जावास्क्रिप्ट प्रोग्रामर के पास उस समय का उच्च प्रतिशत "बस काम" बंद हो जाएगा।


यहां मानक रूपों पर रैंडडाउन है जो कार्य बनाते हैं: (मूल रूप से किसी अन्य प्रश्न के लिए लिखा गया है, लेकिन कैननिकल प्रश्न में स्थानांतरित होने के बाद अनुकूलित किया गया है।)

शर्तें:

त्वरित सूची:

  • समारोह घोषणा

  • "बेनामी" function अभिव्यक्ति (जो शब्द के बावजूद, कभी-कभी नामों के साथ फ़ंक्शन बनाती है)

  • नामित function अभिव्यक्ति

  • एक्सेसर फ़ंक्शन प्रारंभकर्ता (ES5 +)

  • तीर फ़ंक्शन अभिव्यक्ति (ES2015 +) (जो, अज्ञात फ़ंक्शन अभिव्यक्तियों की तरह, एक स्पष्ट नाम शामिल नहीं है, और फिर भी नामों के साथ फ़ंक्शन बना सकता है)

  • ऑब्जेक्ट इनिशिलाइज़र में विधि घोषणा (ES2015 +)

  • class में कन्स्ट्रक्टर और विधि घोषणाएं (ES2015 +)

समारोह घोषणा

पहला रूप एक समारोह घोषणा है , जो इस तरह दिखता है:

function x() {
    console.log('x');
}

एक समारोह घोषणा एक घोषणा है ; यह एक बयान या अभिव्यक्ति नहीं है। इस प्रकार, आप इसका पालन नहीं करते हैं ; (हालांकि ऐसा करना हानिरहित है)।

किसी चरण-दर-चरण कोड को निष्पादित करने से पहले निष्पादन उस संदर्भ में प्रवेश करता है जब निष्पादन में प्रकट होता है, एक फ़ंक्शन घोषणा संसाधित की जाती है। जो फ़ंक्शन बनाता है उसे उचित नाम दिया जाता है (ऊपर दिए गए उदाहरण में x ), और वह नाम उस दायरे में रखा जाता है जिसमें घोषणा प्रकट होती है।

चूंकि इसे एक ही संदर्भ में चरण-दर-चरण कोड से पहले संसाधित किया जाता है, इसलिए आप इस तरह की चीजें कर सकते हैं:

x(); // Works even though it's above the declaration
function x() {
    console.log('x');
}

ES2015 तक, कल्पना में शामिल नहीं था कि जावास्क्रिप्ट इंजन को क्या करना चाहिए यदि आप नियंत्रण संरचना के अंदर फ़ंक्शन घोषणा जैसे try , if , switch , इत्यादि, जैसे:

if (someCondition) {
    function foo() {    // <===== HERE THERE
    }                   // <===== BE DRAGONS
}

और चूंकि चरण-दर-चरण कोड चलाने से पहले उन्हें संसाधित किया जाता है, इसलिए यह जानना मुश्किल होता है कि जब वे नियंत्रण संरचना में होते हैं तो क्या करना है।

हालांकि ऐसा करने के लिए ES2015 तक निर्दिष्ट नहीं किया गया था, यह ब्लॉक में फ़ंक्शन घोषणाओं का समर्थन करने के लिए एक स्वीकार्य विस्तार था। दुर्भाग्य से (और अनिवार्य रूप से), विभिन्न इंजनों ने अलग-अलग चीजें कीं।

ES2015 के अनुसार, विनिर्देश कहता है कि क्या करना है। वास्तव में, यह करने के लिए तीन अलग-अलग चीजें देता है:

  1. यदि एक वेब ब्राउज़र पर ढीला मोड नहीं है, तो जावास्क्रिप्ट इंजन को एक काम करना चाहिए
  2. यदि किसी वेब ब्राउज़र पर ढीले मोड में, जावास्क्रिप्ट इंजन को कुछ और करना है
  3. यदि सख्त मोड (ब्राउज़र या नहीं) में, जावास्क्रिप्ट इंजन को अभी तक एक और चीज करना है

ढीले मोड के नियम मुश्किल हैं, लेकिन सख्त मोड में, ब्लॉक में फ़ंक्शन घोषणाएं आसान हैं: वे ब्लॉक के लिए स्थानीय हैं (उनके पास ब्लॉक स्कोप है , जो ES2015 में भी नया है), और वे शीर्ष पर फिसल गए हैं ब्लॉक का इसलिए:

"use strict";
if (someCondition) {
    foo();               // Works just fine
    function foo() {
    }
}
console.log(typeof foo); // "undefined" (`foo` is not in scope here
                         // because it's not in the same block)

"बेनामी" function अभिव्यक्ति

दूसरे सामान्य रूप को अनाम कार्य अभिव्यक्ति कहा जाता है:

var y = function () {
    console.log('y');
};

सभी अभिव्यक्तियों की तरह, यह मूल्यांकन किया जाता है जब यह कोड के चरण-दर-चरण निष्पादन में पहुंच जाता है।

ईएस 5 में, इस रचना के फ़ंक्शन का कोई नाम नहीं है (यह अनाम है)। ES2015 में, फ़ंक्शन को संदर्भ से संदर्भित करके संभवतः एक नाम असाइन किया गया है। उपर्युक्त उदाहरण में, नाम y होगा। कुछ ऐसा ही किया जाता है जब फ़ंक्शन किसी प्रॉपर्टी प्रारंभकर्ता का मान होता है। (यह कब होता है और नियमों के विवरण के लिए , विनिर्देशन में SetFunctionName खोज करें - यह पूरे स्थान पर दिखाई देता है।)

नामित function अभिव्यक्ति

तीसरा रूप एक नामित फ़ंक्शन अभिव्यक्ति ("एनएफई") है:

var z = function w() {
    console.log('zw')
};

इस रचना का कार्य उचित नाम है (इस मामले में w )। सभी अभिव्यक्तियों की तरह, यह मूल्यांकन किया जाता है जब यह कोड के चरण-दर-चरण निष्पादन में पहुंच जाता है। फ़ंक्शन का नाम उस दायरे में नहीं जोड़ा गया है जिसमें अभिव्यक्ति प्रकट होती है; नाम फ़ंक्शन के भीतर ही दायरे में है:

var z = function w() {
    console.log(typeof w); // "function"
};
console.log(typeof w);     // "undefined"

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

एक्सेसर फ़ंक्शन प्रारंभकर्ता (ES5 +)

कभी-कभी कार्य बड़े पैमाने पर अनजान में छेड़छाड़ कर सकते हैं; यह एक्सेसर फ़ंक्शंस के मामले में है। यहां एक उदाहरण दिया गया है:

var obj = {
    value: 0,
    get f() {
        return this.value;
    },
    set f(v) {
        this.value = v;
    }
};
console.log(obj.f);         // 0
console.log(typeof obj.f);  // "number"

ध्यान दें कि जब मैंने फ़ंक्शन का उपयोग किया, तो मैंने () उपयोग नहीं किया! ऐसा इसलिए है क्योंकि यह किसी संपत्ति के लिए एक एक्सेसर फ़ंक्शन है । हम संपत्ति को सामान्य तरीके से प्राप्त करते हैं और सेट करते हैं, लेकिन दृश्यों के पीछे, फ़ंक्शन को कॉल किया जाता है।

आप Object.defineProperty , Object.defineProperties , और Object.defineProperties लिए कम ज्ञात दूसरे तर्क के साथ Object.defineProperty फ़ंक्शंस भी बना सकते हैं।

तीर फंक्शन अभिव्यक्ति (ES2015 +)

ES2015 हमें तीर समारोह लाता है। यहां एक उदाहरण दिया गया है:

var a = [1, 2, 3];
var b = a.map(n => n * 2);
console.log(b.join(", ")); // 2, 4, 6

देखें कि n => n * 2 चीज़ map() में छिपा रही है map() कॉल? यह एक समारोह है।

तीर कार्यों के बारे में कुछ चीजें:

  1. उनके पास यह स्वयं नहीं है। इसके बजाय, वे संदर्भ के this पर बंद होते हैं जहां उन्हें परिभाषित किया जाता है। (वे arguments भी बंद करते arguments , जहां प्रासंगिक, super ।) इसका मतलब है कि this उनके भीतर समान है, जहां वे बनाए गए हैं, और बदला नहीं जा सकता है।

  2. जैसा कि आपने उपरोक्त के साथ देखा होगा, आप कीवर्ड function उपयोग नहीं करते हैं; इसके बजाय, आप => उपयोग करते हैं।

ऊपर n => n * 2 उदाहरण उनमें से एक रूप है। यदि आपके पास फ़ंक्शन पास करने के लिए कई तर्क हैं, तो आप माता-पिता का उपयोग करते हैं:

var a = [1, 2, 3];
var b = a.map((n, i) => n * i);
console.log(b.join(", ")); // 0, 2, 6

(याद रखें कि Array#map प्रवेश को पहले तर्क के रूप में पास करता है, और सूचकांक दूसरे के रूप में।)

दोनों मामलों में, समारोह का शरीर सिर्फ एक अभिव्यक्ति है; फ़ंक्शन का रिटर्न वैल्यू स्वचालित रूप से उस अभिव्यक्ति का परिणाम होगा (आप एक स्पष्ट return उपयोग नहीं करते return )।

यदि आप केवल एक अभिव्यक्ति से अधिक कर रहे हैं, तो {} और एक स्पष्ट return (यदि आपको मूल्य वापस करने की आवश्यकता है) का उपयोग करें, सामान्य के रूप में:

var a = [
  {first: "Joe", last: "Bloggs"},
  {first: "Albert", last: "Bloggs"},
  {first: "Mary", last: "Albright"}
];
a = a.sort((a, b) => {
  var rv = a.last.localeCompare(b.last);
  if (rv === 0) {
    rv = a.first.localeCompare(b.first);
  }
  return rv;
});
console.log(JSON.stringify(a));

{ ... } बिना संस्करण को अभिव्यक्ति निकाय या संक्षिप्त निकाय के साथ एक तीर फ़ंक्शन कहा जाता है । (इसके अलावा: एक संक्षिप्त तीर समारोह।) शरीर के साथ परिभाषित { ... } एक समारोह शरीर के साथ एक तीर समारोह है । (इसके अलावा: एक वर्बोज़ तीर समारोह।)

ऑब्जेक्ट इनिशिलाइज़र में विधि घोषणा (ES2015 +)

ES2015 एक ऐसी संपत्ति घोषित करने का एक छोटा रूप प्रदान करता है जो किसी फ़ंक्शन का संदर्भ देता है; यह इस तरह दिख रहा है:

var o = {
    foo() {
    }
};

ईएस 5 और पहले के बराबर होगा:

var o = {
    foo: function foo() {
    }
};

class में कन्स्ट्रक्टर और विधि घोषणाएं (ES2015 +)

ES2015 हमें घोषित रचनाकारों और विधियों सहित class वाक्यविन्यास लाता है:

class Person {
    constructor(firstName, lastName) {
        this.firstName = firstName;
        this.lastName = lastName;
    }

    getFullName() {
        return this.firstName + " " + this.lastName;
    }
}

ऊपर दो फ़ंक्शन घोषणाएं हैं: एक कन्स्ट्रक्टर के लिए, जिसे नाम Person जाता है, और getFullName लिए एक, जो Person.prototype को सौंपा गया एक फ़ंक्शन है।







javascript extjs