क्या Are एरो फंक्शंस ’और ions फंक्शन्स’ समतुल्य / विनिमेय हैं?

Dec 19 2015

ES2015 में एरो फ़ंक्शंस एक अधिक संक्षिप्त सिंटैक्स प्रदान करते हैं।

  • क्या मैं अपने सभी फ़ंक्शन घोषणाओं / अभिव्यक्तियों को अब एरो फ़ंक्शन के साथ बदल सकता हूं?
  • मुझे क्या देखना है?

उदाहरण:

कंस्ट्रक्टर फ़ंक्शन

function User(name) {
  this.name = name;
}

// vs

const User = name => {
  this.name = name;
};

प्रोटोटाइप के तरीके

User.prototype.getName = function() {
  return this.name;
};

// vs

User.prototype.getName = () => this.name;

वस्तु (शाब्दिक) विधियाँ

const obj = {
  getName: function() {
    // ...
  }
};

// vs

const obj = {
  getName: () => {
    // ...
  }
};

कॉलबैक

setTimeout(function() {
  // ...
}, 500);

// vs

setTimeout(() => {
  // ...
}, 500);

वेरिएडिक कार्य

function sum() {
  let args = [].slice.call(arguments);
  // ...
}

// vs
const sum = (...args) => {
  // ...
};

जवाब

817 FelixKling Dec 19 2015 at 00:58

tl; dr: नहीं! एरो फ़ंक्शंस और फ़ंक्शन घोषणाएं / अभिव्यक्तियाँ समतुल्य नहीं हैं और इन्हें नेत्रहीन रूप से प्रतिस्थापित नहीं किया जा सकता है।
यदि आप जिस फ़ंक्शन को बदलना चाहते हैं वह उपयोग नहीं करता है this, argumentsऔर इसके साथ नहीं बुलाया जाता है new, तो हाँ।


जैसा कि अक्सर: यह निर्भर करता है । फ़ंक्शन फ़ंक्शन / अभिव्यक्तियों की तुलना में एरो फ़ंक्शंस का व्यवहार अलग-अलग होता है, इसलिए पहले अंतरों पर एक नज़र डालते हैं:

1. लेक्सिकल thisऔरarguments

