কেন 0 [0] সিনথেটিকভাবে বৈধ?


119

এই রেখাটি জাভাস্ক্রিপ্টে বৈধ কেন?

var a = 0[0];

তার পরে, aহয় undefined


4
হিসাবে true[0]বা ""[0]
হ্যাক্কেতো

24
@ কোডএগ্রি ন্যায্য হতে জাভাস্ক্রিপ্ট HTML এর মধ্যেই জন্মগ্রহণ করেছিল এবং এটি এইচটিএমএল থেকেই পুরোপুরি শুরু হয়েছিল "আপনার কাছে আমার পছন্দ মতো কিছু ফেলে দিন এবং আমি এটি উপলব্ধি করার চেষ্টা করব" জিনিসটি।
নাইট দ্য ডার্ক আবসোল

8
@NiettheDarkAbsol ফেয়ার হবে আপনি কেবল ভুল হিসাবে সিনট্যাক্স হয় না জানার (এখনও এত নয়)। এটি কেবল "0"কোনও new Number(0)বস্তুর নাম হিসাবে সম্পত্তি পাচ্ছে ।
meandre

এটি একটি মিথ্যা ধারণা যে একটি সর্বদা সংজ্ঞায়িত হবে। 0[0]কোনও মান ফেরত পাওয়া পুরোপুরি সম্ভব
রুন এফএস

@ ম্যান্ড্রে 0["toString"]এটি দুর্দান্ত, এটি দেখানোর জন্য ধন্যবাদ।
জোনাথন

উত্তর:


169

আপনি যখন করবেন 0[0], জেএস ইন্টারপ্রেটার প্রথমটিকে 0একটি Numberবস্তুতে পরিণত করবে এবং তারপরে [0]সেই বস্তুর সম্পত্তিটি অ্যাক্সেস করার চেষ্টা করবে undefined

কোনও সিনট্যাক্স ত্রুটি নেই কারণ 0[0]এই প্রসঙ্গে ভাষা ব্যাকরণ দ্বারা সম্পত্তি অ্যাক্সেস সিনট্যাক্সের অনুমতি দেওয়া হয়েছে। এই কাঠামো (জাভাস্ক্রিপ্ট ব্যাকরণে পদ ব্যবহার করে) হয় NumericLiteral[NumericLiteral]

ES5 ECMAScript বিশেষের বিভাগ A.3 বিভাগ থেকে ভাষা ব্যাকরণের সম্পর্কিত অংশটি হ'ল:

Literal ::
    NullLiteral
    BooleanLiteral
    NumericLiteral
    StringLiteral
    RegularExpressionLiteral

PrimaryExpression :
    this
    Identifier
    Literal
    ArrayLiteral
    ObjectLiteral
    ( Expression )

MemberExpression :
    PrimaryExpression
    FunctionExpression
    MemberExpression [ Expression ]
    MemberExpression . IdentifierName
    new MemberExpression Arguments    

সুতরাং, কেউ এই অগ্রগতির মাধ্যমে ব্যাকরণ অনুসরণ করতে পারে:

MemberExpression [ Expression ]
PrimaryExpression [ Expression ]
Literal [ Expression ]
NumericLiteral [ Expression ]

এবং, একইভাবে ব্যাকরণ অনুসরণ করার পরে Expressionঅবশেষে NumericLiteralতাই হতে পারে , আমরা দেখতে যে এটি অনুমোদিত:

NumericLiteral [ NumericLiteral ]

যার অর্থ 0[0]এটি ব্যাকরণের একটি অনুমোদিত অংশ এবং সুতরাং কোনও সিনট্যাক্সেরর নেই।


তারপরে, রান-টাইমে আপনাকে এমন একটি সম্পত্তি পড়ার অনুমতি দেওয়া হবে যা অস্তিত্বহীন (এটি কেবল তখনই পড়া হবে undefined) যতক্ষণ না আপনি যে উত্স থেকে পড়ছেন তা কোনও বস্তু বা কোনও অবজেক্টে অন্তর্নিহিত রূপান্তর রয়েছে। এবং, একটি সংখ্যাসূচক আক্ষরিক সত্যই একটি অবজেক্টের (একটি সংখ্যার অবজেক্ট) সাথে অন্তর্নিহিত রূপান্তর রয়েছে।

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

