सवाल ES6 तीर फ़ंक्शंस और फ़ंक्शन.प्रोटोटाइप.बिंड से जुड़े फ़ंक्शंस के बीच मतभेद (यदि कोई हैं) क्या हैं?


मुझे ऐसा लगता है कि, ईएस 6 में, निम्नलिखित दो कार्य बहुत हैं लगभग समान:

function () {
  return this;
}.bind(this);

() => {
  return this;
};

अंतिम परिणाम समान लगता है: तीर फ़ंक्शन उनके साथ एक जावास्क्रिप्ट फ़ंक्शन ऑब्जेक्ट उत्पन्न करते हैं this संदर्भ के समान मूल्य के लिए बाध्य this जहां वे बनाए जाते हैं।

जाहिर है, सामान्य अर्थ में, Function.prototype.bind तीर कार्यों की तुलना में अधिक लचीला है: यह स्थानीय के अलावा अन्य मूल्यों से जुड़ सकता है this, और यह किसी भी समारोह को बांध सकता है this किसी भी समय, संभावित रूप से इसे शुरू करने के बाद संभावित रूप से लंबे समय तक। हालांकि, मैं नहीं पूछ रहा हूँ कि कैसे bind खुद तीर कार्यों से अलग है, मैं पूछ रहा हूं कि तुरंत कॉलिंग से तीर कार्य कैसे भिन्न होते हैं bind साथ में this

क्या ES6 में दो संरचनाओं के बीच कोई अंतर है?


38
2017-09-12 04:17


मूल


साथ में bind आप अनिवार्य रूप से दो कार्य बना रहे हैं। इसके अलावा, जिन चीजों का आपने उल्लेख किया है और तथ्य यह है कि तीर कार्यों में अधिक संक्षिप्त वाक्यविन्यास है, इसमें कोई अंतर नहीं है। - Felix Kling
चूंकि यह प्रश्न नहीं खोजता है और इसका उत्तर किसी भी समय प्रदान नहीं करता है जहां आपके पास उपयोग करने का अच्छा कारण हो सकता है bind एक तीर समारोह पर, मैंने ऐसा करने के बारे में एक नया सवाल पूछा है: runkit.com/embed/yhv29j5sybvn - hippietrail


जवाब:


कोई (महत्वपूर्ण) अंतर नहीं हैं।

ठीक है, ठीक है, यह थोड़ा समयपूर्व है। वहा तीन है छोटे तीर कार्यों के लिए अद्वितीय मतभेद।

  1. तीर कार्यों का उपयोग नहीं किया जा सकता है new

    इसका मतलब है, ज़ाहिर है कि उनके पास नहीं है prototype संपत्ति और क्लासिकली-प्रेरित वाक्यविन्यास के साथ एक वस्तु बनाने के लिए इस्तेमाल नहीं किया जा सकता है।

    new (() => {}) // TypeError: () => {} is not a constructor
    

    यह शायद सबसे अच्छा है, वैसे भी new काम बाध्य कार्यों के साथ ज्यादा समझ में नहीं आता है।

  2. तीर कार्यों के पास विशेष तक पहुंच नहीं है arguments ऑब्जेक्ट कि सामान्य जावास्क्रिप्ट कार्यों तक पहुंच है।

    (() => arguments)(1, 2, 3) // ReferenceError: arguments is not defined
    

    यह शायद एक गॉचा का थोड़ा और अधिक है। संभवतः यह जावास्क्रिप्ट की अन्य विषमताओं में से एक को हटाना है। arguments वस्तु अपने स्वयं के विशेष जानवर है, और इसमें अजीब व्यवहार है, इसलिए यह आश्चर्य की बात नहीं है कि इसे फेंक दिया गया था।

    इसके बजाए, ईएस 6 में विभाजन हैं जो बिना किसी जादू के छिपे हुए चर के एक ही चीज़ को पूरा कर सकते हैं:

    ((...args) => args)(1, 2, 3) // [1, 2, 3]
    
  3. तीर कार्यों का अपना नहीं है new.target संपत्ति, वे उपयोग करते हैं new.target यदि यह अस्तित्व में है, तो उनके संलग्न कार्य का।

    यह तीर कार्यों के लिए "जादुई" पेश किए गए मानों को हटाने के लिए अन्य परिवर्तनों के अनुरूप है। यह विशेष परिवर्तन विशेष रूप से स्पष्ट है, क्योंकि तीर कार्यों पर विचार नहीं किया जा सकता है new वैसे भी, ऊपर वर्णित है।