एरो फ़ंक्शंस के पास अपना thisया argumentsबाध्यकारी नहीं है। इसके बजाय, उन पहचानकर्ताओं को किसी अन्य चर की तरह शाब्दिक दायरे में हल किया जाता है। इसका मतलब है कि एक तीर फ़ंक्शन के अंदर, thisऔर पर्यावरण में और argumentsमानों को संदर्भित करता है तीर फ़ंक्शन को (यानी "बाहर" तीर ") में परिभाषित किया गया है:thisarguments

// Example using a function expression
function createObject() {
  console.log('Inside `createObject`:', this.foo);
  return {
    foo: 42,
    bar: function() {
      console.log('Inside `bar`:', this.foo);
    },
  };
}

createObject.call({foo: 21}).bar(); // override `this` inside createObject

// Example using a arrow function
function createObject() {
  console.log('Inside `createObject`:', this.foo);
  return {
    foo: 42,
    bar: () => console.log('Inside `bar`:', this.foo),
  };
}

createObject.call({foo: 21}).bar(); // override `this` inside createObject

फ़ंक्शन अभिव्यक्ति मामले में, thisउस ऑब्जेक्ट को संदर्भित करता है जिसे अंदर बनाया गया था createObject। तीर समारोह मामले में, thisको संदर्भित करता है thisकी createObjectअपने आप में।

यदि आपको thisवर्तमान परिवेश तक पहुँचने की आवश्यकता है, तो यह तीर के कार्यों को उपयोगी बनाता है:

// currently common pattern
var that = this;
getData(function(data) {
  that.data = data;
});

// better alternative with arrow functions
getData(data => {
  this.data = data;
});

ध्यान दें कि इसका मतलब यह भी है कि तीर फ़ंक्शन को या के साथ सेट करना संभव नहीं है ।this.bind.call

यदि आप बहुत परिचित नहीं हैं this, तो पढ़ने पर विचार करें

2. एरो फ़ंक्शंस के साथ नहीं बुलाया जा सकता है new

ES2015 कार्यों कि कर रहे हैं अलग बीच फोन सक्षम और कार्यों कि कर रहे हैं का निर्माण करने में सक्षम। यदि कोई फ़ंक्शन निर्माण योग्य है, तो इसे कहा जा सकता है new, अर्थात new User()। यदि कोई newफ़ंक्शन कॉल करने योग्य है, तो इसे बिना कॉल किया जा सकता है (यानी सामान्य फ़ंक्शन कॉल)।

फ़ंक्शन घोषणाओं / अभिव्यक्तियों के माध्यम से बनाए गए फ़ंक्शंस रचनात्मक और कॉल करने योग्य दोनों हैं।
एरो फ़ंक्शंस (और तरीके) केवल कॉल करने योग्य हैं। classकंस्ट्रक्टर केवल निर्माण योग्य हैं।

यदि आप एक गैर-कॉल करने योग्य फ़ंक्शन को कॉल करने या गैर-निर्माण योग्य फ़ंक्शन का निर्माण करने का प्रयास कर रहे हैं, तो आपको एक रनटाइम त्रुटि मिलेगी।


यह जानते हुए, हम निम्नलिखित बता सकते हैं।

बदली:

  • फ़ंक्शंस जो उपयोग नहीं करते हैं thisया arguments
  • जिन कार्यों के साथ उपयोग किया जाता है .bind(this)

बदली नहीं :

  • कंस्ट्रक्टर कार्य करता है
  • फ़ंक्शन / विधियों को एक प्रोटोटाइप में जोड़ा गया (क्योंकि वे आमतौर पर उपयोग करते हैं this)
  • वैरिएडिक फ़ंक्शन (यदि वे उपयोग करते हैं arguments(नीचे देखें))

अपने उदाहरणों का उपयोग करते हुए इसे करीब से देखें:

कंस्ट्रक्टर फ़ंक्शन

यह काम नहीं करेगा क्योंकि तीर फ़ंक्शन को नहीं बुलाया जा सकता है new। फ़ंक्शन घोषणा / अभिव्यक्ति या उपयोग का उपयोग करते रहें class

प्रोटोटाइप के तरीके

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

class User {
  constructor(name) {
    this.name = name;
  }
  
  getName() {
    return this.name;
  }
}

वस्तु विधियाँ

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

const obj = {
  getName() {
    // ...
  },
};

कॉलबैक

निर्भर करता है। यदि आप बाहरी रूप thisसे उपयोग कर रहे हैं या उपयोग कर रहे हैं, तो आपको इसे निश्चित रूप से प्रतिस्थापित करना चाहिए .bind(this):

// old
setTimeout(function() {
  // ...
}.bind(this), 500);

// new
setTimeout(() => {
  // ...
}, 500);

लेकिन: यदि कोड जो कॉलबैक को स्पष्ट रूप thisसे एक विशिष्ट मूल्य पर सेट करता है, जैसा कि अक्सर इवेंट हैंडलर के साथ होता है, विशेष रूप से jQuery के साथ, और कॉलबैक का उपयोग करता है this(या arguments), आप एक तीर फ़ंक्शन का उपयोग नहीं कर सकते हैं !

वेरिएडिक कार्य

चूंकि एरो फ़ंक्शंस के पास अपना नहीं है arguments, आप बस उन्हें एक तीर फ़ंक्शन के साथ बदल नहीं सकते हैं। हालांकि, ES2015 उपयोग करने के लिए एक विकल्प प्रस्तुत करता है arguments: बाकी पैरामीटर

// old
function sum() {
  let args = [].slice.call(arguments);
  // ...
}

// new
const sum = (...args) => {
  // ...
};

संबंधित प्रश्न:

आगे के संसाधन:

17 Ashutosh Jan 10 2020 at 03:22

एरो फ़ंक्शंस => अब तक का सबसे अच्छा ईएस 6 फ़ीचर। वे ES6 के लिए एक जबरदस्त शक्तिशाली जोड़ हैं, जिसका मैं लगातार उपयोग करता हूं।

रुको, आप अपने कोड में हर जगह तीर फ़ंक्शन का उपयोग नहीं कर सकते हैं, इसके सभी मामलों में काम नहीं करने जा thisरहे हैं जैसे कि तीर फ़ंक्शन उपयोग करने योग्य नहीं हैं। एक शक के बिना, तीर समारोह एक महान इसके अलावा यह कोड सादगी लाता है।

जब आप एक डायनामिक संदर्भ की आवश्यकता होती है, तो आप एक तीर फ़ंक्शन का उपयोग नहीं कर सकते हैं: तरीकों को परिभाषित करना, निर्माणकर्ताओं के साथ ऑब्जेक्ट बनाना, घटनाओं को संभालते समय इससे लक्ष्य प्राप्त करना।

एरो फ़ंक्शंस का उपयोग नहीं किया जाना चाहिए क्योंकि:

  1. उनके पास नहीं है this

    यह "लेक्सिकल स्कूपिंग" का उपयोग यह पता लगाने के लिए करता है कि " this" का मूल्य क्या होना चाहिए। सरल शब्द लेक्सिकल स्कूपिंग में यह thisफ़ंक्शन के शरीर के अंदर से " " का उपयोग करता है।

  2. उनके पास नहीं है arguments

    एरो फ़ंक्शंस में कोई argumentsऑब्जेक्ट नहीं है । लेकिन बाकी मापदंडों का उपयोग करके समान कार्यक्षमता प्राप्त की जा सकती है।

    let sum = (...args) => args.reduce((x, y) => x + y, 0) sum(3, 3, 1) // output - 7 `

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

    एरो फ़ंक्शंस बाधा नहीं बन सकते क्योंकि उनके पास एक प्रोटोटाइप संपत्ति नहीं है।

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

  1. ऑब्जेक्ट शाब्दिक रूप में फ़ंक्शन को जोड़ने के लिए उपयोग न करें क्योंकि हम इस तक पहुंच नहीं सकते हैं।
  2. फंक्शन एक्सप्रेशन ऑब्जेक्ट के तरीकों के लिए सबसे अच्छे हैं। तीर कार्यों कॉलबैक या तरह के तरीकों के लिए सबसे अच्छा कर रहे हैं map, reduceया forEach
  3. फ़ंक्शन के लिए फ़ंक्शन घोषणाओं का उपयोग करें जिन्हें आप नाम से बुलाएंगे (क्योंकि वे फहराए गए हैं)।
  4. कॉलबैक के लिए एरो फ़ंक्शंस का उपयोग करें (क्योंकि वे बहुत ख़राब होते हैं)।
2 toddmo May 16 2020 at 08:56

के साथ तीर फ़ंक्शन का उपयोग करने के लिए function.prototype.call, मैंने ऑब्जेक्ट प्रोटोटाइप पर एक सहायक फ़ंक्शन बनाया:

  // Using
  // @func = function() {use this here} or This => {use This here}
  using(func) {
    return func.call(this, this);
  }

प्रयोग

  var obj = {f:3, a:2}
  .using(This => This.f + This.a) // 5

संपादित करें

आप एक सहायक की जरूरत नहीं है। तुम यह कर सकते थे:

var obj = {f:3, a:2}
(This => This.f + This.a).call(undefined, obj); // 5