'তীর ফাংশন' এবং 'ফাংশন' সমান / বিনিময়যোগ্য?


519

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: () => {
    // ...
  }
};

Callbacks

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

// vs

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

ভারিয়াদিক ফাংশন

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

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

5
ES2015 আরও জনপ্রিয় হয়ে ওঠার সাথে তীর ফাংশন সম্পর্কিত একই প্রশ্ন আরও বেশি করে উঠে এসেছে। আমি মনে করি না যে এই ইস্যুটির জন্য একটি ভাল প্রমিত প্রশ্ন / উত্তর আছে তাই আমি এটি তৈরি করেছি। আপনি যদি ভাবেন যে ইতিমধ্যে একটি ভাল আছে তবে দয়া করে আমাকে জানান এবং আমি এটিটিকে সদৃশ হিসাবে বন্ধ করব বা এটি মুছব। উদাহরণগুলি উন্নত করতে বা নতুন একটি যুক্ত করতে নির্দ্বিধায়।
ফেলিক্স ক্লিং

2
জাভাস্ক্রিপ্ট ecma6 তীর ফাংশনে স্বাভাবিক ফাংশন পরিবর্তন সম্পর্কে কী ? অবশ্যই, একটি সাধারণ প্রশ্নটি কখনও কখনও তেমন ভাল এবং জেনেরিক হতে পারে না যতটা বিশেষভাবে একটি ক্যানোনিকাল হিসাবে লেখা হয়।
বার্গি

এই Plnkr উদাহরণটি দেখুন ভেরিয়েবলটি প্রতিবার বোতামটি কল করার সময় কেবল 1 দ্বারা thisখুব আলাদা timesCalledবৃদ্ধি হয় very যা আমার ব্যক্তিগত প্রশ্নের উত্তর দেয়: .click( () => { } )এবং .click(function() { }) উভয়ই লুপে ব্যবহার করার সময় একই সংখ্যক ফাংশন তৈরি করে যা আপনি Plnkr এর গাইড গণনা থেকে দেখতে পাবেন।
abbaf33f

উত্তর:


749

tl; dr: না! তীর ফাংশন এবং ফাংশন ঘোষণা / এক্সপ্রেশন সমতুল্য নয় এবং অন্ধভাবে প্রতিস্থাপন করা যায় না।
যদি ফাংশন আপনি প্রতিস্থাপন করতে না চান না ব্যবহার this, argumentsএবং বলা হয় না new, তারপর হ্যাঁ।


যেমন প্রায়ই: এটি নির্ভর করে । ফাংশন ঘোষণার / এক্সপ্রেশনগুলির চেয়ে তীরের ক্রিয়াকলাপগুলির ভিন্ন আচরণ থাকে, তাই আসুন প্রথমে তফাতগুলি একবার দেখি:

1. লেক্সিকাল thisএবংarguments

তীর ফাংশনগুলির নিজস্ব thisবা argumentsবাঁধাই নেই। পরিবর্তে, identif শনাক্তকারীদের অন্যান্য ভেরিয়েবলের মতো লেজিকাল স্কোপে সমাধান করা হয়। তার মানে তাদের একটি তীর ফাংশন ভিতরে, thisএবং argumentsমান পড়ুন thisএবং argumentsপরিবেশ তীর ফাংশন হয় সংজ্ঞায়িত (অর্থাত তীর ফাংশন "বাহিরে") মধ্যে:

// 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() {
    // ...
  },
};

Callbacks

এটা নির্ভর করে. আপনি যদি বাইরের অংশটিকে অ্যালিজ করছেন 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) => {
  // ...
};

সম্পর্কিত প্রশ্ন:

আরও সংস্থানগুলি:


6
সম্ভবত উল্লেখযোগ্যভাবে উল্লেখযোগ্য যে লেসিকালগুলিও thisপ্রভাবিত করে superএবং তাদের কোনও নেই .prototype
লগানফস্মিথ

