জাভাস্ক্রিপ্ট >>> অপারেটর কী এবং আপনি কীভাবে এটি ব্যবহার করবেন?


150

আমি মজিলা থেকে কোডটি খুঁজছিলাম যা অ্যারেতে একটি ফিল্টার পদ্ধতি যুক্ত করে এবং এতে কোডের একটি লাইন ছিল যা আমাকে বিভ্রান্ত করেছিল।

var len = this.length >>> 0;

আমি >>> এর আগে জাভাস্ক্রিপ্টে কখনও দেখিনি।
এটা কি এবং এটা কি কাজ করে?


@ সিএমএস সত্য, এই কোড / প্রশ্নটি তাদের থেকে আসে; তবে, এখানে প্রতিক্রিয়া আগের তুলনায় আরও নির্দিষ্ট এবং মূল্যবান।
জাস্টিন জনসন

2
অথবা এটি কোনও বাগ বা মজিলা ছেলেরা ধরে নিচ্ছে যে এটির দৈর্ঘ্য -1 হতে পারে। >>> স্বাক্ষরবিহীন শিফট অপারেটর তাই ভের লেন সবসময় 0 বা তত বেশি হয়।
ব্যবহারকারী 347594

1
অ্যাশ সেরেল এর জন্য একটি ব্যবহার খুঁজে পেয়েছিল - জেএসের অধিপতি ( ডগ ক্রকফোর্ড) এর প্রয়োগকে Array.prototype.push/ Array.prototype.pop- hexmen.com/blog/2006/12/push-and-pop (যদিও তিনি পরীক্ষা করেছিলেন, হাহা) এর উপর উল্টে দিয়েছিলেন ।
ড্যান বিম

উত্তর:


211

এটি কেবল নন-সংখ্যাগুলিকে সংখ্যায় রূপান্তরিত করে না, এটি তাদের এমন নম্বরগুলিতে রূপান্তর করে যা 32-বিট স্বাক্ষরযুক্ত ইনট হিসাবে প্রকাশ করা যেতে পারে।

যদিও জাভাস্ক্রিপ্ট এর নাম্বার ডাবল স্পষ্টতা ভাসে (*), bitwise অপারেটরদের হয় ( <<, >>, &, |এবং ~) 32-বিট ইন্টিজার উপর অপারেশন পদ সংজ্ঞায়িত করা হয়। কিছুটা অপারেশন করা এই সংখ্যাটি 32-বিট স্বাক্ষরিত ইনটকে রূপান্তরিত করে, 32 টির চেয়ে কোনও ভগ্নাংশ এবং উচ্চ-স্থান বিট হারিয়ে, গণনা করার আগে এবং পরে সংখ্যায় ফিরে রূপান্তরিত করে।

সুতরাং 0 বিটের ডানদিকের শিফ্টের মতো কোনও প্রকৃত প্রভাব ছাড়াই বিটওয়াস অপারেশন করা কোনও >>0সংখ্যাকে গোল করা এবং এটি 32-বিট ইনট রেঞ্জে রয়েছে তা নিশ্চিত করার একটি দ্রুত উপায়। তদ্ব্যতীত, ট্রিপল >>>অপারেটর, স্বাক্ষরবিহীন অপারেশন করার পরে, তার গণনার ফলাফলগুলি অন্যদের স্বাক্ষরিত পূর্ণসংখ্যার চেয়ে স্বাক্ষরিত পূর্ণসংখ্যার হিসাবে রূপান্তর করে, সুতরাং এটি 32-বিট-টু-পরিপূরককে নেতিবাচক রূপান্তর করতে ব্যবহার করা যেতে পারে একটি বড় সংখ্যা হিসাবে সংস্করণ। >>>0ব্যবহারটি নিশ্চিত করে যে আপনি 0 এবং 0xFFFFFFFF এর মধ্যে একটি পূর্ণসংখ্যা পেয়েছেন।

এই ক্ষেত্রে এটি দরকারী কারণ ECMAScript 32 বিট স্বাক্ষরযুক্ত ইনটগুলির ক্ষেত্রে অ্যারে সূচকগুলি সংজ্ঞায়িত করে। সুতরাং আপনি যদি এমনভাবে বাস্তবায়ন করার চেষ্টা করছেন array.filterযা ইসমাস্ক্রিপ্ট পঞ্চম সংস্করণের মান যা বলে ঠিক হুবহু ডুপ্লিকেট করে, আপনি এই সংখ্যাটি 32-বিট স্বাক্ষরযুক্ত ইন্টিতে নিক্ষেপ করবেন।

