ES6 তত্ক্ষণাত তীর ফাংশন চাওয়া


149

কেন এটি Node.jsকনসোলে কাজ করে (4.1.1 এবং 5.3.0 এ পরীক্ষিত) কিন্তু ব্রাউজারে কাজ করে না (ক্রোমে পরীক্ষিত)? এই কোড ব্লকটি এমন একটি বেনামি ফাংশন তৈরি এবং লগ করা উচিত যা লগ করে Ok

() => {
  console.log('Ok');
}()

উপরোক্তগুলি নোডে কাজ করার সময় এটি কার্যকর হয় না:

n => {
  console.log('Ok');
}()

না এটি:

(n) => {
  console.log('Ok');
}()

মজার বিষয়টি হল প্যারামিটারটি যুক্ত করা হলে এটি SyntaxErrorতাত্ক্ষণিকভাবে অনুরোধকারী অংশে ছুড়ে দেয় ।


8
ভাল প্রশ্ন. উভয় প্যারামিটারাইজড সংস্করণগুলি ব্যাবেল
কোডিংইন্ট্রিগ

2
আগ্রহের বাইরে, (n => { console.log("Ok"); })();কাজ করে?
কোডিংইন্ট্রিগ

হ্যাঁ (n => { console.log("Ok"); })()এমনকি ক্রোম দেব
কনসোলেও

এবং তাই, 3 বছর পরে, উত্তর? অবশ্যই নীচের 3 টির মধ্যে একটি উত্তর গ্রহণ করা উচিত ?!
joedotnot

@ জোয়েডোটনোট আমি একটি পরিষ্কার উত্তর পাইনি, বেশিরভাগ ক্ষেত্রে এটি নোড.জেএস-এ একটি অদ্ভুত বাস্তবায়ন ছিল mostly দেখে মনে হচ্ছে সর্বশেষ সংস্করণে Node.jsপ্রথম সংস্করণটি আর কাজ করছে না।
এক্সসিএস 14

উত্তর:


194

আপনাকে এটিকে ফাংশন সংজ্ঞার পরিবর্তে একটি ফাংশন এক্সপ্রেশন তৈরি করতে হবে যা নামের প্রয়োজন নেই এবং এটি একটি বৈধ জাভাস্ক্রিপ্ট তৈরি করে।

(() => {
  console.log('Ok');
})()

আইআইএফই এর সমতুল্য

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

এবং কেন এটি নোড.জেজে কাজ করে তবে ক্রোমে নয় এমন সম্ভাব্য কারণ এটির পার্সার এটিকে একটি স্ব সম্পাদনকারী কার্য হিসাবে ব্যাখ্যা করে কারণ

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

Node.jsএটিতে একটি সূক্ষ্ম কাজ করে এটি একটি ফাংশন এক্সপ্রেশন এবং ক্রোম এবং ফায়ারফক্স এবং ব্রাউজারের বেশিরভাগই এটি এভাবে ব্যাখ্যা করে। আপনার এটি ম্যানুয়ালি প্রার্থনা করা প্রয়োজন।

পার্সারকে কোনও ফাংশন এক্সপ্রেশন আশা করতে বলার সর্বাধিক স্বীকৃত উপায় হ'ল এটি প্যারেন্সে আবৃত করা, কারণ জাভাস্ক্রিপ্টে পেরেন বিবৃতি ধারণ করতে পারে না। এই মুহুর্তে, যখন পার্সার ফাংশন কীওয়ার্ডটির মুখোমুখি হয়, তখন এটি কোনও ফাংশন ঘোষণার পরিবর্তে এটি একটি ফাংশন এক্সপ্রেশন হিসাবে পার্স করতে জানে।

সংক্রান্ত parametrized সংস্করণ , এই কাজ করবে।

((n) => {
  console.log('Ok');
})()

4
প্রথম উদাহরণটি কাজ করে Node.jsএবং প্রকৃতপক্ষে মানটি লগ করে। আমার প্রশ্ন কেন এটি কাজ করে? আমি কেন প্যারামিটারটি যুক্ত করব না কেন?
এক্সসিএস

1
আমি IIFEএর সাথে বেশ পরিচিত এবং আমার কোড ঠিক করতে জানি। আমি কেবল কৌতূহল ছিলাম কেন, উদাহরণস্বরূপ, পরামিতিটি যুক্ত IIFEনা nহওয়াতে প্যারামিটার যুক্ত হওয়ার পরে আমার কাজ হয় না ।
এক্সসিএস 11

