ES2015 এ আমি কীভাবে একটি নামযুক্ত তীর ফাংশন লিখব?


204

আমার একটি ফাংশন রয়েছে যা আমি ES6 এ নতুন তীর সিনট্যাক্সে রূপান্তরিত করার চেষ্টা করছি । এটি একটি নামকৃত কার্য:

function sayHello(name) {
    console.log(name + ' says hello');
}

কোনও বর্ণ বিবরণ ছাড়াই এটি নাম দেওয়ার কোনও উপায় আছে:

var sayHello = (name) => {
    console.log(name + ' says hello');
}

স্পষ্টতই, আমি এই ফাংশনটি সংজ্ঞায়িত করার পরেই ব্যবহার করতে পারি। নিম্নলিখিত কিছু মত:

sayHello = (name) => {
        console.log(name + ' says hello');
    }

ES6 এ করার কোনও নতুন উপায় আছে ?


3
তীর বাক্য গঠন বিন্দু নয় না ফাংশন একটি নাম দিন?
এস্ট্রোসিবি

64
অগত্যা, তীর ফাংশনগুলি লেক্সিকাল স্কোপ বজায় রাখে তাই লেক্সিক স্কোপ সহ নামযুক্ত ফাংশনগুলি (স্ট্যাক ট্রেসের জন্য দরকারী) উত্পাদন করার জন্য একটি শর্টহ্যান্ড থাকা বেশ কার্যকর হবে
ম্যাট স্টাইলস

6
দ্বিতীয় স্নিপেটে কী ভুল?
বার্গি

আপনি অবশ্যই কার্যকারিতাটির দেহের অভ্যন্তরে একটি নির্ধারিত নামটি উল্লেখ করতে পারেন: var sayHello = (নাম) => so কনসোল.লগ (বলে হেলো); }; এবং পুনরাবৃত্ত ক্রিয়াকলাপগুলির ক্ষেত্রে, আপনি প্রায়শই ঠিক এমনটি করেন। একটি দুর্দান্ত দরকারী উদাহরণ নয়, তবে এখানে এমন একটি ফাংশন রয়েছে যা তার যুক্তি না পেলে নিজেকে ফিরে দেয়: var sayHello = (নাম) => নাম? কনসোল.লগ (নাম + 'হ্যালো বলে'): বলুন হেলো; sayHello () ( 'অকপট'); // -> "অকপট বলেছেন হ্যালো"
ডিটিপসন

4
প্রশ্নের শিরোনাম এর সামগ্রীর সাথে তুলনা করে বিরাট বিভ্রান্তিকর, কারণ আপনি যেভাবে তীর ফাংশনটির নাম দিয়েছেন তা বাতিল করেছেন (এটি দ্বিতীয় স্নিপেট)।
টিজে ক্রাউডার

উত্তর:


211

ES2015 এ আমি কীভাবে একটি নামযুক্ত তীর ফাংশন লিখব?

আপনি আপনার প্রশ্নের যেভাবে রায় বাতিল করেছেন তা আপনি এটি করেন: আপনি কোনও অ্যাসাইনমেন্ট বা সম্পত্তি প্রাথমিককরণের ডানদিকে রেখেছেন যেখানে ভেরিয়েবল বা সম্পত্তির নামটি জাভাস্ক্রিপ্ট ইঞ্জিন দ্বারা যুক্তিযুক্তভাবে নাম হিসাবে ব্যবহার করা যেতে পারে। এটি করার মতো অন্য কোনও উপায় নেই তবে এটি করা সঠিক এবং স্পেসিফিকেশন দ্বারা সম্পূর্ণরূপে coveredাকা রয়েছে।

প্রতি বৈশিষ্ট হিসাবে, এই ফাংশনটির একটি সত্য নাম রয়েছে sayHello:

var sayHello = name => {
    console.log(name + ' says hello');
};

এটি এসাইনমেন্ট অপারেটর> রানটাইম শব্দার্থক: মূল্যায়ন যেখানে এটি বিমূর্ত SetFunctionNameঅপারেশনকে কল করে (এটি কলটি বর্তমানে পদক্ষেপে 1.eiii))