1
এগুলি উল্লেখ করাও ভাল হবে যে তারা সিনথেটিকভাবে বিনিময়যোগ্য নয় - একটি তীর ফাংশন ( AssignmentExpression) কেবল যেখানেই একটি ফাংশন এক্সপ্রেশন ( PrimaryExpression) পারে সর্বত্র ফেলে দেওয়া যায় না এবং এটি মানুষকে প্রায়শই ঘন ঘন ঘন ঘন ট্রিপ করে (বিশেষত যেহেতু পার্সিং হয়েছে) প্রধান জেএস বাস্তবায়নে ত্রুটি)।
জেএমএম

@ জেএমএম: "এটি মানুষকে প্রায়শই ঘন ঘন ঘন ঘন ঘন ঘুরিয়ে দেয় " আপনি কি একটি নিদর্শন উদাহরণ দিতে পারেন? অনুমানের উপর ঝাঁপিয়ে পড়ে মনে হচ্ছে যে জায়গাগুলি যেখানে আপনি একটি এফই ফেলতে পারেন তবে একটি এএফ নয় এমন জায়গায় রানটাইম ত্রুটিগুলি যেভাবেই ঘটতে পারে ...
ফেলিক্স ক্লিং

নিশ্চিত, (একটি ফাংশন অভিব্যক্তি মত একটি তীর ফাংশন ডাকা অবিলম্বে বের করার চেষ্টা আমি গড় কাপড় () => {}()) অথবা ভালো কিছু করতে x || () => {}। এটাই আমার অর্থ: রানটাইম (পার্স) ত্রুটি। (এবং এটি সত্ত্বেও, প্রায়শই লোকেরা মনে করে যে ত্রুটিটি ত্রুটিযুক্ত) new'ইনগ ইন একটি রানটাইম ত্রুটি ঠিক আছে?
জেএমএম

এখানে এর কয়েকটি লিঙ্ক বন্যের মধ্যে আসছে: সাবট্যাক / নোড-ব্রাউজারিফাই # 1499 , ব্যাবেল / ব্যাবেল-এস্লিন্ট # 245 (এটি একটি অ্যাসিঙ্ক তীর, তবে আমি মনে করি এটি একই বেসিক সমস্যা), এবং আরও কিছু ইস্যু রয়েছে বাবেল যেগুলি এখন খুঁজে পাওয়া শক্ত, তবে এখানে একটি টি 2828৪
জেএমএম

11

তীর ফাংশন => এখন পর্যন্ত সেরা ES6 বৈশিষ্ট্য। তারা 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. ফাংশন এক্সপ্রেশন অবজেক্ট পদ্ধতির জন্য সেরা। তীর ফাংশন callbacks বা মত পদ্ধতি জন্য সবচেয়ে ভাল হয় map, reduceকিংবা forEach
  3. আপনি নাম ধরে কল করবেন এমন ফাংশনগুলির জন্য ফাংশন ঘোষণাগুলি ব্যবহার করুন (কারণ তারা উত্তোলন করা হয়েছে)।
  4. কলব্যাকগুলির জন্য তীর ফাংশনগুলি ব্যবহার করুন (কারণ তারা ক্ষুন্ন হতে থাকে)।

2
২. তাদের যুক্তি নেই, আমি দুঃখিত সত্য নয়, ... অপারেটর ব্যবহার না করে কারও পক্ষে যুক্তি থাকতে পারে, সম্ভবত আপনি বলতে চান যে আপনার পক্ষে যুক্তি হিসাবে বিন্যাস নেই
কারমিন তম্বাসিয়া

@ কারমাইনটাম্বাসিয়া সেই বিশেষ argumentsঅবজেক্ট সম্পর্কে পড়ুন যা তীর ফাংশনগুলিতে এখানে পাওয়া যায় না: developer.mozilla.org/en-US/docs/Web/JavaScript/References/…
vichle

0

এর সাথে তীর ফাংশনগুলি ব্যবহার করতে 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
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.