(বাস্তবে এই জন্য সামান্য ব্যবহারিক প্রয়োজন আশা মানুষ সেটিং করা যাচ্ছে না যেমন array.lengthকরতে 0.5, -1, 1e21বা 'LEMONS'। কিন্তু এই জাভাস্ক্রিপ্ট লেখক আমরা যে বিষয়ে কথা বলছি তাই আপনি জানেন না হয়, ...)

সারসংক্ষেপ:

1>>>0            === 1
-1>>>0           === 0xFFFFFFFF          -1>>0    === -1
1.7>>>0          === 1
0x100000002>>>0  === 2
1e21>>>0         === 0xDEA00000          1e21>>0  === -0x21600000
Infinity>>>0     === 0
NaN>>>0          === 0
null>>>0         === 0
'1'>>>0          === 1
'x'>>>0          === 0
Object>>>0       === 0

* উপকারিতা.)


2
গভীরতার বর্ণনা এবং সারণিতে +2, -1 কারণ অ্যারে. দৈর্ঘ্য নিজেকে বৈধ করে এবং নির্বিচারে এমন কোনও কিছুতে সেট করা যায় না যা কোনও পূর্ণসংখ্যা বা 0 নয় (এফএফ এই ত্রুটিটি ছুড়ে ফেলে RangeError: invalid array length:)।
জাস্টিন জনসন

4
যাইহোক, ধারণাটি ইচ্ছাকৃতভাবে অনেক অ্যারে ফাংশনকে অ-অ্যারেতে (যেমন। মাধ্যমে Array.prototype.filter.call) কল করার অনুমতি দেয়, তাই এটি arrayআসলে বাস্তব হতে পারে না Array: এটি অন্য কোনও ব্যবহারকারী-সংজ্ঞায়িত শ্রেণি হতে পারে। (দুর্ভাগ্যবশত, এটা না নির্ভরযোগ্যভাবে একটি NodeList, যা যখন আপনি সত্যিই যে কাজ করতে চান চাই যে একটি হোস্ট বস্তু আছে যেতে পারে যে পাতার একমাত্র জায়গা আপনি বাস্তবানুগভাবে যে করতে চাই। argumentsসিউডো-এরে।)
bobince

