জাভাস্ক্রিপ্ট টার্নারি অপারেটরের সাথে অপারেটরের নজির


116

আমি এই কোডটির প্রথম অংশটি (+ =) টার্নারি অপারেটরের সাথে মিশ্রিত করতে পারি না বলে মনে হচ্ছে।

h.className += h.className ? ' error' : 'error'

আমি মনে করি এই কোডটি যেভাবে কাজ করে তা নিম্নরূপ:

h.className = h.className + h.className ? ' error' : 'error'

তবে এটি সঠিক নয় কারণ এটি আমার কনসোলে একটি ত্রুটি দেয়।

সুতরাং আমার প্রশ্ন হ'ল আমি এই কোডটি কীভাবে সঠিকভাবে ইন্টারপেট করব?

উত্তর:


141
h.className = h.className + (h.className ? ' error' : 'error')

আপনি চান অপারেটরের জন্য কাজ করা h.className, এটি সম্পর্কে আরও সুনির্দিষ্ট করুন।
অবশ্যই, কোনও ক্ষতি থেকে আসা উচিত h.className += ' error'নয়, তবে এটি অন্য বিষয়।

এছাড়াও, নোটের +অপারেটরের চেয়ে অগ্রাধিকার রয়েছে তা নোট করুন : জাভাস্ক্রিপ্ট অপারেটর অগ্রাধিকার


3
আমি মনে করি এটি নোট করা উচিত, যদিও কোনও ক্ষতি হতে পারে না h.className += ' error', এটি স্ট্রিংয়ের শুরুতে একটি ফাঁকা জায়গা ছেড়ে দেয় যদি এটি প্রাথমিকভাবে খালি ছিল। আমি বিশ্বাস করি যে টার্নারি অপারেশনের মূল বিষয়টি পরিষ্কার-পরিচ্ছন্ন স্ট্রিং উত্পাদন করা।
জেএমটাইলার

@ জেএমটাইলার - এটিই আমি ইঙ্গিত করছিলাম - যদি এটি সমস্ত কিছু শুরু থেকে জায়গা রাখার জন্য করা হয় তবে আমার মূল্য হবে না। (প্রান্তের ক্ষেত্রে হুবহু jQuery বা এক্সপাথ নির্বাচনকারী অন্তর্ভুক্ত থাকে)। যাইহোক ধন্যবাদ.
কোবি

অপারেটর অগ্রাধিকার সতর্কতার জন্য @ কোবি +1!
এড চ্যাপেল

129

এই ভাবে চিন্তা করুন:

<variable> = <expression> ? <true clause> : <false clause>

বিবৃতিটি কার্যকর করার পদ্ধতিটি মূলত:

  1. নেই <expression>সত্য নির্ণয় করা, বা মিথ্যাতে মূল্যায়ন করে?
  2. যদি <expression>সত্য হিসাবে মূল্যায়ন করা হয়, তবে এর মান <true clause>নির্ধারিত হয় <variable>, <false clause>অগ্রাহ্য করা হয় এবং পরবর্তী বিবৃতি কার্যকর করা হয়।
  3. যদি <expression>মিথ্যা হিসাবে মূল্যায়ন করা হয়, তবে <true clause>তা উপেক্ষা করা হবে এবং এর মান <false clause>নির্ধারিত হবে <variable>

এটি এবং অন্যান্য ভাষাগুলিতে টার্নারি অপারেটরের সাথে উপলব্ধি করার জন্য গুরুত্বপূর্ণ বিষয়টি হ'ল <expression>মূল্যায়ন করার সময় যে কোনও কোডেই বুলিয়ান ফলাফল উত্থাপন করা উচিত: সত্য বা মিথ্যা।

আপনার উদাহরণের ক্ষেত্রে আমার ব্যাখ্যাতে "অর্পিতকে" প্রতিস্থাপন করুন "যোগ করা", বা আপনি যে কোনও শর্টহ্যান্ড পাটিগণিত ব্যবহার করছেন, যদি কোনওর জন্য একইরকম হয়।