আপনি যখন কোনও আদিম যেমন কোনও বস্তুর মতো সিনট্যাক্স ব্যবহার করেন 0[0], দোভাষী তাকে আদিম কোনও সম্পত্তি অ্যাক্সেস হিসাবে স্বীকৃতি দেয়। এটির প্রতিক্রিয়া হ'ল প্রথম 0সংখ্যাগত আদিম গ্রহণ করা এবং এটিকে বাধ্যতামূলকভাবে একটি পূর্ণ-বিকশিত Numberবস্তুতে পরিণত করা হয় যা এটির পরে [0]সম্পত্তিটি অ্যাক্সেস করতে পারে । এই নির্দিষ্ট ক্ষেত্রে, [0]একটি সংখ্যা অবজেক্টের সম্পত্তি undefinedহ'ল এজন্য আপনার কাছ থেকে পাওয়া মূল্য 0[0]

সম্পত্তি নিয়ে কাজ করার উদ্দেশ্যে কোনও বস্তুর কাছে আদিমকে স্বয়ংক্রিয় রূপান্তর সম্পর্কিত একটি নিবন্ধ এখানে:

জাভাস্ক্রিপ্ট পুরষ্কারের গোপন জীবন


এখানে ECMAScript 5.1 নির্দিষ্টকরণের সম্পর্কিত অংশ রয়েছে:

9.10 চেকঅবজেক্টকোর্সিবল

যদি মান হয় undefinedবা nullঅন্যথায় প্রত্যাবর্তন হয় তবে প্রকারের ত্রুটি ছুড়ে দেয় true

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

11.2.1 সম্পত্তি অ্যাক্সেসর

  1. বেসএরফারেন্সকে মেম্বার এক্সপ্রেসনের মূল্যায়নের ফলাফল হতে দিন।
  2. বেসভ্যালুটি getValue (বেসরাইফারেন্স) হতে দিন।
  3. সম্পত্তির নাম রেফারেন্সটিকে এক্সপ্রেশন মূল্যায়নের ফলাফল হিসাবে দেখা যাক।
  4. প্রোপার্টি নেমভ্যালুটি getValue (সম্পত্তি নাম রেফারেন্স) হতে দিন Let
  5. চেকঅবজেক্টকোসরসিবল (বেসভ্যালু) কল করুন।
  6. প্রোপার্টিনেমস্ট্রিং টুস্ট্রিং (প্রপার্টি নেমভ্যালু) হতে দিন।
  7. যদি সিনট্যাকটিক উত্পাদনের মূল্যায়ন করা হয় তবে যদি তা কঠোর মোড কোডের মধ্যে থাকে তবে কঠোরভাবে সত্য হওয়া উচিত, অন্যথায় কঠোরভাবে মিথ্যা হোক।
  8. টাইপ রেফারেন্সের একটি মান ফেরান যার মূল মানটি বেসভ্যালু এবং যার রেফারেন্সকৃত নাম প্রপার্টি নেমস্ট্রিং, এবং যার কঠোর মোড পতাকাটি কঠোর।

এই প্রশ্নের জন্য অপারেটিভ অংশটি উপরের # 5 ধাপ।

8.7.1 গেটভ্যালু (ভ)

এটি বর্ণনা করে যে কীভাবে যখন অ্যাক্সেস করা মানটি কোনও সম্পত্তি রেফারেন্স হয়, এটি ToObject(base)কোনও আদিমটির অবজেক্ট সংস্করণ পেতে কল করে।

9.9 টোবজেক্ট

এভাবেই বর্ণনা করে Boolean, Numberএবং Stringপ্রিমিটিভের সঙ্গে [[PrimitiveValue]] অভ্যন্তরীণ সম্পত্তি সেট তদনুসারে একটি বস্তু ফর্মে রূপান্তরিত হয়।


একটি আকর্ষণীয় পরীক্ষা হিসাবে, কোডটি যদি এটির মতো হয়:

var x = null;
var a = x[0];

এটি প্রযুক্তিগতভাবে আইনী বাক্য গঠন হিসাবে বিশ্লেষণের সময় এখনও সিন্ট্যাক্সেরর ফেলে দিতে পারে না, আপনি কোডটি চালনার সময় রান টাইমের সময় এটি টাইপআরার নিক্ষেপ করবে কারণ যখন উপরের সম্পত্তি অ্যাকসেসর যুক্তি যুক্ত xহবে তখন এটি কল করবে CheckObjectCoercible(x)বা কল করবে ToObject(x)যা কল করবে উভয় একটি TypeError নিক্ষেপ করা হবে যদি xহয় nullবা undefined


0[1,2]এটিও বৈধ, এর অর্থ কী? (আমি প্রশ্নটি আপডেট করি)
মাইকেল এম।

এবং এটা কারণ কিছু নয় উপর বৈশিষ্ট্য অ্যাক্সেস করার সময়ে, একটি বাক্য গঠন ত্রুটি বাড়াতে না nullবা undefinedসম্পূর্ণভাবে জরিমানা, এমনকি যদি সেই সব সম্পত্তিতে কোন অস্তিত্ব নেই।
user4642212