अन्यथा, तीर केवल बाध्य कार्यों की तरह हैं, अर्थात्। तीरों के लिए अधिक प्रदर्शन करने के लिए यह संभव है, क्योंकि उन्हें अतिरिक्त सामान लेना नहीं पड़ता है और चूंकि उन्हें पहले सामान्य कार्यों से परिवर्तित करने की आवश्यकता नहीं होती है, लेकिन वे व्यवहारिक रूप से वही हैं।


29
2017-09-12 05:40



मैं नहीं कहूंगा arguments "अजीब व्यवहार" के कारण फेंक दिया गया था (जिसे वैसे भी सख्त मोड में तय किया गया है)। इसके बजाय, तीर फ़ंक्शन उनके संलग्न कार्य को एक्सेस कर सकते हैं arguments ऑब्जेक्ट, इसके साथ संगत कैसे वे इसका उपयोग करते हैं this बाध्यकारी और new.target। - Bergi
@ बर्गी सख्त मोड में भी, arguments काफी अजीब है: यह अभी भी एक सरणी नहीं है, इसलिए एक विभाजन अभी भी अधिक उपयोगी और अनुमानित है। - Alexis King
@AlexisKing, आपको निश्चित रूप से अपने उत्तर में मूल संदर्भ को स्वीकार करने का उल्लेख करना चाहिए। - richardpringle


कुछ मतभेद हैं:

  • तीर कार्यों का निर्माण नहीं किया जा सकता है। जबकि दोनों तीर कार्यों और बाध्य कार्यों दोनों में एक नहीं है .prototype संपत्ति, पूर्व के साथ बुलाए जाने पर एक अपवाद फेंक देते हैं new जबकि उत्तरार्द्ध केवल बाध्य मूल्य को अनदेखा करते हैं और नए लक्ष्य पर उनके लक्ष्य कार्य को कन्स्ट्रक्टर (आंशिक रूप से लागू बाध्य तर्कों के साथ) कहते हैं।

    function F() {}
    var f = () => {},
        boundF = F.bind({});
    console.log(new boundF(), new boundF instanceof F) // {}, true
    console.log(new f) // TypeError
    
  • तीर कार्यों में शब्दावली होती है arguments, new.targetतथा super साथ ही (न केवल व्याख्यात्मक this)। एक तीर फ़ंक्शन पर एक कॉल उन में से किसी को प्रारंभ नहीं करता है, वे केवल उस क्रिया से विरासत में प्राप्त होते हैं जिसमें तीर फ़ंक्शन को परिभाषित किया गया था। बाध्य कार्य में, वे केवल लक्ष्य फ़ंक्शन के संबंधित मानों को संदर्भित करते हैं।

  • तीर कार्य वास्तव में एक बांध नहीं है this मूल्य। इसके बजाय, उनके पास एक नहीं है, और जब आप इसका उपयोग करते हैं this यह व्याख्यात्मक दायरे में एक परिवर्तनीय नाम की तरह देखा जाता है। यह आपको आलसी कार्य को आलसी रूप से परिभाषित करने की अनुमति देता है this अभी तक उपलब्ध नहीं है:

    class X extends Object {
        constructor() {
             var f = () => this, // works
                 boundF = function(){ return this; }.bind(this);
    //                                                    ^^^^ ReferenceError
             super(); // initialises `this`
             console.log(f(), f() == this); // {}, true
        }
    }
    new X;
    
  • तीर कार्य जनरेटर फ़ंक्शन नहीं हो सकते हैं (हालांकि वे जेनरेटर वापस कर सकते हैं)। आप उपयोग कर सकते हैं .bind() जनरेटर फ़ंक्शन पर, अभी तक तीर फ़ंक्शन का उपयोग करके इसे व्यक्त करने का कोई तरीका नहीं है।


26
2017-09-12 13:34





यहां एक और सूक्ष्म अंतर है:

तीर फ़ंक्शंस {} ब्रेसिज़ को तुरंत => के बाद छोड़कर, 'वापसी' कीवर्ड का उपयोग किए बिना एक मूल्य वापस कर सकता है।

var f=x=>x;           console.log(f(3));  // 3
var g=x=>{x};         console.log(g(3));  // undefined
var h=function(x){x}; console.log(h(3));  // undefined
var i=x=>{a:1};       console.log(i(3));  // undefined
var j=x=>({a:1});     console.log(j(3));  // {a:1}

3
2017-07-24 09:59