নিখুঁত মন্তব্যটি উপযুক্ত কিনা তা নিশ্চিত করুন :) এটি বাম-হাতের অভিব্যক্তিটি কেন প্রথমে "একত্রিত" হয়েছিল তার কোনও ব্যাখ্যা এড়িয়ে যায় (কারণ +শর্তসাপেক্ষ / ত্রিনিয়ী অপারেটরের চেয়ে বেশি অগ্রাধিকার রয়েছে (আসলে শর্তসাপেক্ষ অপারেটরটি প্রায় সর্বশেষে সর্বশেষে থাকে যে কোনও অভিব্যক্তিতে মূল্যায়ন করা হয়েছে)
কোডিং গেছে

10

+=আপনি যা চান তা, কিন্তু এটি ঈশ্বরের ডানপাশে তিন বিবৃতি, এটা চেক যদি h.className, falsey এটা যদি এটা অনির্দিষ্ট ছিল হবে পারে। যদি এটি সত্যবাদী (যেমন কোনও শ্রেণীর নাম ইতিমধ্যে নির্দিষ্ট করা থাকে), তবে একটি স্থানের সাথে ত্রুটি যুক্ত করা হয় (অর্থাত্ একটি নতুন শ্রেণি যুক্ত করা), অন্যথায় স্থান ছাড়াই এটি যুক্ত হয়।

কোডটি আপনার পরামর্শ অনুসারে আবারও লেখা যেতে পারে, তবে আপনার এটি নির্দিষ্ট করতে হবে যে h.classNameসত্যতা-তুলনার জন্য ব্যবহার করতে হবে, তার প্রকৃত মানটি টার্নারি অপারেটরে ব্যবহার করার পরিবর্তে, তাই নিশ্চিত হয়ে নিন যে আপনি মানগুলির সংমিশ্রণে বিরক্ত করবেন না আপনার ত্রৈমাসিক অপারেশন করার সাথে সাথে:

h.className = h.className + (h.className ? ' error' : 'error');

13
হ্যাঁ, undefinedএটি মিথ্যা নয় এটি ঠিক যেমন আচরণ করা হয়েছিল ঠিক তেমন
ডেভিড হেডলুন্ড

4

=অপারেটরের ডান হাতটি বাম থেকে ডানদিকে মূল্যায়ন করা হয়। সুতরাং,

g.className = h.className + h.className ? ' error' : 'error';`

সমতুল্য

h.className = (h.className + h.className) ? ' error' : 'error';

সমান হতে

h.className += h.className ? ' error' : 'error';

আপনাকে প্রথম বন্ধনীতে তিনটি বিবৃতি আলাদা করতে হবে

h.className = h.className + (h.className ? ' error' : 'error');


1

আমি জানি এটি খুব পুরানো প্রশ্ন, তবে উত্তরগুলি যেহেতু সবগুলি অসম্পূর্ণ বলে মনে হচ্ছে আমি তার সাথে 100% খুশি নই। সুতরাং এখানে আমরা প্রথম প্রিন্সিপাল থেকে আবার যাই:

ব্যবহারকারীর সামগ্রিক লক্ষ্য:

কোডটির সংক্ষিপ্তসার: "আমি স্ট্রিংয়ে ক্লাসের নাম যুক্ত করতে চাই optionচ্ছিকভাবে একটি স্ট্রিংয়ের সাথে একটি নেতৃস্থানীয় স্থানের সাথে যদি ইতিমধ্যে স্ট্রিংয়ে শ্রেণীর নাম থাকে।"error

সহজ সমাধান

কোবি যেমন উল্লেখ করেছেন, ৫ বছর আগে, শ্রেণীর নামগুলির শীর্ষস্থানীয় স্থান থাকা কোনও পরিচিত ব্রাউজারে কোনও সমস্যা সৃষ্টি করবে না, তাই সংক্ষিপ্ত সঠিক সমাধানটি হ'ল:

h.className += ' error';

এটি প্রকৃত সমস্যার আসল উত্তর হওয়া উচিত ছিল ।


তা যেমন হয়, প্রশ্নগুলি হ'ল ...

1) কেন এই কাজ?

h.className += h.className ? ' error' : 'error'

শর্তসাপেক্ষ / ত্রৈমাসিক অপারেটর যদি একটি বিবৃতিটির মতো কাজ করে, যা তার চলকের ফলাফল trueবা falseপাথগুলিকে নির্ধারিত করে ।

সুতরাং কোডটি কাজ করেছে কারণ এটি সহজভাবে মূল্যায়ন করা হয়:

if (h.className IS NOT null AND IS NOT undefined AND IS NOT '') 
    h.className += ' error'
else
    h.className += 'error'

2) এবং কেন এই ব্রেক?

h.className = h.className + h.className ? ' error' : 'error'

প্রশ্নটিতে বলা হয়েছে "যা আমার কনসোলে একটি [এন] ত্রুটি দেয়", যা আপনাকে কোডটি কাজ করে না ভেবে ভুল পথে চালিত করতে পারে । বস্তুত নিম্নলিখিত কোড ছাড়াই চালানো হয়, তাহলে এরর , কিন্তু এটা কেবল আয় 'ত্রুটি' STRING যদি হয় নি খালি এবং 'ত্রুটি' যদি স্ট্রিং ছিল খালি এবং তাই প্রয়োজনীয়তা পূরণ করা হয়নি

এই কোডটি সর্বদা একটি স্ট্রিংয়ের ফলাফল দেয় যা কেবলমাত্র থাকে ' error'বা 'error'কারণ এটি এই সিডো কোডটিতে মূল্যায়ন করে:

if ((h.className + h.className) IS NOT null AND IS NOT undefined AND IS NOT '')
    h.className = ' error'
else
    h.className = 'error'

এর কারণ হ'ল সংযোজন অপারেটরটির ( +সাধারণ লোকের কাছে) শর্তসাপেক্ষে / টের্নারি অপারেটর (15) এর চেয়ে বেশি "অগ্রাধিকার" (6) থাকে। আমি জানি সংখ্যাগুলি পিছনের দিকে প্রদর্শিত হবে

অগ্রাধিকারের সহজ অর্থ হল যে কোনও ভাষার প্রতিটি ধরণের অপারেটর একটি নির্দিষ্ট পূর্বনির্ধারিত ক্রমে (এবং কেবল বাম থেকে ডান নয়) মূল্যায়ন করা হয়।

তথ্যসূত্র: জাভাস্ক্রিপ্ট অপারেটর অগ্রাধিকার

মূল্যায়নের ক্রম কীভাবে পরিবর্তন করবেন:

এখন আমরা জানি এটি কেন ব্যর্থ হয়, কীভাবে এটি কাজ করে তা আপনার জানা দরকার।

আরও কিছু উত্তর অগ্রাধিকার পরিবর্তনের বিষয়ে কথা বলে তবে আপনি তা করতে পারবেন না । প্রাধান্যটি ভাষায় কঠোরভাবে ব্যবহৃত হয়। এটি কেবলমাত্র নিয়মের একটি নির্দিষ্ট সেট ... তবে, আপনি মূল্যায়নের ক্রম পরিবর্তন করতে পারেন ...

আমাদের সরঞ্জামবাক্সের যে সরঞ্জামটি মূল্যায়নের ক্রম পরিবর্তন করতে পারে তা হ'ল গ্রুপিং অপারেটর (ওরফে বন্ধনী)। এটি বন্ধনীগুলির এক্সপ্রেশনগুলি ব্র্যাকেটের বাইরে ক্রিয়াকলাপের আগে মূল্যায়ন করা হয় তা নিশ্চিত করে এটি করে । তারা এগুলিই করে তবে এটি যথেষ্ট।

বন্ধনীগুলি কেবলমাত্র কাজ করে কারণ তাদের (গ্রুপিং অপারেটর) অন্যান্য অপারেটরের তুলনায় উচ্চতর প্রাধান্য রয়েছে ("এখন একটি স্তর 0 রয়েছে")।

কেবল বন্ধনী যুক্ত করে আপনি সাধারণ স্ট্রিং কনটেনটেশনের আগে শর্তসাপেক্ষ পরীক্ষাটি প্রথম সম্পাদিত হয় তা নিশ্চিত করার জন্য মূল্যায়নের ক্রম পরিবর্তন করে :

h.className = h.className + (h.className ? ' error' : 'error')

আমি এখন এই উত্তরটি অন্যদের মধ্যে অদেখা জংয়ের জন্য ছেড়ে দেব :)


1

আমি ওয়েইনের ব্যাখ্যা বেছে নিতে চাই:

<variable> = <expression> ? <true clause> : <false clause>

উভয় ক্ষেত্রে বিবেচনা করা যাক:

case 1:
h.className += h.className ? 'true' : 'false'     
  • অ্যাসাইনমেন্ট অপারেটর সূক্ষ্মভাবে কাজ করে এবং মান সংযোজন হয়
  • যখন প্রথমবারের জন্য চালিত হয়, o / p: মিথ্যা
  • ২ য় বার o / p: মিথ্যা - মানগুলি সংযোজন করে রাখে

কেস 2: এইচ। 'সত্য মিথ্যা'

  • ফলাফল কেস 1 এর মতো নয়
  • যখন প্রথমবারের জন্য চালিত হয়, o / p: মিথ্যা
  • ২ য় বার o / p: মিথ্যা - মানগুলি সংযোজন করে না

explanation

উপরের কোডে, কেস 1 ভাল কাজ করে

যদিও কেস 2:

h.className = h.className + h.className ? 'true' : 'false'
is executed as 
 h.className = (h.className + h.className) ? 'true' : 'false'

h.className + h.className=> টেরিনারি অপারেটরের হিসাবে অভিব্যক্তি হিসাবে বিবেচিত হিসাবে টের্নারি অপারেটরকে উচ্চতর প্রাধান্য দেওয়া হয়। সুতরাং, সর্বদা ত্রৈমাসিক অভিব্যক্তির ফলাফল কেবল নির্ধারিত হয়

বন্ধনী ব্যবহার করে আপনাকে অগ্রাধিকারটি নির্ধারণ করতে হবে

কেস 2 কে কেস 1 হিসাবে কাজ করার জন্য বন্ধনীগুলির সাহায্যে বিবেচনা করার জন্য আপনাকে মূল্যায়নের ক্রমটি সংজ্ঞায়িত করতে হবে

h.className = h.className + (h.className ? ' error' : 'error') 

1
এখানে পরিভাষাটি মোটেই ঠিক নয়। প্রাধান্য ভাষা অন্তর্নিহিত, আপনি এটি সংজ্ঞায়িত করবেন না । আপনি পরিবর্তে বন্ধনী প্রবর্তন করে মূল্যায়নের ক্রমটি সংজ্ঞায়িত করছেন (যা অন্যান্য অপারেটরের তুলনায় উচ্চতর প্রাধান্য পেয়েছে)।
কোডিং হয়ে গেছে

@ ট্র্রু ব্লুউসি আমি এটি গ্রহণ করি। আপনার অভিপ্রায় +1 পড়ার জন্য আমি প্রশংসা করি
অ্যাঞ্জলিন নাদার
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.