6
@ মিশেল আপডেট করার দরকার নেই। এটি একটি কমা অপারেটর তাই এটি ঠিক0[2]
অমিত জোকি

1
কমা অপারেটর: 1 এবং 2 উভয়ই মূল্যায়ন করে 1,2তবে 2 ফেরত দেয়
ব্যবহারকারী 4642212

2
এটি একটি প্রশ্নের সার্থকতার জন্য এমন দুর্দান্ত উত্তর।
tbh__

20

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

প্রাসঙ্গিক অংশের ব্যাকরণ জাতীয় হয়

Literal :: 
   NumericLiteral
   ...

PrimaryExpression :
   Literal
   ...

MemberExpression :
   PrimaryExpression
   MemberExpression [ Expression ]
   ...

যেহেতু 0[0]এই নিয়মগুলি মেনে চলে তাই এটি একটি বৈধ অভিব্যক্তি হিসাবে বিবেচিত । এটি সঠিক কিনা (যেমন রান চলাকালীন কোনও ত্রুটি নিক্ষেপ করে না) এটি অন্য গল্প, তবে হ্যাঁ এটি। জেএস এভাবেই মতপ্রকাশের মূল্যায়ন করে someLiteral[someExpression]:

  1. মূল্যায়ন someExpression(যা নির্বিচারে জটিল হতে পারে)
  2. আক্ষরিককে সংশ্লিষ্ট বস্তুর প্রকারে রূপান্তর করুন (সংখ্যার লিটারাল => Number, স্ট্রিং => Stringইত্যাদি)
  3. get propertyসম্পত্তি নামের ফলাফল (1) সহ ফলাফল (2) এ অপারেশন কল করুন
  4. ফলাফল বাতিল (2)

সুতরাং 0[0]হিসাবে ব্যাখ্যা করা হয়

index = 0
temp = Number(0)
result = getproperty(temp, index) // it's undefined, but JS doesn't care
delete temp
return result

এখানে বৈধ , তবে ভুল অভিব্যক্তির উদাহরণ রয়েছে :

null[0]

এটি যথাযথভাবে পার্স করা হয়েছে, তবে রান সময়ে দোভাষী দ্বিতীয় ধাপে ব্যর্থ হয় (কারণ nullকোনও বস্তুকে রূপান্তর করা যায় না) এবং রান টাইম ত্রুটি নিক্ষেপ করে।


1
এর চেয়ে আরও অনেক কিছু আছে। var x = null; var a = x[0];একটি সিনট্যাক্স ত্রুটি উত্পন্ন করে না, তবে রানটাইমের সময় টাইপ এরির ফেলে দেয়।
jਫਰ00

@ জোফ্রেন্ড ২০০: প্রশ্নটি এটাই ছিল না, তবে যুক্ত হয়েছে।
জর্জি 9

ফলাফল অপরিবর্তিত হতে হবে না। 0[0]
অপরিশোধিত

9

এমন পরিস্থিতি রয়েছে যেখানে আপনি জাভাস্ক্রিপ্টে বৈধভাবে একটি নম্বর সাবস্ক্রিপ্ট করতে পারেন:

-> 0['toString']
function toString() { [native code] }

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


@ অমিত জোকি এটি হ'ল (0).toString(ফাংশনটি কল না করে)। এটি সংখ্যার ধরণের সম্পত্তি।
ব্যবহারকারী4642212

@ অমিতজোকি কারণ এটি 'এই লাইনটি বৈধ কেন' এমন প্রশ্নের উত্তর দেয়।
ডানকান

@ ডানকান তবে এটি "কি বন্ধনী চিহ্নিতকরণ" এর চেয়ে বেশি এবং আমি মনে করি ওপি এটি জানে। এটিকে সংখ্যার অবজেক্ট হিসাবে ব্যাখ্যা করা হয় এবং তারপরে তার 0সম্পত্তিটি অ্যাক্সেস করা হয় এবং যেহেতু এটি বিদ্যমান না তাই jender00 তে বর্ণিত হিসাবে undefinedএটি আরও সঠিক।
অমিত জোকি

@ অমিত জোকি এটি একটি ভুল অনুমান যা 0[0]অনির্ধারিত ফিরে আসবে। সম্ভবত এটি এটি হবে তবে এটি হওয়ার দরকার নেই
রুন এফএস

9