দুর্দান্ত ব্যাখ্যা এবং দুর্দান্ত উদাহরণ! দুর্ভাগ্যক্রমে এটি জাভাস্ক্রিপ্টের আর একটি উন্মাদ দিক। আমি ভুল বুঝতে পারি না আপনি যখন ভুল টাইপটি পান তখন একটি ত্রুটি নিক্ষেপ করার মধ্যে এত ভয়ঙ্কর কি। প্রতিটি দুর্ঘটনাজনিত ভুলকে টাইপ কাস্টিং তৈরি না করে গতিশীল টাইপিংয়ের অনুমতি দেওয়া সম্ভব। :(
মাইক উইলিয়ামসন

">>> ব্যবহার করে আপনি 0 এবং 0xFFFFFFFF এর মধ্যে একটি পূর্ণসংখ্যা পেয়েছেন তা নিশ্চিত করে" " ifমূল্যায়নের বাম দিকটি কোন অন্তর্নিহিত ছিল না তা সনাক্ত করার চেষ্টা করার সময় বিবৃতিটি এর জন্য কেমন হবে ? 'lemons'>>>0 === 0 && 0 >>>0 === 0সত্য হিসাবে মূল্যায়ন? যদিও লেবু স্পষ্টতই একটি শব্দ ..?
জেজ ২

58

স্বাক্ষরবিহীন রাইট শিফট অপারেটরটি মজিলার সমস্ত অ্যারে অতিরিক্ত পদ্ধতি প্রয়োগে ব্যবহৃত হয় , যাতে lengthসম্পত্তিটি স্বাক্ষরযুক্ত 32-বিট পূর্ণসংখ্যার হয় তা নিশ্চিত করতে ।

lengthঅ্যারে বস্তুর সম্পত্তি বর্ণিত হিসাবে স্পেসিফিকেশন দেখুন:

প্রতিটি অ্যারে অবজেক্টের দৈর্ঘ্যের সম্পত্তি থাকে যার মান সর্বদা 2 32 এর চেয়ে কম সংখ্যক পূর্ণসংখ্যা হয় ।

এই অপারেটরটি এটি অর্জনের সবচেয়ে সংক্ষিপ্ততম উপায়, অভ্যন্তরীণভাবে অ্যারে পদ্ধতিগুলি ToUint32অপারেশনটি ব্যবহার করে তবে সেই পদ্ধতিটি অ্যাক্সেসযোগ্য নয় এবং বাস্তবায়নের উদ্দেশ্যে নির্দিষ্টকরণে বিদ্যমান।

মজিলা অ্যারের অতিরিক্ত প্রয়োগগুলি ECMAScript 5 এর সাথে অনুগত হওয়ার চেষ্টা করুন , Array.prototype.indexOfপদ্ধতির বিবরণটি দেখুন (§ 15.4.4.14):

1. এই মানটি পাস করার ক্ষেত্রে টোবজেক্টকে কল করার ফলাফল হ'ল ও O 
   যুক্তি হিসাবে
২. লেনভ্যালু ও এর অভ্যন্তরীণ পদ্ধতির সাথে [[পান]] কল করার ফলাফল হোক 
   "দৈর্ঘ্য" যুক্তি।
3. লেনটি ToUint32 (লেনভ্যালু) হতে দিন ।
....

আপনি দেখতে পাচ্ছেন যে, তারা কেবল ToUint32কোনও ES3 বাস্তবায়নের বিষয়ে ES5 নির্দিষ্ট মেনে চলার পদ্ধতির আচরণটি পুনরুত্পাদন করতে চায় এবং আমি আগেই বলেছি, স্বাক্ষরবিহীন ডান শিফট অপারেটর সবচেয়ে সহজ উপায়।


লিঙ্কযুক্ত অ্যারের অতিরিক্ত প্রয়োগগুলি সঠিক হতে পারে (বা সঠিকের কাছাকাছি) কোডটি এখনও একটি খারাপ কোডের উদাহরণ। উদ্দেশ্য সম্পর্কে স্পষ্ট করার জন্য একটি মন্তব্যও এই পরিস্থিতির সমাধান করবে।
fmark

2
এটা কি সম্ভব যে একটি অ্যারের দৈর্ঘ্য হল না একটি পূর্ণসংখ্যা? আমি এটি কল্পনা করতে পারি না, সুতরাং এই ধরণের ToUint32আমার কাছে কিছুটা অপ্রয়োজনীয় মনে হয়।
মার্সেল করপেল

7
@ মার্সেল: মনে রাখবেন যে বেশিরভাগ Array.prototypeপদ্ধতি ইচ্ছাকৃতভাবে জেনেরিক , সেগুলি অ্যারে-জাতীয় বস্তুগুলিতে ব্যবহার করা যেতে পারে Array.prototype.indexOf.call({0:'foo', 1:'bar', length: 2}, 'bar') == 1;argumentsবস্তুর একটি ভাল উদাহরণ। জন্য বিশুদ্ধ অ্যারের বস্তু, তা টাইপ পরিবর্তন অসম্ভব length, সম্পত্তি, কারণ তারা একটি বিশেষ বাস্তবায়ন [[Put ]] অভ্যন্তরীণ পদ্ধতি, এবং একটি নিয়োগ তৈরি করা হয় যখন lengthসম্পত্তি, আবার রূপান্তরিত হয় ToUint32এবং অন্যান্য ক্রিয়াগুলি উপরে ইনডেক্স মুছে ফেলতে নেওয়া হয় নতুন দৈর্ঘ্য ...
CMS

32

এটি স্বাক্ষরযুক্ত ডান বিট শিফট অপারেটর। এই এবং স্বাক্ষরিত ডান বিট শিফট অপারেটরের মধ্যে পার্থক্যটি হ'ল স্বাক্ষরযুক্ত ডান বিট শিফট অপারেটর ( >>> ) বাম দিক থেকে শূন্যগুলি পূরণ করে এবং স্বাক্ষরিত ডান বিট শিফট অপারেটর ( >> ) সাইন বিট দিয়ে পূরণ করে স্থানান্তরিত হলে সংখ্যার মান সাইন সংরক্ষণ।


ইভান, এটি 0 স্থান দ্বারা স্থানান্তরিত হবে; যে বিবৃতি কিছুই পরিবর্তন করবে না।
ডিন জে

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

2
@ ইভান, নীচে জাস্টিনের উত্তর দেখুন। এটি লেন ভেরিয়েবলের একটি সংখ্যা রয়েছে তা নিশ্চিত করার একটি উপায়।
ড্রাইভিস

1
আরও, >>>পূর্ণসংখ্যায় রূপান্তরিত হয়, যা অ্যানারি +করে না un
পুনরাবৃত্তি

এই দৈর্ঘ্য >>> 0 একটি স্বাক্ষরিত পূর্ণসংখ্যাকে একটি স্বাক্ষরবিহীন ব্যক্তিতে রূপান্তর করে। বাইনারি ফাইলটিতে স্বাক্ষরযুক্ত ইনট সহ লোড করার সময় ব্যক্তিগতভাবে আমি এটি দরকারী পেয়েছি।
ম্যাট পার্কিন্স

29

ড্রাইভারগুলি অপারেটর কী এবং এটি কী করে তা যথেষ্ট ব্যাখ্যা করেছে। এর পিছনে অর্থটি / কেন এটি ব্যবহৃত হয়েছিল:

কোনও দিক পরিবর্তন করে 0মূল সংখ্যাটি দেয় এবং এতে ফেলে দেওয়া nullহবে 0। দেখে মনে হচ্ছে যে আপনি যে উদাহরণ কোডটি দেখছেন সেটি সংজ্ঞায়িত না হলেও তা সংখ্যাসূচক this.length >>> 0কিনা তা নিশ্চিত করতে ব্যবহার করছে । lenthis.length

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

// Cast this.length to a number
var len = +this.length;

অথবা

// Cast this.length to a number, or use 0 if this.length is
// NaN/undefined (evaluates to false)
var len = +this.length || 0; 

1
যদিও, আপনার দ্বিতীয় সমাধানটি মাঝে মাঝে মূল্যায়ন করে NaN... উদাহরণস্বরূপ +{}... দু'টি একত্রিত করা সম্ভবত সেরা:+length||0
জেমস

1
এই দৈর্ঘ্য অ্যারে অবজেক্টের প্রসঙ্গে, যা একটি অ-নেতিবাচক পূর্ণসংখ্যার (কমপক্ষে এফএফ মধ্যে) ছাড়া আর কিছু হতে পারে না, সুতরাং এটি এখানে সম্ভাবনা নয়। এছাড়াও, {} || 1 রিটার্ন দেয়}} সুতরাং যদি এই দৈর্ঘ্যটি কোনও অবজেক্ট হয় তবে আপনি আর ভাল নন। প্রথম পদ্ধতিতে এই দৈর্ঘ্যটিকে অবিচ্ছিন্নভাবে কাস্ট করার সুবিধাটি হ'ল এটি হ'ল যেখানে এই দৈর্ঘ্যটি এনএন হয় Na যে প্রতিফলিত সম্পাদিত প্রতিক্রিয়া।
জাস্টিন জনসন