অবিচ্ছিন্নভাবে, রানটাইম শব্দার্থক: সম্পত্তি সংজ্ঞা মূল্যায়ন কল করে SetFunctionNameএবং এই ফাংশনটিকে একটি সত্য নাম দেয়:

let o = {
    sayHello: name => {
        console.log(`${name} says hello`);
    }
};

আধুনিক ইঞ্জিনগুলি ইতিমধ্যে এর মত বিবরণের জন্য ফাংশনের অভ্যন্তরীণ নাম সেট করে; nameএকটি রানটাইম পতাকার পিছনে ফাংশনের উদাহরণ হিসাবে এজ এখনও বিটটি উপলব্ধ করে।

উদাহরণস্বরূপ, ক্রোম বা ফায়ারফক্সে ওয়েব কনসোলটি খুলুন এবং তারপরে এই স্নিপেটটি চালান:

"use strict";
let foo = () => { throw new Error(); };
console.log("foo.name is: " + foo.name);
try {
  foo();
} catch (e) {
  console.log(e.stack);
}

ক্রোম ৫১ এবং তারপরে এবং ফায়ারফক্স ৫৩ এবং তার উপরে (এবং একটি পরীক্ষামূলক পতাকা সহ ১৩ এবং তার বেশি প্রান্তে) আপনি যখন এটি চালান, আপনি দেখতে পাবেন:

foo.name হ'ল: foo
ত্রুটি
    Foo এ (http://stacksnippets.net/js:14:23)
    http://stacksnippets.net/js 17:38 এ

নোট করুন foo.name is: fooএবং Error...at foo

ক্রোম ৫০ এবং তার আগে, ফায়ারফক্স ৫২ এবং তার আগে এবং পরীক্ষামূলক পতাকা ছাড়াই এজ, আপনি এটি পরিবর্তে দেখতে পাবেন কারণ তাদের কাছে নেই Function#name সম্পত্তি নেই (এখনও):

foo.name হ'ল: 
ত্রুটি
    Foo এ (http://stacksnippets.net/js:14:23)
    http://stacksnippets.net/js 17:38 এ

মনে রাখবেন যে, নাম থেকে অনুপস্থিত foo.name is:, কিন্তু এটা করা হয় স্ট্যাক ট্রেস দেখানো। এটি ঠিক যে ফাংশনে name সম্পত্তি বাস্তবায়ন করা অন্যান্য কিছু ES2015 বৈশিষ্ট্যের তুলনায় নিম্ন অগ্রাধিকার ছিল; ক্রোম এবং ফায়ারফক্স এখন এটি আছে; এজটির পতাকার পিছনে এটি রয়েছে, সম্ভবত এটি পতাকাটির পিছনে বেশি দিন থাকবে না।

স্পষ্টতই, আমি এই ফাংশনটি সংজ্ঞায়িত করার পরেই ব্যবহার করতে পারি

সঠিক। তীর ফাংশনগুলির জন্য কোনও ফাংশন ডিক্লেয়ারেশন সিনট্যাক্স নেই , কেবল ফাংশন এক্সপ্রেশন সিনট্যাক্স এবং ফাংশন এক্সপ্রেশন নামের একটি পুরানো স্টাইলে নামের সমান কোনও তীর নেই var f = function foo() { };। সুতরাং এর সমতুল্য নেই:

console.log(function fact(n) {
    if (n < 0) {
        throw new Error("Not defined for negative numbers");
    }
    return n == 0 ? 1 : n * fact(n - 1);
}(5)); // 120

আপনাকে এটিকে দুটি এক্সপ্রেশন ভাঙতে হবে (আমি তর্ক করব যে আপনার যাইহোক এটি করা উচিত ) :

let fact = n => {
    if (n < 0) {
      throw new Error("Not defined for negative numbers.");
    }
    return n == 0 ? 1 : n * fact(n - 1);
};
console.log(fact(5));

অবশ্যই, যদি আপনি এটি একটি জায়গায় রাখতে চান যেখানে একটি একক অভিব্যক্তি প্রয়োজন, আপনি সর্বদা ... একটি তীর ফাংশন ব্যবহার করতে পারেন:

console.log((() => {
    let fact = n => {
        if (n < 0) {
            throw new Error("Not defined for negative numbers.");
        }
        return n == 0 ? 1 : n * fact(n - 1);
    };
    return fact(5);
})()); // 120

আমি বলার অপেক্ষা রাখে না 'এটি বেশ সুন্দর, তবে এটি যদি আপনার একেবারে, ইতিবাচকভাবে একটি একক অভিব্যক্তি মোড়কের প্রয়োজন হয় তবে এটি কাজ করে।


কীভাবে নামটি সেট হওয়া থেকে রোধ করব (পুরানো ইঞ্জিনগুলির মতো)?
trusktr

1
@ ট্রাসক্রিটার: আপনি কেন চাইছেন তা আমি দেখতে পাচ্ছি না, তবে আপনি যদি এটি প্রতিরোধ করতে চান: উপরের জিনিসটি (গুলি) করবেন না। উদাহরণস্বরূপ, let f = () => { /* do something */ };ফাংশনটিতে একটি নাম নির্ধারণের সময় , let g = (() => () => { /* do something */ })();না।
টিজে ক্রোডার

এটাই আমি শেষ করেছিলাম। আমার ক্লাসের উত্তরাধিকার লাইব্রেরি দ্বারা বেনামে বানাতে বেনামে বানাতে আমার বেনিয়াল ভেরিয়েবলের নাম থাকার চেয়ে আমার ক্লাসের উত্তরাধিকার লাইব্রেরির ব্যবহারকারীদের ভেবে দেখার দরকার পড়েনি, এবং আমি শেষ ব্যবহারকারীটি একটি নাম দেখতে চাই তারা যদি ক্লাসের জন্য একটি নাম সরবরাহ করে তবেই। ( github.com/trusktr/lowclass )
trusktr

4
@trusktr: তাদের করা এক ব্যতিক্রমটি আপনার উদ্দেশ্যগুলির সাথে উপযুক্ত হতে পারে, তারপরে: আপনি যদি কোনও বিদ্যমান অবজেক্টের কোনও সম্পত্তিতে কোনও ফাংশন বরাদ্দ করেন তবে নামটি সেট করা হয় না: o.foo = () => {};ফাংশনটিকে কোনও নাম দেয় না। এই ইচ্ছাকৃত ছিল তথ্য ফুটো প্রতিরোধ।
টিজে ক্রাউডার 31'18

86

না। তীর বাক্য গঠন বেনামে ফাংশনগুলির জন্য একটি শর্টফর্ম। নামবিহীন ফাংশনগুলি হ'ল ভাল, বেনামে।

নামযুক্ত ফাংশনগুলি functionকীওয়ার্ড দিয়ে সংজ্ঞায়িত করা হয় ।


16
@ ডেনিসসগুরেট যেমন বলেছিলেন, বেনামি কার্যকারিতার জন্য কোনও শর্টফর্ম নয় । আপনি একটি হার্ড বাঁধা ফাংশন পাবেন। আপনি এখানে স্থানান্তরিত ফলাফলটি দেখতে পারেন বিট.ডো / এস ২০১৫- এটিকে কী বোঝায় তা আরও ভালভাবে বোঝার জন্য তরো ...
স্মিনটোলি

16
এই উত্তরের প্রথম শব্দটি জিজ্ঞাসা করা প্রশ্নের জন্য সঠিক কারণ ওপি আপনার তীর ফাংশনটির নামটি অস্বীকার করেছে । তবে উত্তরের বাকীটি কেবল ভুল। যেখানে জন্য স্পেসিফিকেশন তাকান বিমূর্ত SetFunctionNameঅপারেশন ব্যবহার করা হয়। let a = () => {};একটি সংজ্ঞায়িত নামে ফাংশন (নাম a) উভয় বৈশিষ্ট প্রয়োজন এবং আধুনিক ইঞ্জিন অনুযায়ী (এটা দেখার জন্য একটি ত্রুটি নিক্ষেপ); তারা কেবল nameসম্পত্তি এখনও সমর্থন করে না (তবে এটি অনুমানের মধ্যে রয়েছে এবং তারা শেষ পর্যন্ত সেখানে পাবেন)।
টিজে ক্রাউডার

4
@ ডেনিসসগারেট: আপনি কেবল তাদের নাম দিতে পারেন , এটি জল্পনা in ওপিতে যেভাবে প্রশ্নটিকে বাতিল করে দিয়েছিল তা আপনি এটি করেন যা ফাংশনটি দেয় (কেবল পরিবর্তনশীল নয়) একটি সত্য নাম দেয়।
টিজে ক্রাউডার

5
@ টিজে ক্রাউডার সেই বিট তথ্যের জন্য এবং আপনার দরকারী উত্তরের জন্য ধন্যবাদ । আমি এই (খুব খুব অদ্ভুত) বৈশিষ্ট্যটি জানতাম না।
অস্বীকার করেছেন সাগুরেট

4
এই উত্তরটি সঠিক নয়। প্রশ্ন নিচে @TJCrowder দ্বারা সঠিকভাবে উত্তর দেওয়া হয়েছিল
Drenai

44

যদি 'নামকরণ করা' দ্বারা, আপনার অর্থ .nameআপনার তীর ফাংশনটির সম্পত্তি সেট করা উচিত, আপনি ভাগ্যবান।

যদি একটি অ্যাসাইনমেন্ট এক্সপ্রেশনটির ডান হাতের দিকের একটি তীর ফাংশনটি সংজ্ঞায়িত করা হয় তবে ইঞ্জিনটি বাম-হাতের নামটি গ্রহণ করবে এবং তীর ফাংশনটি সেট করতে এটি ব্যবহার করবে .name, যেমন

var sayHello = (name) => {
    console.log(name + ' says hello');
}

sayHello.name //=== 'sayHello'

এটি বলার পরে, আপনার প্রশ্নটি আরও বেশি বলে মনে হচ্ছে 'উত্তোলনের জন্য আমি কী তীর ফাংশন পেতে পারি?' সেটার উত্তরটি একটি বড় অল 'না', আমি ভীত।


1
ক্রোমের বর্তমান সংস্করণে কমপক্ষে বলুন হেলো.নাম এখনও "" রয়েছে; মনে রাখবেন যে সমস্ত ফাংশনের মতো, হেলো একটি বস্তু, তাই আপনি যদি চান তবে এটিতে স্বেচ্ছাচারিত বৈশিষ্ট্যগুলি সংজ্ঞায়িত করতে পারেন। আপনি কেবল "নাম" এ এটি কেবল পঠনযোগ্য হিসাবে লিখতে পারবেন না, তবে আপনি বলতে পারেন হেলো.মাই_নাম = "sayHello"; এটি আপনাকে কী দেয় তা নিশ্চিত নন, যেহেতু আপনি ফাংশনের মূল অংশের মধ্যে যা করতে / রেফারেন্স করতে পারবেন না।
ডিটিপসন

2
আমি ভুল ছিলাম: নামটি সরাসরি পরিবর্তনযোগ্য না হলেও আপনি এটিকে এটির মতো কনফিগার করতে পারেন: Object.defineProperty (sayHello, 'name', {value: 'sayHello'})
Dtipson

1
"যদি একটি তীর ফাংশন ডান হাতের উপর সংজ্ঞায়িত করা হয় [..]" এটির উত্স কী? আমি অনুমান এটি খুঁজে পাচ্ছি না। শুধু উদ্ধৃতি একটি রেফারেন্স প্রয়োজন।
গজুস

@ ডিটিপসন: এটি কেবলমাত্র এজন্য যে আধুনিক ইঞ্জিনগুলি এখনও nameES2015 স্পেসের যে কোনও জায়গায় সম্পত্তি নির্ধারণের প্রয়োগ করে না; তারা এটি পেতে হবে। এটি ক্রোমের সম্মতি তালিকার শেষ জিনিসগুলির মধ্যে একটি এবং এমনকি ক্রোম 50 তেও নেই (ক্রম 51 শেষ পর্যন্ত হবে)। বিশদ । তবে ওপি বিশেষত এটি (উদ্ভট) করার কথা অস্বীকার করেছে।
টিজে ক্রাউডার

আমি কি টাস্টস্ট্রিং এ এই নাম পেতে পারি? আমি এটিকে ওভাররাইড করার চেষ্টা করেছি, তবে তখন কীভাবে ফাংশন বডিটি অ্যাক্সেস করতে হয় তা আমি জানি না।
কিওয়ার্টি

0

দেখা যাচ্ছে যে এটি ES7 এর মাধ্যমে সম্ভব হবে: https://babeljs.io/blog/2015/06/07/react-on-es6-plus#arrow-function

প্রদত্ত উদাহরণটি হ'ল:

class PostInfo extends React.Component {
  handleOptionsButtonClick = (e) => {
    this.setState({showOptionsModal: true});
  }
}

ES6 তীরের ফাংশনগুলির বডি তাদের চারপাশে থাকা কোডের মতো একই লেকিক্যালকে ভাগ করে দেয়, যা ES7 প্রপার্টি ইনিশিয়েলাইজারদের যেভাবে স্কোপ করা হয় তার কারণে আমাদের কাঙ্ক্ষিত ফলাফল পায়।

নোট করুন যে বাবেলের সাথে এই কাজটি করার জন্য আমার সবচেয়ে পরীক্ষামূলক ES7 পর্যায় 0 সিনট্যাক্স সক্ষম করতে হবে। আমার ওয়েবপ্যাক.কমফিজ.জেএস ফাইলটিতে আমি বাবল লোডারটিকে এর মতো আপডেট করেছি:

{test: /\.js$/, exclude: /node_modules/, loader: 'babel?stage=0'},

6
এটি হ'ল নামযুক্ত তীর ফাংশন নয়। এটি কনস্ট্রাক্টরে উদাহরণ পদ্ধতি তৈরির জন্য একটি শর্টকাট এবং আমি অবাক করে দেখি কীভাবে এটি এখানে প্রাসঙ্গিক?
বার্গি

হাই @ বার্গি, আমি নিশ্চিত নই যে এটি মূল লেখকের উদ্দেশ্য ছিল কিনা তবে আমি বস্তুর মতো এই সুযোগ নিয়ে একটি নামকৃত ফাংশন তৈরি করার চেষ্টা করছিলাম। যদি আমরা এই কৌশলটি ব্যবহার না করি এবং আমরা উপযুক্ত সুযোগ পেতে চাই আমাদের এটি ক্লাস কনস্ট্রাক্টরে বিং করতে হবে। this.handleOptionsButtonClick = this.handleOptionsButtonClick.bind(this);
হামিশ কারি

8
ওহ, আপনি ঠিক তত সহজেই ব্যবহার করতে পারেন constructor() { this.handleOptionsButtonClick = (e) => {…}; }যা আপনার উত্তরের কোডের সম্পূর্ণ সমান তবে ইতিমধ্যে ES6 এ কাজ করে works ব্যবহার করার দরকার নেই .bind
বার্গি

1
বিটিডব্লু, আমি মনে করি আপনি "নামকরণের ফাংশন" "(উদাহরণ) পদ্ধতি" এবং "সুযোগ" দিয়ে " thisপ্রসঙ্গ" দিয়ে বিভ্রান্ত করছেন
বার্গি

1
@ টিডিক্স: হ্যাঁ, আপনি পারেন; জার্গ ভুল হয়েছে। নামকlet a = () => {}; একটি তীর ফাংশন সংজ্ঞায়িত করে । বিশদa
টিজে ক্রাউডার

0

প্রকৃতপক্ষে এটি তীর ফাংশনগুলির নামকরণের এক উপায় (কমপক্ষে ক্রোম 77 ... এর মতো) এর মতো দেখায়:

"use strict";
let fn_names = {};
fn_names.foo = () => { throw new Error(); };
console.log("foo.name is: " + foo.name);
try {
  foo();
} catch (e) {
  console.log(e.stack);
}

এখানে চিত্র বর্ণনা লিখুন


তত্ত্বগতভাবে একটি Babel ম্যাক্রো তৈরী করতে পারে fn('yourName', ()=>{}), যা 100% সঠিক তীর ফাংশন শব্দার্থবিদ্যা এখনো ভাল জন্য "নামে তীর ফাংশন সিনট্যাক্স" একটি Babel প্লাগইন বজায় রাখতে পারে, অথবা: fn yourName() => {}। এর যে কোনওটি উপরের কোডটিতে সংকলন করবে। আমি মনে করি নামযুক্ত তীরগুলি এতটা BADA55 হবে
ডেভিন জি রোড

-1

নামযুক্ত তীর ফাংশনটি লেখার জন্য আপনি নমুনা উদাহরণটি সহকারে করতে পারেন, যেখানে আমার লগইনক্লাস নামে একটি ক্লাস রয়েছে এবং এই শ্রেণীর ভিতরে আমি একটি তীর লিখেছি ফাংশন নামের, successAuth ক্লাস লগইনক্লাস named

    constructor() {

    }

    successAuth = (dataArgs)=> { //named arow function

    }

}

1
আপনি উত্তর হিসাবে পোস্ট করছেন এমন কোডটির একটি ব্যাখ্যা যুক্ত করা সর্বদা ভাল, যাতে এটি দর্শকদের কেন এটি ভাল উত্তর তা বুঝতে সহায়তা করবে।
অ্যারিসোন

এটি ওপি বলেছে যা সে করতে চায় না এটি করে, এবং এই প্রস্তাবের উপর নির্ভর করে যা কেবলমাত্র দ্বিতীয় পর্যায়ে রয়েছে এবং সম্ভবত ES2017 তৈরি করতে যাচ্ছে না (তবে আমি মনে করি এটি সম্ভবত ES2018 তৈরি করবে, এবং ট্রান্সপোর্টাররা এটি সমর্থন করেছে) মাস). এটি কার্যকরভাবে বেশ কয়েকটি পূর্ববর্তী উত্তরগুলিও নকল করে, যা কার্যকর নয়।
টিজে ক্রাউডার