3
আমি ডাউনভিট করি নি, তবে প্রশ্নটি হল কেন প্যারামিটারযুক্ত সংস্করণ নোডে কাজ করে না যখন প্যারামিটার ছাড়াই হুবহু একই সংজ্ঞা হয় - এটি বেনামে ফাংশনগুলির নোড / ক্রোম বাস্তবায়নের মধ্যে পার্থক্য জিজ্ঞাসা করছে না
কোডিংট্রিট্রিগ

1
এটি একটি ভাল-জানা কিন্তু এটি প্রশ্নের উত্তর দেয় না, যেমনটি আগেই বলা হয়েছে - প্যারামিটার ছাড়া ঠিক একই সংজ্ঞা যখন দেয় তখন প্যারামিটারাইজড সংস্করণ
নোডে

তবে function(){}()তীর ফাংশনগুলির সমতুল্য কী ? যদি আমি চাই তবে ফাংশন অবজেক্টটি এক্সপোজড ফাংশন এক্সপ্রেশনগুলি এর বিরুদ্ধে সুরক্ষা দেয়।
দাদাবাবা

18

এগুলির কোনওটিরই প্রথম বন্ধনী ছাড়া কাজ করা উচিত।

কেন?

কারণ অনুমান অনুযায়ী:

  1. ArrowFunction হয় অধীন তালিকাভুক্ত AssignmentExpression
  2. একটি এর LHS CallExpression একটি হওয়া আবশ্যক MemberExpression , SuperCall বা CallExpression

সুতরাং একটি ArrowFunction একটি এর LHS উপর হতে পারে না CallExpression


এই কার্যকরভাবে কিভাবে মানে =>, ব্যাখ্যা করা উচিত যে এটা নিয়োগ অপারেটার যেমন স্তর একই সাজানোর কাজ করে =, +=ইত্যাদি

