diff --git a/1-js/04-object-basics/01-object/2-hello-object/task.md b/1-js/04-object-basics/01-object/2-hello-object/task.md index 2841a058f..19c39a9ca 100644 --- a/1-js/04-object-basics/01-object/2-hello-object/task.md +++ b/1-js/04-object-basics/01-object/2-hello-object/task.md @@ -1,14 +1,13 @@ -importance: 5 +গুরুত্বঃ ৫ --- -# Hello, object +# হ্যালো, অবজেক্ট -Write the code, one line for each action: - -1. Create an empty object `user`. -2. Add the property `name` with the value `John`. -3. Add the property `surname` with the value `Smith`. -4. Change the value of the `name` to `Pete`. -5. Remove the property `name` from the object. +নিন্মে বর্ণিত প্রতিটি একশনের জন্য এক একটি লাইনে কোড লিখুনঃ +1. `user` নামে একটি খালি অবজেক্ট তৈরি করুন। +2. `name` নামে একটি প্রোপার্টি `John` ভ্যালু সহ সংযুক্ত করুন। +3. `surname` নামে একটি প্রোপার্টি `Smith` ভ্যালু সহ সংযুক্ত করুন। +4. `name` নামের প্রোপার্টির ভ্যালু পরিবর্তন করে `Pete` রাখুন। +5. `name` নামের প্রোপার্টিটি অবজেক্ট থেকে মুছে দিন। diff --git a/1-js/04-object-basics/01-object/3-is-empty/_js.view/solution.js b/1-js/04-object-basics/01-object/3-is-empty/_js.view/solution.js index db3283e49..594039258 100644 --- a/1-js/04-object-basics/01-object/3-is-empty/_js.view/solution.js +++ b/1-js/04-object-basics/01-object/3-is-empty/_js.view/solution.js @@ -1,6 +1,6 @@ function isEmpty(obj) { for (let key in obj) { - // if the loop has started, there is a property + // যদি লুপ শুরু হয় তাহলে অবজেক্টে প্রোপার্টি আছে return false; } return true; diff --git a/1-js/04-object-basics/01-object/3-is-empty/solution.md b/1-js/04-object-basics/01-object/3-is-empty/solution.md index b876973b5..da18bfc15 100644 --- a/1-js/04-object-basics/01-object/3-is-empty/solution.md +++ b/1-js/04-object-basics/01-object/3-is-empty/solution.md @@ -1 +1 @@ -Just loop over the object and `return false` immediately if there's at least one property. +অবজেক্টের উপর লুপ চালান এবং যদি কোন প্রোপার্টি পাওয়া যায় সাথে সাথে `return false` করুন। \ No newline at end of file diff --git a/1-js/04-object-basics/01-object/3-is-empty/task.md b/1-js/04-object-basics/01-object/3-is-empty/task.md index c438d36a2..ffc22ef60 100644 --- a/1-js/04-object-basics/01-object/3-is-empty/task.md +++ b/1-js/04-object-basics/01-object/3-is-empty/task.md @@ -1,12 +1,12 @@ -importance: 5 +গুরুত্বঃ ৫ --- -# Check for emptiness +# খালি কিনা পরীক্ষা করুন -Write the function `isEmpty(obj)` which returns `true` if the object has no properties, `false` otherwise. +একটি ফাংশন `isEmpty(obj)` লিখুন যেটি `true` রিটার্ন করে যদি অবজেক্টে কোন প্রোপার্টি না থাকে, অন্যথায় `false` রিটার্ন করুন। -Should work like that: +কোডটি এভাবে কাজ করা উচিতঃ ```js let schedule = {}; @@ -17,4 +17,3 @@ schedule["8:30"] = "get up"; alert( isEmpty(schedule) ); // false ``` - diff --git a/1-js/04-object-basics/01-object/4-const-object/solution.md b/1-js/04-object-basics/01-object/4-const-object/solution.md index f73c2f92b..fac42de60 100644 --- a/1-js/04-object-basics/01-object/4-const-object/solution.md +++ b/1-js/04-object-basics/01-object/4-const-object/solution.md @@ -1,8 +1,8 @@ -Sure, it works, no problem. +অবশ্যই, কোন সমস্যা ছাড়াই কাজ করে। -The `const` only protects the variable itself from changing. +`const` শুধুমাত্র ওই ভেরিয়েবলকে পরিবর্তন থেকে রক্ষা করে। -In other words, `user` stores a reference to the object. And it can't be changed. But the content of the object can. +অন্যভাবে বললে, `user` অবজেক্টটির একটি রেফারেন্স সংরক্ষণ করে। এবং রেফারেন্স পরিবর্তন করা যাবে না। কিন্তু অবজেক্টের কন্টেন্ট পরিবর্তন করা যাবে। ```js run const user = { @@ -10,10 +10,10 @@ const user = { }; *!* -// works +// কাজ করে user.name = "Pete"; */!* -// error +// এরর user = 123; ``` diff --git a/1-js/04-object-basics/01-object/4-const-object/task.md b/1-js/04-object-basics/01-object/4-const-object/task.md index a9aada631..ac1ddb6c1 100644 --- a/1-js/04-object-basics/01-object/4-const-object/task.md +++ b/1-js/04-object-basics/01-object/4-const-object/task.md @@ -1,10 +1,10 @@ -importance: 5 +গুরুত্বঃ ৫ --- -# Constant objects? +# ধ্রুবক / কন্সটেন্ট অবজেক্ট? -Is it possible to change an object declared with `const`? What do you think? +`const` দিয়ে ডিক্লেয়ার করা অবজেক্ট কি পরিবর্তন করা সম্ভব? আপনার কি ধারণা? ```js const user = { @@ -12,7 +12,7 @@ const user = { }; *!* -// does it work? +// এটা কাজ করে? user.name = "Pete"; */!* ``` diff --git a/1-js/04-object-basics/01-object/5-sum-object/task.md b/1-js/04-object-basics/01-object/5-sum-object/task.md index 7e3e048d0..37d6c1942 100644 --- a/1-js/04-object-basics/01-object/5-sum-object/task.md +++ b/1-js/04-object-basics/01-object/5-sum-object/task.md @@ -1,10 +1,10 @@ -importance: 5 +গুরুত্বঃ ৫ --- -# Sum object properties +# অবজেক্টের প্রোপার্টিগুলো যোগ করা -We have an object storing salaries of our team: +আমাদের অবজেক্টে আমাদের টিমের সবার বেতন রাখা আছেঃ ```js let salaries = { @@ -14,6 +14,6 @@ let salaries = { } ``` -Write the code to sum all salaries and store in the variable `sum`. Should be `390` in the example above. +সব বেতনের যোগফল বের করে `sum` ভেরিয়েবলে রাখার কোড লিখুন। উপরের উদাহরণের যোগফল `390` হওয়া উচিত। -If `salaries` is empty, then the result must be `0`. \ No newline at end of file +যদি `salaries` খালি হয়, তাহলে ফলাফল `0` হতে হবে। \ No newline at end of file diff --git a/1-js/04-object-basics/01-object/8-multiply-numeric/_js.view/source.js b/1-js/04-object-basics/01-object/8-multiply-numeric/_js.view/source.js index a02b1e1cb..35a3b6f3d 100644 --- a/1-js/04-object-basics/01-object/8-multiply-numeric/_js.view/source.js +++ b/1-js/04-object-basics/01-object/8-multiply-numeric/_js.view/source.js @@ -6,12 +6,11 @@ let menu = { function multiplyNumeric(obj) { - - /* your code */ + + /* আপনার কোড এখানে লিখুন */ } multiplyNumeric(menu); alert( "menu width=" + menu.width + " height=" + menu.height + " title=" + menu.title ); - diff --git a/1-js/04-object-basics/01-object/8-multiply-numeric/task.md b/1-js/04-object-basics/01-object/8-multiply-numeric/task.md index 33eb89220..1cb26d753 100644 --- a/1-js/04-object-basics/01-object/8-multiply-numeric/task.md +++ b/1-js/04-object-basics/01-object/8-multiply-numeric/task.md @@ -1,15 +1,15 @@ -importance: 3 +গুরুত্বঃ ৩ --- -# Multiply numeric properties by 2 +# যেসব প্রোপার্টি ভ্যালু একটি সংখ্যা তাদের `2` দিয়ে গুন করুন -Create a function `multiplyNumeric(obj)` that multiplies all numeric properties of `obj` by `2`. +একটি ফাংশন `multiplyNumeric(obj)` লিখুন যেটি `obj` এর সব সংখ্যাভিত্তিক/numeric প্রোপার্টিগুলো কে `2` দিয়ে গুন করে। -For instance: +উদাহরণস্বরূপঃ ```js -// before the call +// কল করার আগে let menu = { width: 200, height: 300, @@ -18,7 +18,7 @@ let menu = { multiplyNumeric(menu); -// after the call +// কল করার পর menu = { width: 400, height: 600, @@ -26,8 +26,6 @@ menu = { }; ``` -Please note that `multiplyNumeric` does not need to return anything. It should modify the object in-place. - -P.S. Use `typeof` to check for a number here. - +মনে রাখবেন `multiplyNumeric` এর কিছুই রিটার্ন করার দরকার নেই। এটা শুধুই অবজেক্টকে ইন-প্লেস পরিবর্তন করবে। +পুনশ্চঃ `typeof` ব্যবহার করে নাম্বার কিনা পরীক্ষা করুন। diff --git a/1-js/04-object-basics/01-object/article.md b/1-js/04-object-basics/01-object/article.md index ea015e7ca..6600031b6 100644 --- a/1-js/04-object-basics/01-object/article.md +++ b/1-js/04-object-basics/01-object/article.md @@ -1,60 +1,60 @@ -# Objects +# অবজেক্ট -As we know from the chapter , there are seven data types in JavaScript. Six of them are called "primitive", because their values contain only a single thing (be it a string or a number or whatever). + অধ্যায়ে আমরা জেনেছি, জাভাস্ক্রিপ্টে সাতটি ডাটা টাইপ রয়েছে। তাদের মধ্যে ছয়টিকে বলা হয় "প্রিমিটিভ", কারণ তাদের ভ্যালুতে শুধু একটি জিনিসই (হোক তা স্ট্রিং, নাম্বার বা অন্য যেকোনো কিছু) থেকে থাকে। -In contrast, objects are used to store keyed collections of various data and more complex entities. In JavaScript, objects penetrate almost every aspect of the language. So we must understand them first before going in-depth anywhere else. +অন্যদিকে, বিভিন্ন ধরনের ডাটার কালেকশন ও একটু জটিল ধরনের জিনিস রাখার জন্য অবজেক্ট ব্যবহৃত হয়। জাভাস্ক্রিপ্টের প্রতিটি বিষয়ে অবজেক্টের আধিক্য এবং প্রভাব বিদ্যমান। সুতরাং অন্য কিছু নিয়ে গভীরে জানার আগে আমাদের অবশ্যই অবজেক্ট সম্পর্কে জানতে হবে। -An object can be created with figure brackets `{…}` with an optional list of *properties*. A property is a "key: value" pair, where `key` is a string (also called a "property name"), and `value` can be anything. +দ্বিতীয় বন্ধনী `{…}` ও তার সাথে একগুচ্ছ ঐচ্ছিক *প্রোপার্টি* এর সাহায্যে একটি অবজেক্ট তৈরি করা যায়। একটি প্রপার্টি "key: value" জোড়ায় হয়ে থাকে, যেখানে `key` একটি স্ট্রিং (একে প্রোপার্টির নামও বলা হয়), এবং `value` হতে পারে যেকোনো কিছু। -We can imagine an object as a cabinet with signed files. Every piece of data is stored in its file by the key. It's easy to find a file by its name or add/remove a file. +আমরা অবজেক্টকে তুলনা করতে পারি একটি সাইন করা ফাইলের কেবিনেটের সাথে। যেখানে প্রতিটি ফাইল একটি key (ফাইলের নাম) দিয়ে সংরক্ষণ করা আছে। সুতরাং ফাইলের নাম দিয়ে ফাইল খুঁজে বের করা বা নতুন ফাইল যুক্ত করা অথবা মুছে ফেলা খুবই সহজ। ![](object.svg) -An empty object ("empty cabinet") can be created using one of two syntaxes: +একটি খালি অবজেক্ট ("খালি কেবিনেট"), এ দুটি সিনট্যাক্সের যেকোনো একটি দিয়ে তৈরি করা যায়ঃ ```js -let user = new Object(); // "object constructor" syntax -let user = {}; // "object literal" syntax +let user = new Object(); // "অবজেক্ট কন্সট্রাক্টর" সিনট্যাক্স +let user = {}; // "অবজেক্ট লিটারেল" সিনট্যাক্স ``` ![](object-user-empty.svg) -Usually, the figure brackets `{...}` are used. That declaration is called an *object literal*. +অবজেক্ট তৈরিতে সচরাচর দ্বিতীয় বন্ধনী `{...}` ব্যবহৃত হয়। এধরণের ডিক্লারেশনকে বলে "অবজেক্ট লিটারেল"। -## Literals and properties +## লিটারেল এবং প্রোপার্টি -We can immediately put some properties into `{...}` as "key: value" pairs: +আমরা একই সঙ্গে কিছু প্রোপার্টি "key: value" জোড়ায় `{...}` এর ভেতর দিয়ে দিতে পারিঃ ```js -let user = { // an object - name: "John", // by key "name" store value "John" - age: 30 // by key "age" store value 30 +let user = { // একটি অবজেক্ট + name: "John", // "name" key তে "John" ভ্যালুটি সংরক্ষণ করা হয়েছে + age: 30 // "age" key তে 30 ভ্যালুটি সংরক্ষণ করা হয়েছে }; ``` -A property has a key (also known as "name" or "identifier") before the colon `":"` and a value to the right of it. +কোলনের `":"` আগে প্রোপার্টির key ("নাম" অথবা "আইডেন্টিফায়ার" ও বলা হয়) থাকে এবং এর ডানে একটি ভ্যালু থাকে। -In the `user` object, there are two properties: +`user` অবজেক্টে দুটো প্রপার্টি আছেঃ -1. The first property has the name `"name"` and the value `"John"`. -2. The second one has the name `"age"` and the value `30`. +1. প্রথম প্রোপার্টির কী হল `"name"` এবং ভ্যালু `"John"`। +2. দ্বিতীয় প্রোপার্টির নাম হল `"age"` এবং ভ্যালু `30`। -The resulting `user` object can be imagined as a cabinet with two signed files labeled "name" and "age". +`user` কে এভাবে কল্পনা করা যায়, একটি ফাইলের কেবিনেট যেখানে "name" এবং "age" লেবেলের দুটি সাইন করা ফাইল আছে। ![user object](object-user.svg) -We can add, remove and read files from it any time. +আমরা যেকোনো সময় ফাইল যুক্ত করা, মুছে দেয়া বা পড়তে পারি। -Property values are accessible using the dot notation: +প্রোপার্টির ভ্যালুগুলো ডট নোটেশন দিয়ে এক্সেস করা যায়ঃ ```js -// get property values of the object: +// অবজেক্ট থেকে প্রোপার্টি ভ্যালু গুলো নেয়া হচ্ছেঃ alert( user.name ); // John alert( user.age ); // 30 ``` -The value can be of any type. Let's add a boolean one: +ভ্যালুগুলো যেকোনো টাইপের হতে পারে। একটি বুলিয়ান প্রোপার্টি যুক্ত করা যাকঃ ```js user.isAdmin = true; @@ -62,7 +62,7 @@ user.isAdmin = true; ![user object 2](object-user-isadmin.svg) -To remove a property, we can use `delete` operator: +কোন একটা প্রোপার্টিকে মুছে দিতে আমরা `delete` অপারেটরটি ব্যবহার করতে পারিঃ ```js delete user.age; @@ -70,40 +70,40 @@ delete user.age; ![user object 3](object-user-delete.svg) -We can also use multiword property names, but then they must be quoted: +আমরা প্রোপার্টির নাম হিসেবে একাধিক শব্দও ব্যবহার করতে পারি, তবে সেক্ষেত্রে শব্দগুলো উদ্ধৃতি চিহ্নের ভেতর রাখতে হবেঃ ```js let user = { name: "John", age: 30, - "likes birds": true // multiword property name must be quoted + "likes birds": true // একাধিক শব্দের প্রোপার্টির নাম অবশ্যই উদ্ধৃতি চিহ্নের ভেতর রাখতে হবে }; ``` ![](object-user-props.svg) -The last property in the list may end with a comma: +শেষ প্রোপার্টিটি একটি কমা দিয়ে শেষ হতে পারেঃ ```js let user = { name: "John", age: 30*!*,*/!* } ``` -That is called a "trailing" or "hanging" comma. Makes it easier to add/remove/move around properties, because all lines become alike. +একে বলা হয় "ট্রেইলিং" বা "হ্যাঙ্গিং" কমা। এটি এড/রিমুভ এবং পরিবর্তন করা সহজ করে, কারণ সবগুলো লাইন দেখতে একই রকম হয়। -## Square brackets +## তৃতীয় বন্ধনী -For multiword properties, the dot access doesn't work: +একাধিক শব্দের প্রোপার্টি গুলোকে ডট দিয়ে এক্সেস করা যায় নাঃ ```js run -// this would give a syntax error +// এটি একটি সিনট্যাক্স এরর দেখাবে user.likes birds = true ``` -That's because the dot requires the key to be a valid variable identifier. That is: no spaces and other limitations. +এটার কারণ, ডট নোটেশন ব্যবহার করার জন্য key - কে একটি ভেরিয়েবল আইডেন্টিফায়ার হতে হবে। যার জন্য এতে কোন স্পেস থাকতে পারবে না এবং আরও অন্যান্য নিয়ম রয়েছে। -There's an alternative "square bracket notation" that works with any string: +তৃতীয় বন্ধনী ব্যবহার করে আরেকটি পদ্ধতি রয়েছে, যা যেকোনো স্ট্রিং এ কাজ করেঃ ```js run let user = {}; @@ -118,9 +118,9 @@ alert(user["likes birds"]); // true delete user["likes birds"]; ``` -Now everything is fine. Please note that the string inside the brackets is properly quoted (any type of quotes will do). +এখন সবকিছু কাজ করে। বন্ধনীর ভেতর স্ট্রিংটি ঠিকমত উদ্ধৃতি চিহ্নের ভেতর রয়েছে (যেকোনো উদ্ধৃতি চিহ্ন কাজ করবে)। -Square brackets also provide a way to obtain the property name as the result of any expression -- as opposed to a literal string -- like from a variable as follows: +লিটারেল স্ট্রিং এর বিপরীতে তৃতীয় বন্ধনী ব্যবহারের পদ্ধতিটি এক্সপ্রেশনের রেজাল্টকে ব্যবহার করে প্রোপার্টির নাম বের করার সুযোগ দেয় -- যেমনটা নিচের ভেরিয়েবল থেকেঃ ```js let key = "likes birds"; @@ -129,9 +129,9 @@ let key = "likes birds"; user[key] = true; ``` -Here, the variable `key` may be calculated at run-time or depend on the user input. And then we use it to access the property. That gives us a great deal of flexibility. +এখানে, `key` ভেরিয়েবলটি রান-টাইমে ক্যালকুলেট করে বা ইউজারের ইনপুট এর উপর ভিত্তি করে তৈরি হতে পারে। এবং পরে আমরা এটাকে প্রোপার্টি এক্সেস করার জন্য ব্যবহার করতে পারি। এটি প্রোগ্রাম করার সময় খুব ভাল স্বাধীনতা দেয়। -For instance: +যেমনঃ ```js run let user = { @@ -141,11 +141,11 @@ let user = { let key = prompt("What do you want to know about the user?", "name"); -// access by variable +// ভেরিয়েবলের মাধ্যমে এক্সেস করা হচ্ছে alert( user[key] ); // John (if enter "name") ``` -The dot notation cannot be used in a similar way: +ডট নোটেশনকে একই ভাবে ব্যবহার করা যায় নাঃ ```js run let user = { @@ -154,43 +154,43 @@ let user = { }; let key = "name"; -alert( user.key ) // undefined +alert( user.key ) // আনডিফাইন্ড ``` -### Computed properties +### কম্পুটেড প্রোপার্টি -We can use square brackets in an object literal. That's called *computed properties*. +আমরা অবজেক্ট লিটারেলে তৃতীয় বন্ধনী ব্যবহার করতে পারি। একে বলে *কম্পিউটেড প্রোপার্টি*। -For instance: +উদাহরণস্বরূপঃ ```js run let fruit = prompt("Which fruit to buy?", "apple"); let bag = { *!* - [fruit]: 5, // the name of the property is taken from the variable fruit + [fruit]: 5, // প্রোপার্টির নাম fruit ভেরিয়েবল থেকে নেয়া হয়েছে */!* }; alert( bag.apple ); // 5 if fruit="apple" ``` -The meaning of a computed property is simple: `[fruit]` means that the property name should be taken from `fruit`. +কম্পিউটেড প্রোপার্টির মানে খুবই সহজঃ `[fruit]` মানে প্রোপার্টির নামটি `fruit` ভেরিয়েবল থেকে নেয়া হবে। -So, if a visitor enters `"apple"`, `bag` will become `{apple: 5}`. +সুতরাং, যদি ভিজিটর `"apple"` লিখে, `bag` হয়ে যাবে `{apple: 5}`। -Essentially, that works the same as: +মূলত, নিচের কোডটিও একই কাজ করেঃ ```js run let fruit = prompt("Which fruit to buy?", "apple"); let bag = {}; -// take property name from the fruit variable +// প্রোপার্টির নাম fruit ভেরিয়েবল থেকে নাও bag[fruit] = 5; ``` -...But looks nicer. +...কিন্তু আগেরটি দেখতে সুন্দর। -We can use more complex expressions inside square brackets: +আমরা তৃতীয় বন্ধনীর ভেতরে আরও জটিল এক্সপ্রেশন ব্যবহার করতে পারিঃ ```js let fruit = 'apple'; @@ -199,16 +199,16 @@ let bag = { }; ``` -Square brackets are much more powerful than the dot notation. They allow any property names and variables. But they are also more cumbersome to write. +তৃতীয় বন্ধনী ডট নোটেশনের চাইতে অনেক বেশী শক্তিশালী। কিন্তু তাদের লেখাটা একটু কষ্টকর। -So most of the time, when property names are known and simple, the dot is used. And if we need something more complex, then we switch to square brackets. +সুতরাং অধিকাংশ সময়, যখন প্রোপার্টির নাম সহজ এবং আগে থেকেই জানা, ডট নোটেশন ব্যবহৃত হয়। এবং যদি আমাদের জটিল কিছু করতে হয়, তখন আমরা তৃতীয় বন্ধনী ব্যবহার করি। -````smart header="Reserved words are allowed as property names" -A variable cannot have a name equal to one of language-reserved words like "for", "let", "return" etc. +````smart header="সংরক্ষিত শব্দগুলো প্রোপার্টির নাম হিসেবে ব্যবহার করা যায়" +ভেরিয়েবল এর নাম ভাষা কর্তৃক সংরক্ষিত শব্দ, যেমন "for", "let", "return" ইত্যাদি হতে পারবে না। -But for an object property, there's no such restriction. Any name is fine: +কিন্তু অবজেক্টের প্রোপার্টির জন্য তেমন কোন বাধ্যবাধকতা নেই। যেকোনো নাম ব্যবহার করা যায়ঃ ```js run let obj = { @@ -220,7 +220,7 @@ let obj = { alert( obj.for + obj.let + obj.return ); // 6 ``` -Basically, any name is allowed, but there's a special one: `"__proto__"` that gets special treatment for historical reasons. For instance, we can't set it to a non-object value: +মূলত, যেকোনো নাম ব্যবহার করা যায়, কিন্তু একটি বিশেষ নাম আছেঃ `"__proto__"` যেটি ঐতিহাসিক কারণে বিশেষভাবে ব্যবহৃত হয়। যেমন, আমরা এটি অবজেক্ট নয় এমন কোন ভ্যালুতে ব্যবহার করে পারি নাঃ ```js run let obj = {}; @@ -228,30 +228,30 @@ obj.__proto__ = 5; alert(obj.__proto__); // [object Object], didn't work as intended ``` -As we see from the code, the assignment to a primitive `5` is ignored. +যেমনটি আমরা কোডে দেখতে পাচ্ছি, প্রিমিটিভ `5` এর সাথে সংযুক্তিটি উপেক্ষা করা হয়েছে। -That can become a source of bugs and even vulnerabilities if we intend to store arbitrary key-value pairs in an object, and allow a visitor to specify the keys. +যদি আমরা ইচ্ছামত কী ভ্যালু একটি অবজেক্টে রাখতে যাই, এবং ভিজিটরদের কী প্রদান করতে দিতে দেই, তাহলে এটির কারণে অনেক বাগ এবং এমনকি ভলনারেবিলিটির উৎস তৈরি হতে পারে। -In that case the visitor may choose `__proto__` as the key, and the assignment logic will be ruined (as shown above). +এরকম ক্ষেত্রে ভিজিটর `__proto__` কে কী হিসেবে দিয়ে দিতে পারে, এবং এসাইনমেন্ট এর লজিকটা নষ্ট হয়ে যেতে পারে (যেমনটা উপরে দেখানো হয়েছে)। -There is a way to make objects treat `__proto__` as a regular property, which we'll cover later, but first we need to know more about objects. +অবজেক্টকে `__proto__` কে সাধারণ প্রোপার্টি হিসেবে গণ্য করতে বাধ্য করা যায়, যা আমরা পরে দেখব, কিন্তু তার আগে আমাদের অবজেক্ট সম্পর্কে আরও জানতে হবে। -There's also another data structure [Map](info:map-set), that we'll learn in the chapter , which supports arbitrary keys. +[Map](info:map-set) নামে আরও একটি ডাটা স্ট্রাকচার রয়েছে, যেটি সম্পর্কে আমরা অধ্যায়ে জানব, যা যেকোনো কী গ্রহণ করে। ```` -## Property value shorthand +## প্রোপার্টি ভ্যালু সর্টহ্যান্ড -In real code we often use existing variables as values for property names. +প্রায়সময় আমরা বর্তমানে বিদ্যমান ভেরিয়েবলগুলোকে প্রোপার্টি নামের ভ্যালু হিসেবে ব্যবহার করি। -For instance: +যেমনঃ ```js run function makeUser(name, age) { return { name: name, age: age - // ...other properties + // ...অন্যান্য প্রোপার্টি }; } @@ -259,9 +259,9 @@ let user = makeUser("John", 30); alert(user.name); // John ``` -In the example above, properties have the same names as variables. The use-case of making a property from a variable is so common, that there's a special *property value shorthand* to make it shorter. +উপরের উদাহরণে, প্রোপার্টি এবং ভেরিয়েবলের নাম একই। এই ব্যবহারটি এত বেশী হয়ে থাকে যে একটি বিশেষ *প্রোপার্টি ভ্যালু সর্টহ্যান্ড* আছে এটিকে ছোট করে লিখার জন্য। -Instead of `name:name` we can just write `name`, like this: +`name:name` এর পরিবর্তে আমরা সরাসরি `name` লিখতে পারি, এরকম ভাবেঃ ```js function makeUser(name, age) { @@ -275,7 +275,7 @@ function makeUser(name, age) { } ``` -We can use both normal properties and shorthands in the same object: +আমরা একই অবজেক্টে একই সাথে সাধারণ প্রোপার্টি এবং সর্টহ্যান্ড ব্যবহার করতে পারিঃ ```js let user = { @@ -284,77 +284,77 @@ let user = { }; ``` -## Existence check +## প্রোপার্টি আছে কিনা পরীক্ষা করা -A notable objects feature is that it's possible to access any property. There will be no error if the property doesn't exist! Accessing a non-existing property just returns `undefined`. It provides a very common way to test whether the property exists -- to get it and compare vs undefined: +অবজেক্টের একটি উল্লেখযোগ্য ফিচার হল এর যেকোনো প্রোপার্টিকে এক্সেস করা যায়। যদি প্রোপার্টি না থাকে তাহলে কোন এরর হয় না। বরং অবজেক্টে নেই এমন প্রোপার্টিকে এক্সেস করলে `undefined` রিটার্ন করে। প্রোপার্টি আছে কি নেই পরীক্ষার জন্য সাধারনত - আনডিফাইন্ড এর সাথে তুলনা করা হয়ে থাকেঃ ```js run let user = {}; -alert( user.noSuchProperty === undefined ); // true means "no such property" +alert( user.noSuchProperty === undefined ); // true মানে "এরকম কোন প্রোপার্টি নেই" ``` -There also exists a special operator `"in"` to check for the existence of a property. +একটি বিশেষ অপারেটর `"in"` ও রয়েছে প্রোপার্টি আছে কিনা পরীক্ষা করার জন্য। -The syntax is: +সিনট্যাক্সঃ ```js "key" in object ``` -For instance: +যেমনঃ ```js run let user = { name: "John", age: 30 }; -alert( "age" in user ); // true, user.age exists -alert( "blabla" in user ); // false, user.blabla doesn't exist +alert( "age" in user ); // true, user.age আছে +alert( "blabla" in user ); // false, user.blabla নেই ``` -Please note that on the left side of `in` there must be a *property name*. That's usually a quoted string. +মনে রাখবেন `in` অপারেটরের বাম পাশে অবশ্যই একটি  "প্রোপার্টির নাম" থাকতে হবে। সাধারণত এটিকে উদ্ধৃতি চিহ্নের ভেতর রাখা হয়। -If we omit quotes, that would mean a variable containing the actual name will be tested. For instance: +উদ্ধৃতি চিহ্ন না দিলে এটিকে একটি ভেরিয়েবল হিসেবে ধরা হবে, এবং ওই ভেরিয়েবলের ভ্যালুর সাথে তুলনা করা হবে। যেমনঃ ```js run let user = { age: 30 }; let key = "age"; -alert( *!*key*/!* in user ); // true, takes the name from key and checks for such property +alert( *!*key*/!* in user ); // true, key থেকে নামটি নিয়ে, ওই নামে প্রোপার্টি আছে কিনা দেখা হচ্ছে ``` -````smart header="Using \"in\" for properties that store `undefined`" -Usually, the strict comparison `"=== undefined"` check the property existance just fine. But there's a special case when it fails, but `"in"` works correctly. +````smart header="`undefined` প্রোপার্টির ক্ষেত্রে \"in\" এর ব্যবহার" +সাধারণত, `"=== undefined"` এভাবে প্রোপার্টি আছে কিনা পরীক্ষা করা ঠিকঠাক কাজ করে, কিছু বিশেষ ক্ষেত্রে এটি ভুল ফলাফল দেয়, কিন্তু `"in"` অপারেটর ঠিকমত কাজ করে। -It's when an object property exists, but stores `undefined`: +এটি ঘটে যখন অবজেক্টের প্রোপার্টি আছে কিন্তু তা অলরেডি `undefined` হয়ে আছেঃ ```js run let obj = { test: undefined }; -alert( obj.test ); // it's undefined, so - no such property? +alert( obj.test ); // এটি undefined, তাই - প্রোপার্টি নেই? -alert( "test" in obj ); // true, the property does exist! +alert( "test" in obj ); // true, প্রোপার্টি আছে! ``` -In the code above, the property `obj.test` technically exists. So the `in` operator works right. +উপরের কোডে, `obj.test` এই প্রোপার্টি কিন্তু টেকনিক্যালি অবজেক্টে আছে। সুতরাং `in` অপারেটর ঠিকভাবে কাজ করছে। -Situations like this happen very rarely, because `undefined` is usually not assigned. We mostly use `null` for "unknown" or "empty" values. So the `in` operator is an exotic guest in the code. +এধরেন পরিস্থিতি কিছুটা বিরল, কারণ `undefined` আসলে এসাইন করা হয় না। আমরা বেশীরভাগ সময় "অজানা" বা "খালি" বুঝাতে `null` ব্যবহার করি। তাই `in` অপারেটরের ব্যবহার কদাচিৎ দেখা যায়। ```` -## The "for..in" loop +## "for..in" লুপ -To walk over all keys of an object, there exists a special form of the loop: `for..in`. This is a completely different thing from the `for(;;)` construct that we studied before. +অবজেক্টের সবগুলো কী এর উপর ভিজিট করার জন্য একটি বিশেষ ধরণের লুপ আছেঃ `for..in`। এটি `for(;;)` এর চাইতে পুরোপুরি আলাদা, যেটি আমরা পূর্বে দেখেছি। -The syntax: +সিনট্যাক্সঃ ```js for (key in object) { - // executes the body for each key among object properties + // অবজেক্টের প্রতিটি কী এর জন্য এই বডিটি এক্সিকিউট হবে } ``` -For instance, let's output all properties of `user`: +যেমন, `user` এর সব প্রোপার্টি বের করা যাকঃ ```js run let user = { @@ -371,18 +371,18 @@ for (let key in user) { } ``` -Note that all "for" constructs allow us to declare the looping variable inside the loop, like `let key` here. +উল্লেখ্য, সব "for" লুপ কন্সট্রাক্ট, লুপের মধ্যে লুপিং ভেরিয়েবল ঘোষণা করতে দেয়, যেমন এখানে `let key`। -Also, we could use another variable name here instead of `key`. For instance, `"for (let prop in obj)"` is also widely used. +এছাড়াও, আমরা এখানে `key` এর পরিবর্তে অন্য ভেরিয়েবলও ব্যবহার করতে পারব। উদাহরণস্বরূপ, `"for (let prop in obj)"` এটিও ব্যপকভাবে ব্যবহৃত হয়। -### Ordered like an object +### অবজেক্ট এ প্রোপার্টির অর্ডার -Are objects ordered? In other words, if we loop over an object, do we get all properties in the same order they were added? Can we rely on this? +আমরা যদি অবজেক্টের উপর লুপ চালাই, আমরা কি সবগুলো প্রোপার্টি একই ভাবে সাজানো পাবো যেভাবে আমরা সংযুক্ত করেছি? আমরা কি এই বিষয়ে ভরসা রাখতে পারি? -The short answer is: "ordered in a special fashion": integer properties are sorted, others appear in creation order. The details follow. +সংক্ষেপে বললেঃ "বিশেষ ভাবে সাজানো" ঃ যেসব প্রোপার্টি ইন্টেজার সেসব ক্রমানুসারে সাজানো, অন্যেরা তৈরি করার সময় যে অর্ডারে ছিল সেই অর্ডারে সাজানো পাওয়া যাবে। বিস্তারিত নিচে। -As an example, let's consider an object with the phone codes: +উদাহরণ হিসেবে, ধরি ফোন কোডের একটি অবজেক্টঃ ```js run let codes = { @@ -400,19 +400,19 @@ for (let code in codes) { */!* ``` -The object may be used to suggest a list of options to the user. If we're making a site mainly for German audience then we probably want `49` to be the first. +এই অবজেক্টটি হয়তো ইউজারকে একটি অপশনের লিস্ট দেখানোর জন্য ব্যবহার করা হবে। যদি সাইটটি মূলত জার্মান ইউজারদের জন্য হয়, তাহলে আমরা চাইব `49` যেন প্রথমেই থাকে। -But if we run the code, we see a totally different picture: +কিন্তু কোড রান করলে আমরা পুরোপুরি অন্যরকম অবস্থা দেখিঃ - USA (1) goes first - then Switzerland (41) and so on. -The phone codes go in the ascending sorted order, because they are integers. So we see `1, 41, 44, 49`. +ফোন কোডগুলো ঊর্ধ্বগামী (ascending) ক্রমে সাজানো, কারণ তারা ইন্টিজার। তাই আমরা পাই `1, 41, 44, 49`। -````smart header="Integer properties? What's that?" -The "integer property" term here means a string that can be converted to-and-from an integer without a change. +````smart header="ইন্টিজার প্রোপার্টি?" +"ইন্টিজার প্রোপার্টি" হল একটি স্ট্রিং যেটি ইন্টিজার (পূর্ণসংখ্যা) থেকে বা ইন্টিজারে কোন পরিবর্তন ছাড়াই পরিবর্তন করা যায়। -So, "49" is an integer property name, because when it's transformed to an integer number and back, it's still the same. But "+49" and "1.2" are not: +তাই, "49" একটি ইন্টিজার প্রোপার্টির নাম, কারণ যখন এটিকে ইন্টিজারে পরিবর্তন এবং ইন্টিজার থেকে স্ট্রিং এ পরিবর্তন করা হয় এটি একই থাকে। কিন্তু "+49" এবং "1.2" ইন্টিজার নয়ঃ ```js run // Math.trunc is a built-in function that removes the decimal part @@ -422,7 +422,7 @@ alert( String(Math.trunc(Number("1.2"))) ); // "1", not same "1.2" ⇒ not integ ``` ```` -...On the other hand, if the keys are non-integer, then they are listed in the creation order, for instance: +...অপরদিকে, যদি কী ইন্টিজার না হয়, তাহলে তারা তৈরির সময় যে ক্রমে ছিল সেভাবেই থাকবে, যেমনঃ ```js run let user = { @@ -432,16 +432,16 @@ let user = { user.age = 25; // add one more *!* -// non-integer properties are listed in the creation order +// যদি কী ইন্টিজার না হয়, তাহলে তারা তৈরির সময় যে ক্রমে ছিল সেভাবেই থাকবে */!* for (let prop in user) { alert( prop ); // name, surname, age } ``` -So, to fix the issue with the phone codes, we can "cheat" by making the codes non-integer. Adding a plus `"+"` sign before each code is enough. +তাই, ফোন কোডের ইস্যু ঠিক করতে আমরা একটু "ধূর্ততার" সাহায্য নিতে পারি। প্রতিটি কোডের আগে `"+"` চিহ্ন ব্যবহার করে তাদের নন-ইন্টিজার করে দেয়াই যথেষ্ট। -Like this: +এভাবেঃ ```js run let codes = { @@ -457,30 +457,30 @@ for (let code in codes) { } ``` -Now it works as intended. +এখন যেভাবে কাজ করা উচিত সেভাবেই কাজ করছে। -## Copying by reference +## রেফারেন্সের মাধ্যমে কপি করা -One of the fundamental differences of objects vs primitives is that they are stored and copied "by reference". +অবজেক্ট আর প্রিমিটিভ এর মধ্যে একটি মৌলিক পার্থক্য হল, অবজেক্ট রেফারেন্সের ("by reference") মাধ্যমে সংরক্ষণ এবং কপি করা হয়। -Primitive values: strings, numbers, booleans -- are assigned/copied "as a whole value". +প্রিমিটিভ ভ্যালুগুলোঃ স্ট্রিং, নাম্বার, বুলিয়ান -- এসব সংরক্ষণ এবং কপি হয়ে থাকে সম্পূর্ণ/সরাসরি ভ্যালু হিসেবে। -For instance: +উদাহরণঃ ```js let message = "Hello!"; let phrase = message; ``` -As a result we have two independent variables, each one is storing the string `"Hello!"`. +এর ফলে, আমাদের কাছে দুটি স্বাধীন ভেরিয়েবল আছে, যাদের প্রত্যেকে `"Hello!"` স্ট্রিংটি সংরক্ষণ করে। ![](variable-copy-value.svg) -Objects are not like that. +অবজেক্টগুলো এই রকম না। -**A variable stores not the object itself, but its "address in memory", in other words "a reference" to it.** +**ভেরিয়েবল সরাসরি অবজেক্টকে সংরক্ষণ করে না, অবজেক্টের "মেমোরি এড্রেস", বা অবজেক্টের "রেফারেন্স" সংরক্ষণ করে।** -Here's the picture for the object: +এখানে অবজেক্টটির গঠনের ছবি দেয়া হলঃ ```js let user = { @@ -490,25 +490,25 @@ let user = { ![](variable-contains-reference.svg) -Here, the object is stored somewhere in memory. And the variable `user` has a "reference" to it. +এখানে, অবজেক্টটি মেমোরিতে কোথাও সংরক্ষিত রয়েছে। এবং `user` ভেরিয়েবলের কাছে এই অবজেক্টের "রেফারেন্স" রয়েছে। -**When an object variable is copied -- the reference is copied, the object is not duplicated.** +**যখন একটি অবজেক্ট ভেরিয়েবলকে কপি করা হয় -- রেফারেন্সটি কপি হয়। অবজেক্টটি দ্বিতীয়বার তৈরি হয় না।** -If we imagine an object as a cabinet, then a variable is a key to it. Copying a variable duplicates the key, but not the cabinet itself. +অবজেক্টকে যদি কেবিনেট ধরি, তাহলে ভেরিয়েবলের কাছে এর চাবি থাকে। ভেরিয়েবল কপি করা মানে চাবি কপি করা, পুরো কেবিনেটকে কপি করা নয়। -For instance: +উদাহরণস্বরূপঃ ```js no-beautify let user = { name: "John" }; -let admin = user; // copy the reference +let admin = user; // রেফারেন্স কপি হচ্ছে ``` -Now we have two variables, each one with the reference to the same object: +এখন আমাদের কাছে দুটি ভেরিয়েবল আছে, প্রত্যেকের কাছে একই অবজেক্টের রেফারেন্স আছেঃ ![](variable-copy-reference.svg) -We can use any variable to access the cabinet and modify its contents: +আমরা যেকোনো ভেরিয়েবল ব্যবহার করে কেবিনেটকে এক্সেস এবং এর কন্টেন্টকে মডিফাই করতে পারিঃ ```js run let user = { name: 'John' }; @@ -516,46 +516,46 @@ let user = { name: 'John' }; let admin = user; *!* -admin.name = 'Pete'; // changed by the "admin" reference +admin.name = 'Pete'; // "admin" রেফারেন্সের মাধ্যমে পরিবর্তন করা হচ্ছে */!* -alert(*!*user.name*/!*); // 'Pete', changes are seen from the "user" reference +alert(*!*user.name*/!*); // 'Pete', "user" রেফারেন্সের মাধ্যমে পরিবর্তনটা দেখা হচ্ছে ``` -The example above demonstrates that there is only one object. As if we had a cabinet with two keys and used one of them (`admin`) to get into it. Then, if we later use the other key (`user`) we would see changes. +উপরের উদাহরণটি প্রমাণ করে যে শুধু একটিই অবজেক্ট রয়েছে। অনেকটা যেন আমাদের কাছে একই কেবিনেটের দুইটা চাবি আছে এবং একটা চাবি (`admin`) ব্যবহার করা হয়েছে কেবিনেট খুলার জন্য। এরপর, আমরা যদি অন্য চাবি (`user`) ব্যবহার করি, আমরা কি পরিবর্তন হয়েছে তা দেখতে পাই। -### Comparison by reference +### রেফারেন্সের সাহায্যে তুলনা -The equality `==` and strict equality `===` operators for objects work exactly the same. +ইকুয়ালিটি `==` and স্ট্রিক্ট ইকুয়ালিটি `===` অপারেটর অবজেক্টের জন্য একই ভাবে কাজ করে। -**Two objects are equal only if they are the same object.** +**দুটি অবজেক্ট ইকুয়াল বা সমান হবে শুধুমাত্র তারা যদি একই অবজেক্ট হয়ে থাকে।** -For instance, if two variables reference the same object, they are equal: +যেমন, যদি দুটি ভেরিয়েবলের রেফারেন্স একই অবজেক্টকে পয়েন্ট করে, তাহলে তারা সমানঃ ```js run let a = {}; let b = a; // copy the reference -alert( a == b ); // true, both variables reference the same object +alert( a == b ); // true, দুটি ভেরিয়েবলে একই অবজেক্টের পয়েন্ট রাখা আছে alert( a === b ); // true ``` -And here two independent objects are not equal, even though both are empty: +এবং এখানে দুটি আলাদা অবজেক্ট দেখানো হচ্ছে যারা সমান না, যদিও দুটিই খালি অবজেক্ট। ```js run let a = {}; -let b = {}; // two independent objects +let b = {}; // দুটি আলাদা অবজেক্ট alert( a == b ); // false ``` -For comparisons like `obj1 > obj2` or for a comparison against a primitive `obj == 5`, objects are converted to primitives. We'll study how object conversions work very soon, but to tell the truth, such comparisons are necessary very rarely and usually are a result of a coding mistake. +`obj1 > obj2` এ রকম তুলনা বা প্রিমিটিভের সাথে তুলনা `obj == 5` এর সময় অবজেক্ট প্রিমিটিভে রূপান্তরিত হয়। আমরা শীঘ্রই অবজেক্ট কিভাবে রূপান্তর হয় তা জানব, কিন্তু সত্যি বলতে, এরকম তুলনা বাস্তবে খুবই কম প্রয়োজন হয় এবং সাধারণত কোডে ভুলের কারণে হয়ে থাকে। -### Const object +### কন্সটেন্ট/ধ্রুবক অবজেক্ট -An object declared as `const` *can* be changed. +`const` দিয়ে ঘোষণা করা অবজেক্ট পরিবর্তিত *হতে পারে*। -For instance: +উদাহরণস্বরূপঃ ```js run const user = { @@ -569,9 +569,9 @@ user.age = 25; // (*) alert(user.age); // 25 ``` -It might seem that the line `(*)` would cause an error, but no, there's totally no problem. That's because `const` fixes only value of `user` itself. And here `user` stores the reference to the same object all the time. The line `(*)` goes *inside* the object, it doesn't reassign `user`. +এটা মনে হতে পারে `(*)` এই লাইনে একটি এরর হবে, কিন্তু না, কোন এরর নেই। কারণ `const` শুধুমাত্র `user` এর ভ্যালুকে পরিবর্তন হতে বাধা দেয়। এখানে `user` সবসময় একই অবজেক্টের রেফারেন্স রাখছে। `(*)` এই লাইনে অবজেক্টের *ভেতরে* পরিবর্তন করা হয়েছে, `user` এর ভ্যালু অপরিবর্তিত রয়ে গেছে। -The `const` would give an error if we try to set `user` to something else, for instance: +`const` এরর দিবে যদি আমরা `user` এর ভ্যালু পরিবর্তন করতে চাই, যেমনঃ ```js run const user = { @@ -586,19 +586,19 @@ user = { }; ``` -...But what if we want to make constant object properties? So that `user.age = 25` would give an error. That's possible too. We'll cover it in the chapter . +...কিন্তু আমরা যদি অবজেক্টের প্রোপার্টিকে ধ্রুবক হিসেবে রাখতে চাই? যাতে `user.age = 25` এটা এরর দেয়। এটা করাও সম্ভব। আমরা অধ্যায়ে তা দেখব। -## Cloning and merging, Object.assign +## ক্লোন এবং মার্জ করা, Object.assign -So, copying an object variable creates one more reference to the same object. +অবজেক্টের ভেরিয়েবল কপি করা মানে, একই অবজেক্টের আরেকটি রেফারেন্স তৈরি করা। -But what if we need to duplicate an object? Create an independent copy, a clone? +কিন্তু আমরা যদি অবজেক্টের প্রতিলিপি/ডুপ্লিকেট তৈরি করতে চাই? একটি সম্পূর্ণ আলাদা কপি তৈরি করতে চাই? -That's also doable, but a little bit more difficult, because there's no built-in method for that in JavaScript. Actually, that's rarely needed. Copying by reference is good most of the time. +অবশ্যই করা যাবে, কিন্তু প্রক্রিয়াটি একটু জটিল, কারণ জাভাস্ক্রিপ্টে এ কাজের জন্য কোন বিল্ড-ইন মেথড নেই। আসলে এটি কদাচিৎ প্রয়োজন হয়। রেফারেন্স দিয়ে কপি করাই বেশিরভাগ কাজের জন্য যথেষ্ট। -But if we really want that, then we need to create a new object and replicate the structure of the existing one by iterating over its properties and copying them on the primitive level. +কিন্তু আমরা যদি আসলেই এটা করতে চাই, তাহলে আমাদের একটি নতুন অবজেক্ট তৈরি করতে হবে এবং আগের অবজেক্টের স্ট্রাকচার/গঠন নতুন অবজেক্টে কপি করতে হবে। এটা করতে আগের অবজেক্টের প্রতিটি প্রোপার্টিকে প্রিমিটিভ স্তর থেকে নতুন অবজেক্টে কপি করতে হবে। -Like this: +এভাবেঃ ```js run let user = { @@ -607,32 +607,32 @@ let user = { }; *!* -let clone = {}; // the new empty object +let clone = {}; // নতুন খালি অবজেক্ট -// let's copy all user properties into it +// user এর সব প্রোপার্টি নতুন অবজেক্টে কপি করা যাক for (let key in user) { clone[key] = user[key]; } */!* -// now clone is a fully independent clone -clone.name = "Pete"; // changed the data in it +// এখন clone হচ্ছে পুরো আলাদা একটি অবজেক্ট +clone.name = "Pete"; // এটির ডাটা পরিবর্তন করা হচ্ছে -alert( user.name ); // still John in the original object +alert( user.name ); // এখনও আগের অবজেক্টের ভ্যালু John ``` -Also we can use the method [Object.assign](mdn:js/Object/assign) for that. +এ কাজের জন্য আমরা [Object.assign](mdn:js/Object/assign) মেথডটাও ব্যবহার করতে পারি। -The syntax is: +সিনট্যাক্সঃ ```js Object.assign(dest, [src1, src2, src3...]) ``` -- Arguments `dest`, and `src1, ..., srcN` (can be as many as needed) are objects. -- It copies the properties of all objects `src1, ..., srcN` into `dest`. In other words, properties of all arguments starting from the 2nd are copied into the 1st. Then it returns `dest`. +- `dest`, এবং `src1, ..., srcN` আর্গুমেন্টগুলো (যতগুলো ইচ্ছা হতে পারে) হল অবজেক্ট। +- এটি `src1, ..., srcN` অবজেক্টগুলোর প্রোপার্টি `dest` অবজেক্টে কপি করে। অন্যভাবে বললে, দ্বিতীয় আর্গুমেন্ট থেকে শুরু করে সব আর্গুমেন্ট এর প্রোপার্টিগুলো প্রথম আর্গুমেন্টে কপি হবে। তারপরত এটি `dest` কে রিটার্ন করে। -For instance, we can use it to merge several objects into one: +যেমন, আমরা এটিকে একাধিক অবজেক্টকে মার্জ করার জন্য ব্যবহার করতে পারিঃ ```js let user = { name: "John" }; @@ -640,14 +640,14 @@ let permissions1 = { canView: true }; let permissions2 = { canEdit: true }; *!* -// copies all properties from permissions1 and permissions2 into user +// permissions1 এবং permissions2 অবজেক্টদ্বয় থেকে সকল প্রোপার্টি user এ কপি করা হচ্ছে Object.assign(user, permissions1, permissions2); */!* -// now user = { name: "John", canView: true, canEdit: true } +// এখন user = { name: "John", canView: true, canEdit: true } ``` -If the receiving object (`user`) already has the same named property, it will be overwritten: +যদি শেষোক্ত অবজেক্টে (`user`) একই নামে প্রোপার্টি আগে থেকেই থেকে থাকে, সেটি ওভাররাইড হয়ে যাবেঃ ```js let user = { name: "John" }; @@ -658,7 +658,7 @@ Object.assign(user, { name: "Pete", isAdmin: true }); // now user = { name: "Pete", isAdmin: true } ``` -We also can use `Object.assign` to replace the loop for simple cloning: +সাধারণ ক্লোনিং এর ক্ষেত্রে আমরা লুপ এর পরিবর্তে `Object.assign` কে ব্যবহার করতে পারিঃ ```js let user = { @@ -671,9 +671,9 @@ let clone = Object.assign({}, user); */!* ``` -It copies all properties of `user` into the empty object and returns it. Actually, the same as the loop, but shorter. +এটি `user` এর সকল প্রোপার্টিকে খালি অবজেক্টে কপি করে এবং রিটার্ন করে। আসলে, এটি লুপের মতই, কিন্তু ছোট করে লেখা যায়। -Until now we assumed that all properties of `user` are primitive. But properties can be references to other objects. What to do with them? +এতক্ষণ পর্যন্ত আমরা ধরে নিয়েছি `user` এর সব প্রোপার্টিগুলো প্রিমিটিভ। কিন্তু প্রোপার্টিতে অন্য অবজেক্টের রেফারেন্স থাকতে পারে। তাদের কিভাবে কপি করা যায়? Like this: ```js run @@ -688,7 +688,7 @@ let user = { alert( user.sizes.height ); // 182 ``` -Now it's not enough to copy `clone.sizes = user.sizes`, because the `user.sizes` is an object, it will be copied by reference. So `clone` and `user` will share the same sizes: +এখন `clone.sizes = user.sizes` এভাবে কপি করা যথেষ্ট না, কারণ `user.sizes` একটি অবজেক্ট, এটির রেফারেন্স কপি হবে। সুতরাং `clone` এবং `user` এর size প্রোপার্টি একই অবজেক্ট হবেঃ Like this: ```js run @@ -702,49 +702,49 @@ let user = { let clone = Object.assign({}, user); -alert( user.sizes === clone.sizes ); // true, same object +alert( user.sizes === clone.sizes ); // true, একই অবজেক্ট // user and clone share sizes -user.sizes.width++; // change a property from one place -alert(clone.sizes.width); // 51, see the result from the other one +user.sizes.width++; // একজায়গায় প্রোপার্টিকে পরিবর্তন করা হচ্ছে +alert(clone.sizes.width); // 51, অন্য জায়গায় পরিবর্তিত হয়ে গেছে ``` -To fix that, we should use the cloning loop that examines each value of `user[key]` and, if it's an object, then replicate its structure as well. That is called a "deep cloning". +এটা ঠিক করার জন্য, আমাদের ক্লোন করার জন্য একটি লুপ চালাতে হবে, যেটি প্রতিটি `user[key]` ভ্যালুকে পরীক্ষা করে দেখবে - এটি অবজেক্ট কিনা, তারপর অবজেক্ট হলে সেই অবজেক্টের স্ট্রাকচারও কপি করা হবে। এটাকে বলে "ডিপ ক্লোনিং"। -There's a standard algorithm for deep cloning that handles the case above and more complex cases, called the [Structured cloning algorithm](https://html.spec.whatwg.org/multipage/structured-data.html#safe-passing-of-structured-data). In order not to reinvent the wheel, we can use a working implementation of it from the JavaScript library [lodash](https://lodash.com), the method is called [_.cloneDeep(obj)](https://lodash.com/docs#cloneDeep). +একটি স্ট্যান্ডার্ড এলগরিদম আছে যা উপরে বর্ণিত ডিপ ক্লোনিং এর কেসটি এবং আরও অনেক জটিল কেস হ্যান্ডেল করে, যাকে বলা হয় [স্ট্যান্ডার্ড ক্লোনিং এলগরিদম](https://html.spec.whatwg.org/multipage/structured-data.html#safe-passing-of-structured-data)। বার বার একই কাজটি না করার জন্য আমরা এর একটি ইমপ্লিমেন্টেশন ব্যবহার করতে পারি এই লাইব্রেরী থেকে - [lodash](https://lodash.com), মেথডটির নাম [_.cloneDeep(obj)](https://lodash.com/docs#cloneDeep). -## Summary +## সারাংশ -Objects are associative arrays with several special features. +অবজেক্ট হল কিছু বিশেষ ফিচার যুক্ত এসোসিয়েটিভ অ্যারে। -They store properties (key-value pairs), where: -- Property keys must be strings or symbols (usually strings). -- Values can be of any type. +তারা কিছু প্রোপার্টি সংরক্ষণ করে (key-value pairs), যেখানেঃ +- প্রোপার্টির কী অবশ্যই স্ট্রিং বা সিম্বল হতে হবে (সাধারণত স্ট্রিং)। +- ভ্যালু যেকোনো টাইপের হতে পারে। -To access a property, we can use: -- The dot notation: `obj.property`. -- Square brackets notation `obj["property"]`. Square brackets allow to take the key from a variable, like `obj[varWithKey]`. +একটি প্রোপার্টিকে এক্সেস করতে আমরা ব্যবহার করিঃ +- ডট নোটেশনঃ `obj.property`. +- তৃতীয় বন্ধনী `obj["property"]`। তৃতীয় বন্ধনী নোটেশন আমাদের ভেরিয়েবল থেকে কী ব্যবহার করতে দেয়, এভাবে `obj[varWithKey]`। -Additional operators: -- To delete a property: `delete obj.prop`. -- To check if a property with the given key exists: `"key" in obj`. -- To iterate over an object: `for (let key in obj)` loop. +অন্যান্য অপারেটরসমূহঃ +- প্রোপার্টি মুছে দিতেঃ `delete obj.prop`। +- নির্দিষ্ট কী এর কোন প্রোপার্টি আছে কিনা পরীক্ষা করতেঃ `"key" in obj`। +- অবজেক্টের উপর ইটারেট বা প্রতিটি কী বের করতেঃ `for (let key in obj)` লুপ ব্যবহার করা হয়। -Objects are assigned and copied by reference. In other words, a variable stores not the "object value", but a "reference" (address in memory) for the value. So copying such a variable or passing it as a function argument copies that reference, not the object. All operations via copied references (like adding/removing properties) are performed on the same single object. +অবজেক্টকে রেফারেন্সের মাধ্যমে এসাইন বা কপি করা হয়। অন্যভাবে বললে, ভেরিয়েবল "অবজেক্ট ভ্যালু" রাখে না, কিন্তু ভ্যালুর "রেফারেন্স" (মেমোরি এড্রেস) রাখে। সুতরাং এরকম ভেরিয়েবল কপি করা বা ফাংশন আর্গুমেন্টে পাঠালে রেফারেন্সটা কপি হয়, অবজেক্টটা নয়। কপি করা রেফারেন্সের মাধ্যমে করা সকল অপারেশন (যেমন প্রোপার্টি এড/রিমুভ করা) মূল অবজেক্টেই হয়। -To make a "real copy" (a clone) we can use `Object.assign` or [_.cloneDeep(obj)](https://lodash.com/docs#cloneDeep). +"আসলেই কপি" (ক্লোন) করার জন্য আমরা `Object.assign` অথবা [_.cloneDeep(obj)](https://lodash.com/docs#cloneDeep) ব্যবহার করতে পারি। -What we've studied in this chapter is called a "plain object", or just `Object`. +আমরা এই অধ্যায়ে যা জেনেছি তাকে "প্লেইন অবজেক্ট", বা শুধু or `Object` বলা হয়। -There are many other kinds of objects in JavaScript: +জাভাস্ক্রিপ্টে অনেক অন্যান্য অবজেক্ট রয়েছেঃ -- `Array` to store ordered data collections, -- `Date` to store the information about the date and time, -- `Error` to store the information about an error. -- ...And so on. +- `Array` ডাটা কালেকশন সংরক্ষণের জন্য, +- `Date` তারিখ ও সময় সংক্রান্ত তথ্য সংরক্ষণের জন্য, +- `Error` এরর সম্পর্কিত তথ্য সংরক্ষণের জন্য, +- ...ইত্যাদি। -They have their special features that we'll study later. Sometimes people say something like "Array type" or "Date type", but formally they are not types of their own, but belong to a single "object" data type. And they extend it in various ways. +তাদের কিছু বিশেষ বৈশিষ্ট্য আছে যা আমরা পরে জানব। মাঝে মাঝে অনেকে "Array type" বা "Date type" বলে, কিন্তু এসব নিজেরা কোন আলাদা টাইপ না, এগুলো সব "অবজেক্ট" ডাটা টাইপ। এবং তাদের নানা ভাবে বর্ধিত করা হয়েছে। -Objects in JavaScript are very powerful. Here we've just scratched the surface of a topic that is really huge. We'll be closely working with objects and learning more about them in further parts of the tutorial. +জাভাস্ক্রিপ্ট এ অবজেক্ট খুবই শক্তিশালী। আমরা অনেক বড় একটি বিষয় সংক্ষিপ্তভাবে আলোচনা করেছি। আমরা অবজেক্ট নিয়ে প্রচুর কাজ করব এবং এই টিউটেরিয়ালের অন্যান্য অংশে অবজেক্ট সম্পর্কে আরও জানব।