jslint var লেন সম্পর্কে অভিযোগ করবে = + এই দৈর্ঘ্যটিকে "বিভ্রান্তিকর অনুভূতি" হিসাবেও দেখায়। ডগলাস, আপনি খুব পিক!
বায়ার্ড র্যান্ডেল

ডগলাস পিক। এবং যদিও তার যুক্তিগুলি জ্ঞানবান এবং সাধারণত সুপ্রতিষ্ঠিত হয়, তবে তিনি যা বলেন তা নিরঙ্কুশ বা সুসমাচার নয়।
জাস্টিন জনসন

15

>>>হয় স্বাক্ষরবিহীন অধিকার শিফট অপারেটর ( পি দেখুন। জাভাস্ক্রিপ্ট 1.5 স্পেসিফিকেশন 76 ), কারণ যে বিরোধিতা >>, স্বাক্ষরিত অধিকার শিফট অপারেটর।

>>>নেতিবাচক সংখ্যা স্থানান্তর করার ফলাফল পরিবর্তন করে কারণ স্থানান্তরিত করার সময় এটি সাইন বিট সংরক্ষণ করে না । এর পরিণতি উদাহরণস্বরূপ, একজন ব্যাখ্যাকারী থেকে বোঝা যায়:

$ 1 >> 0
1
$ 0 >> 0
0
$ -1 >> 0
-1
$ 1 >>> 0
1
$ 0 >>> 0
0
$ -1 >>> 0
4294967295
$(-1 >>> 0).toString(16)
"ffffffff"
$ "cabbage" >>> 0
0