অর্থ

  • x => {foo}() হয়ে যায় না(x => {foo})()
  • দোভাষী তার ব্যাখ্যা করার চেষ্টা করেন x => ({foo}())
  • সুতরাং এটি এখনও একটি সিনট্যাক্স এরর
  • সুতরাং দোভাষী অনুবাদক স্থির করেন যে (অবশ্যই ভুল হয়েছে এবং একটি সিনট্যাক্স এরর ফেলেছে

এটি সম্পর্কে এখানেও বাবেলের একটি বাগ ছিল ।


সেগুলি কিছু বৈধ পয়েন্ট, তবে আমি যদি প্রথমটি, কার্যক্ষম সংস্করণটি প্রতিস্থাপনের চেষ্টা করি তবে এর সাথে: () => ({console.log('Ok')}())এটি আর কাজ করে না। সুতরাং এটি সত্যিই এটি ব্যাখ্যা করে না।
এক্সসিএস 11

@ ক্রিসি এটি একটি বৈধ তীর ফাংশন উত্পাদন নয়। এটি মনে করে যে আপনি অবজেক্ট আক্ষরিক (প্রথম বন্ধনী দ্বারা আবদ্ধ) দিয়ে একটি অবজেক্ট তৈরি করার চেষ্টা করছেন এবং console.log(...)এটি কোনও বৈধ কী নাম নয়।
thefourtheye

@ ক্রিস্টি: হ্যাঁ, আমি মনে করি উপরের বর্ণনার অংশটি ("অর্থ" বিট) খুব সঠিক নাও হতে পারে, তবে স্পেসিফিকেশন অংশগুলি যতদূর আমি বলতে পারি are : এটা এছাড়াও ত্রুটি যা আমি V8 থেকে পেতে ফিট SyntaxError: Unexpected token ((নির্দেশ (মধ্যে ()শেষে না (মধ্যে console.log(...))।
টিজে ক্রাউডার

@ টিজে ক্রাউডার আপনি ঠিক বলেছেন, ত্রুটি বার্তাকে পরিবর্তন করার সাথে সাথে আমি যা বলার চেষ্টা করছি তা জানানো হয়নি (অর্থাত্ (কোনও বৈধ ব্যাখ্যার সন্ধান করার জন্য ক্লান্তিকর চেষ্টা করার পরে দোভাষীর ত্যাগ করতে হবে এবং যায়) "এটি অবশ্যই ভুল হতে হবে"), যা যাইহোক ভুল হতে পারে কারণ দোভাষী কীভাবে লেখা হয় তা আমি জানি না
পল এস।

আমি ভাবছি যদি এটি এই অবস্থানটিতে একটি বৈধ টোকেন না হয়, এটি একটি অর্ধ কোলন toোকানোর চেষ্টা করবে না?
thefourtheye

2

আপনি যে কারণে সমস্যাগুলি দেখছেন তা হ'ল কনসোল নিজেই বর্তমানে আপনি যে প্রসঙ্গটি লক্ষ্য করছেন তার বৈশ্বিক সুযোগ অনুকরণ করার চেষ্টা করে। এটি কনসোলে আপনার লেখা বিবৃতি এবং প্রকাশগুলি থেকে ফিরতি মানগুলি ক্যাপচার করার চেষ্টা করে, যাতে ফলাফল হিসাবে প্রদর্শিত হয় the যেমন ধরুন:

> 3 + 2
< 5

এখানে, এটি কার্যকর করে যেমন এটি প্রকাশ করে তবে আপনি এটি লিখেছেন যেন এটি একটি বিবৃতি। সাধারণ স্ক্রিপ্টগুলিতে, মানটি ফেলে দেওয়া হবে, তবে এখানে কোডটি অভ্যন্তরীণভাবে ম্যাঙ্গেল করা উচিত (যেমন কোনও ফাংশন প্রসঙ্গে এবং পুরো স্টেটমেন্টটি মোড়ানোর মতো)return বিবৃতি ), যা আপনি যে সমস্যার সম্মুখীন হচ্ছেন সেগুলি সহ সকল প্রকারের অদ্ভুত প্রভাবের কারণ হয়।

স্ক্রিপ্টগুলিতে কিছু খালি ES6 কোড ঠিকঠাকভাবে কাজ করে তবে Chrome Dev সরঞ্জামগুলি কনসোলটিতে না রাখার একটি কারণও এটি।

নোড এবং ক্রোম কনসোলে এটি কার্যকর করার চেষ্টা করুন:

{ let a = 3 }

নোড বা একটি <script>ট্যাগে এটি ঠিক কাজ করে তবে কনসোলে এটি দেয় Uncaught SyntaxError: Unexpected identifier। এটি আপনাকে সেই সূত্রের লিঙ্ক দেয় VMxxx:1যা আকারে আপনি মূল্যায়িত উত্সটি পরিদর্শন করতে ক্লিক করতে পারেন, যা এটি প্রদর্শিত হবে:

({ let a = 3 })

তাহলে কেন এটি এমন করল?

উত্তরটি হ'ল এটির জন্য আপনার কোডটি একটি অভিব্যক্তিতে রূপান্তর করা দরকার যাতে ফলাফলটি কলারে ফিরে আসে এবং কনসোলে প্রদর্শিত হয়। আপনি এটি বন্ধনীতে বিবৃতি মোড়ানো দ্বারা এটি করতে পারেন, এটি এটিকে একটি অভিব্যক্তি হিসাবে চিহ্নিত করে, তবে এটি উপরের ব্লকটিকে সিন্টেক্সিকভাবেও ভুল করে তোলে (এক্সপ্রেশনটির কোনও ব্লক ঘোষণা থাকতে পারে না)।

কনসোল কোড সম্পর্কে স্মার্ট হয়ে এই প্রান্তের কেসগুলি ঠিক করার চেষ্টা করে, তবে এটি এই উত্তরটির বাইরে নয়, আমি মনে করি। তারা ঠিক করার বিষয়টি বিবেচনা করছে এমন কিছু কিনা তা দেখতে আপনি একটি বাগ ফাইল করতে পারেন।

খুব অনুরূপ কিছু এর একটি ভাল উদাহরণ এখানে:

https://stackoverflow.com/a/28431346/46588

আপনার কোডের কাজটি করার নিরাপদতম উপায় হল এটি একটি এক্সপ্রেশন হিসাবে চালানো যেতে পারে তা নিশ্চিত করা এবং এটির পরীক্ষা করা SyntaxError আসল এক্সিকিউশন কোডটি কী তা দেখার জন্য উত্সের লিঙ্কটি করা এবং সেখান থেকে কোনও সমাধান বিপরীত প্রকৌশলী। সাধারণত এর অর্থ কৌশলগতভাবে স্থাপন করা প্রথম বন্ধনী।

সংক্ষেপে: কনসোলটি যথাসম্ভব যথাযথভাবে গ্লোবাল এক্সিকিউশন প্রসঙ্গে অনুকরণ করার চেষ্টা করে, তবে ভি 8 ইঞ্জিন এবং জাভাস্ক্রিপ্ট শব্দার্থবিজ্ঞানের সাথে মিথস্ক্রিয়া সীমাবদ্ধতার কারণে এটি কখনও কখনও সমাধান করা শক্ত বা অসম্ভব।


1
এটি পুরো বিষয়টি, আমি প্যারামিটারটি যত্ন করি, তবে এটি পরামিতি সেটটি দিয়ে কাজ করে না।
এক্সসিএস

ঠিক আছে, আমি আপনার পয়েন্ট দেখুন। পার্থক্যটি হ'ল Chrome ডে সরঞ্জাম কনসোলটি আসলে আপনার কোডটি কার্যকর করে। আমি এর প্রতিফলন করতে উত্তর সম্পাদনা করব।
ক্লিমেন স্লাভিč

0

আমি এই জাতীয় একটি প্রশ্ন জিজ্ঞাসা:

@ জেনে নিন আমি এই প্রশ্নটি করেছি: একটি # আইআইএফই প্যাটার্ন উত্পাদন করতে আমরা কোনও ফাংশন ঘোষণার চারপাশে পরান ব্যবহার করি এটি একটি ফাংশন এক্সপ্রেশনে রূপান্তরিত করার জন্য এবং তারপরে অনুরোধ করব। এখন তীর ফাংশন IIFE- এ, আমাদের কেন পরান দরকার?! তীর ফাংশনটি কি ইতিমধ্যে ডিফল্টরূপে একটি অভিব্যক্তি নয় ?!

এবং এটি কাইল সিম্পসনের উত্তর:

একটি তীর ফাংশন হয় একটি expr, কিন্তু আমরা পার্শ্ববর্তী ডান বন্ধনী বি / সি "অপারেটর প্রাধান্য" (sorta) এর প্রয়োজন, তাই চূড়ান্ত ডান বন্ধনী তীর-IIFE সমগ্র ফাংশন প্রযোজ্য ডাকা এবং তার শরীরের মাত্র গত টোকেন না যে ।

x => console.log(x)(4)

বনাম

(x => console.log(x))(4)

- গেটিফাই (@ গেটিফাই) জুন 12, 2020


আমার প্রশ্ন ছিল কেন এটি কিছু সংকলকগুলিতে কাজ করেছে এবং অন্যের জন্য নয়।
এক্সসিএস

এর কারণ বিভিন্ন সংকলক কিছু বিশদে আলাদা আলাদা আচরণ করে যেমন বিভিন্ন ব্রাউজার, অবশ্যই আলাদা আলাদা সংকলক রয়েছে
এরশাদ কাদেরী

আপনি ঠিক বলেছেন, তারা অন্যরকম আচরণ করে তবে জাভাস্ক্রিপ্টের চশমাগুলি তাদের সবার জন্য একই। আমি কৌতূহলী ছিলাম কোনটি সঠিক, জেএস স্পেক এই মামলা সম্পর্কে কী বলে এবং বিশেষত কীভাবে এটি হতে পারে যে এটি যুক্তি ছাড়াই কাজ করে তবে যুক্তি দিয়ে নয়। আমি আরও প্রযুক্তিগত প্রতিক্রিয়া খুঁজছিলাম।
এক্সসিএস

আপনার উদাহরণটি বেশ সুস্পষ্ট, প্রথম ক্ষেত্রে এটি কল করা উচিত console.log(x)(4)
এক্সসিএস

আমি এখানে অনুমান করছি তবে আমি মনে করি এটি এর মতো ব্যাখ্যা করা খুব যুক্তিসঙ্গত: তীর ফাংশন এক্সপ্রেশনগুলিতে যখন আমরা কোনও প্যারামিটার ব্যবহার করি না তখন অবশ্যই প্যারেন ব্যবহার করা উচিত এবং এটি ইঞ্জিনের জন্য খুব স্পষ্ট করে তোলে যে এটি একটি তীর ফাংশন এক্সপ্রেশন, কিন্তু যখন আমাদের একটি প্যারামিটার থাকে প্যারেনগুলি স্বেচ্ছাচারিত হয় যা সম্ভবত এটি পরিষ্কার নয় যে এটি একটি ফাংশন এবং সেই ইঞ্জিনকে বিভ্রান্ত করে তোলে, সেই বিভ্রান্তি সমাধানের জন্য আমাদের পুরো ফাংশন এক্সপ্রেশনটির চারপাশে পেরেনগুলির একটি জুড়ি রাখতে হবে
এরশাদ কাদেরী
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.