আমি কেবল এটি লক্ষ করতে চাই যে এটি বৈধ সিনট্যাক্স জাভাস্ক্রিপ্টের জন্য কোনওভাবেই অনন্য নয়। বেশিরভাগ ভাষায় একটি রানটাইম ত্রুটি বা কোনও ধরণের ত্রুটি থাকবে তবে এটি সিনট্যাক্স ত্রুটির মতো নয়। জাভাস্ক্রিপ্ট এমন অনেক পরিস্থিতিতে অপরিজ্ঞাত ফিরিয়ে নেওয়ার পছন্দ করে যেখানে অন্য কোনও ভাষা ব্যতিক্রম বাড়াতে পারে যার মধ্যে প্রদত্ত নামের সম্পত্তি নেই এমন কোনও বিষয় সাবস্ক্রিপশন করার সময় অন্তর্ভুক্ত রয়েছে।

সিনট্যাক্সটি কোনও এক্সপ্রেশনের ধরণ (সংখ্যার আক্ষরিকের মতো একটি সাধারণ অভিব্যক্তি) জানে না এবং আপনাকে কোনও অভিব্যক্তিতে কোনও অপারেটর প্রয়োগ করার অনুমতি দেবে। উদাহরণস্বরূপ, সাবস্ক্রিপ্ট চেষ্টা করা undefinedবা জাভাস্ক্রিপ্টে nullএকটি কারণ ঘটায় TypeError। এটি কোনও সিনট্যাক্স ত্রুটি নয় - যদি এটি কখনও সম্পাদন না করা হয় (যদি একটি আইফোন-বিবৃতিটির ভুল দিকের দিকে থাকে) তবে এটি কোনও সমস্যা সৃষ্টি করবে না, যদিও একটি বাক্য গঠন ত্রুটি সর্বদা সংকলনের সময় ধরা পড়ে (ইওল, ফাংশন ইত্যাদি) definition , সমস্ত সংকলন হিসাবে গণনা)।


8

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


3

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

0[0] = 1;

যা একটি বৈধ অ্যাসাইনমেন্ট এক্সপ্রেশন যা 1 প্রদান করে কিন্তু আসলে কিছুই বরাদ্দ করে না, অঙ্কটি 0স্থায়ী নয়। যা নিজেই কিছুটা বিজোড়। আপনার কাছে একটি বৈধ এবং সঠিক (এক্সিকিউটেবল) অ্যাসিংমেন্ট এক্সপ্রেশন থাকতে পারে, এটি কোনও কিছুই বরাদ্দ করে না (*)। তবে সংখ্যার ধরণটি একটি পরিবর্তনীয় বস্তু যাতে আপনি প্রকারটি পরিবর্তন করতে পারেন, এবং পরিবর্তনগুলি প্রোটোটাইপ শৃঙ্খলে ক্যাসকেড করবে।

Number[0] = 1;
//print 1 to the console
console.log(0[0]);
//will also print 1 to the console because all integers have the same type
console.log(1[0]); 

অবশ্যই এটি বুদ্ধিমান ব্যবহারের বিভাগ থেকে অনেক দূরের কান্নাকাটি তবে ভাষাটির জন্য এটি নির্দিষ্ট করার জন্য নির্দিষ্ট করা হয়েছে কারণ অন্য পরিস্থিতিতে, অবজেক্টের সক্ষমতা বাড়ানো আসলে অনেকটা অর্থবোধ করে। উদাহরণস্বরূপ জানাতে jQuery প্লাগইনগুলি কীভাবে jQuery অবজেক্টে প্রবেশ করে।

(*) এটি আসলে কোনও বস্তুর সম্পত্তির জন্য মান 1 নির্ধারণ করে, তবে আপনি যে (ট্রান্সক্র্যান্ট) অবজেক্টটি উল্লেখ করতে পারেন তার কোনও উপায় নেই এবং এটি নেক্সেক্স জিসি পাসে সংগ্রহ করা হবে


3

জাভাস্ক্রিপ্টে, সমস্ত বস্তু হয়, সুতরাং দোভাষী যখন এটি বিশ্লেষণ করেন তখন এটি 0 টিকে একটি বস্তু হিসাবে বিবেচনা করে এবং 0টিকে একটি সম্পত্তি হিসাবে ফেরত দেওয়ার চেষ্টা করে। আপনি সত্য বা "" খালি স্ট্রিংয়ের 0 তম উপাদান অ্যাক্সেস করার চেষ্টা করার সময় একই জিনিস ঘটে থাকে।

এমনকি যদি আপনি 0 [0] = 1 সেট করে থাকেন তবে এটি সম্পত্তি এবং এর মানটিকে মেমোরিতে সেট করবে, তবে আপনি 0 এ অ্যাক্সেস করার সময় এটি একটি সংখ্যা হিসাবে গণ্য হবে (এখানে অবজেক্ট এবং সংখ্যা হিসাবে আচরণের মধ্যে বিভ্রান্ত হবেন না))

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