"cabbage"উপরের উদাহরণ অনুসারে , সম্ভবত এখানে কাজটি করার উদ্দেশ্যটি হ'ল দৈর্ঘ্য বা 0 পেতে হবে যদি দৈর্ঘ্যটি সংজ্ঞায়িত হয় বা কোনও পূর্ণসংখ্যা না হয় তবে উপরের উদাহরণ অনুসারে। আমি মনে করি এই ক্ষেত্রে এটি ধরে নেওয়া নিরাপদ যে this.lengthএটি কখনই হবে না < 0। তবুও, আমি তর্ক করব যে এই উদাহরণটি একটি দুষ্টু হ্যাক , দুটি কারণে:

  1. <<<নেতিবাচক সংখ্যা ব্যবহার করার সময় এর আচরণ, উপরের উদাহরণে একটি পার্শ্ব-প্রতিক্রিয়া সম্ভবত উদ্দেশ্যযুক্ত নয় (বা হওয়ার সম্ভাবনা রয়েছে)।

  2. কোডটির উদ্দেশ্যটি স্পষ্ট নয় , কারণ এই প্রশ্নের অস্তিত্ব যাচাই করে।

পারফরম্যান্স একেবারে সমালোচিত না হলে সর্বোত্তম অনুশীলনটি সম্ভবত আরও কিছু পাঠযোগ্য use

isNaN(parseInt(foo)) ? 0 : parseInt(foo)

সুও ... @ জোছনাটফিশ ঠিক আছে? এটি নিশ্চিত করার জন্য? দৈর্ঘ্যটি অ-নেতিবাচক?
অ্যান্থনি

4
ঘটনাটি -1 >>> 0কি কখনও ঘটতে পারে এবং যদি তা হয় তবে তা কি 4294967295 এ স্থানান্তরিত করা সত্যই কাম্য? দেখে মনে হচ্ছে এটি প্রয়োজনের চেয়ে লুপটি আরও কয়েকবার চালিয়ে যাবে।
প্রতারণা করুন

@ ডেসেজ: বাস্তবায়ন না দেখে this.lengthএটি জানা অসম্ভব। যে কোনও "বুদ্ধিমান" প্রয়োগের জন্য কোনও স্ট্রিংয়ের দৈর্ঘ্য কখনই negativeণাত্মক হওয়া উচিত নয়, তবে তারপরে কেউ যুক্তি দেখান যে "বুদ্ধিমান" পরিবেশে আমরা এমন কোনও this.lengthসম্পত্তির অস্তিত্ব ধরে নিতে পারি যা সর্বদা একটি অবিচ্ছেদ্য সংখ্যা দেয় returns
fmark

আপনি বলছেন >>> সাইন বিট সংরক্ষণ করে না .. ঠিক আছে .. সুতরাং, আমাকে জিজ্ঞাসা করতে হবে, যখন আমরা নেতিবাচক সংখ্যাগুলি নিয়ে কাজ করি .. যে কোনও >>> বা >> রূপান্তর হওয়ার আগে, তারা কি 2s প্রশংসা করছে? ফর্ম, বা তারা স্বাক্ষরিত পূর্ণসংখ্যা ফর্মে রয়েছে এবং আমরা কীভাবে জানব? যাইহোক, 2 এস পরিপূরক আমার মনে হয় সম্ভবত একটি সাইন বিট থাকার কথা বলা হয়নি .. এটি স্বাক্ষরিত স্বরলিপি বিকল্প, তবে একটি পূর্ণসংখ্যার চিহ্নটি নির্ধারণ করা সম্ভব
বারলপ

10

দুটি কারণ:

  1. >>> এর ফলাফল একটি "অবিচ্ছেদ্য"

  2. অপরিবর্তিত >>> 0 = 0 (যেহেতু জেএস এলএফএসকে সংখ্যার প্রসঙ্গে চেষ্টা করবে এবং জোর করবে, এটি "foo" >>> 0 ইত্যাদির জন্যও কাজ করবে)

মনে রাখবেন যে জেএসে সংখ্যার দ্বিগুণ অভ্যন্তরীণ-উপস্থাপনা রয়েছে। এটি দৈর্ঘ্যের জন্য প্রাথমিক ইনপুট বিচক্ষণতার একটি "দ্রুত" উপায়।

তবে , -1 >>> 0 (উফ, সম্ভবত পছন্দসই দৈর্ঘ্য নয়!)


0

নীচে জাভা কোডের নমুনা ভালভাবে ব্যাখ্যা করেছে:

int x = 64;

System.out.println("x >>> 3 = "  + (x >>> 3));
System.out.println("x >> 3 = "  + (x >> 3));
System.out.println(Integer.toBinaryString(x >>> 3));
System.out.println(Integer.toBinaryString(x >> 3));

আউটপুট নিম্নলিখিত:

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