-2

এটি ES6

হ্যাঁ আমি মনে করি আপনি যা করছেন তার পরে এরকম কিছু:

const foo = (depth) => {console.log("hi i'm Adele")}
foo -> // the function itself
foo() -> // "hi i'm Adele"

আমি এই উদাহরণটি চেষ্টা করেছিলাম, এটি ঠিক আছে। নেতিবাচক ভোট দেওয়ার কোনও ভাল কারণ? এই ব্যবহারটি কোনও অযাচিত পার্শ্ব প্রতিক্রিয়া তৈরি করছে বা আমি কোনও গুরুত্বপূর্ণ পয়েন্টটি মিস করছি? আমার সন্দেহ পরিষ্কার করতে আপনার সহায়তা প্রশংসা করা হবে।
ফুলমুন

@ গণেশ আডাপা: আমি আশা করি নিম্নাঞ্চলের লোকেরা কারণ ওপেন যেহেতু বলেছেন যে তিনি / তিনি আর করতে চান না, ঠিক তেমন কাজ করার পরামর্শ দিচ্ছেন, কোনও তথ্য না দিয়ে।
টিজে ক্রোডার

-2

ফাংশন তৈরি করতে আপনি ফাংশন অংশ এবং তীর অংশটি এড়িয়ে যেতে পারেন। উদাহরণ:

 class YourClassNameHere{

   constructor(age) {
     this.age = age;
   }

   foo() {
     return "This is a function with name Foo";
   }

   bar() {
     return "This is a function with name bar";
   }

 }

let myVar = new YourClassNameHere(50);
myVar.foo();
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.