From 2898ed40169e65710de1196e7c1336633b83c2b1 Mon Sep 17 00:00:00 2001 From: tahnoonn Date: Thu, 8 Oct 2020 00:12:02 +0600 Subject: [PATCH 1/4] Object Copying, References --- .../02-object-copy/article.md | 230 ++++++++++++++++++ .../variable-contains-reference.svg | 1 + .../variable-copy-reference.svg | 2 + .../02-object-copy/variable-copy-value.svg | 3 + .../1-two-functions-one-object/solution.md | 0 .../1-two-functions-one-object/task.md | 0 .../_js.view/solution.js | 0 .../2-calculator-constructor/_js.view/test.js | 0 .../2-calculator-constructor/solution.md | 0 .../2-calculator-constructor/task.md | 0 .../3-accumulator/_js.view/solution.js | 0 .../3-accumulator/_js.view/test.js | 0 .../3-accumulator/solution.md | 0 .../3-accumulator/task.md | 0 .../article.md | 0 .../{07-symbol => 08-symbol}/article.md | 0 .../article.md | 0 17 files changed, 236 insertions(+) create mode 100644 1-js/04-object-basics/02-object-copy/article.md create mode 100644 1-js/04-object-basics/02-object-copy/variable-contains-reference.svg create mode 100644 1-js/04-object-basics/02-object-copy/variable-copy-reference.svg create mode 100644 1-js/04-object-basics/02-object-copy/variable-copy-value.svg rename 1-js/04-object-basics/{05-constructor-new => 06-constructor-new}/1-two-functions-one-object/solution.md (100%) rename 1-js/04-object-basics/{05-constructor-new => 06-constructor-new}/1-two-functions-one-object/task.md (100%) rename 1-js/04-object-basics/{05-constructor-new => 06-constructor-new}/2-calculator-constructor/_js.view/solution.js (100%) rename 1-js/04-object-basics/{05-constructor-new => 06-constructor-new}/2-calculator-constructor/_js.view/test.js (100%) rename 1-js/04-object-basics/{05-constructor-new => 06-constructor-new}/2-calculator-constructor/solution.md (100%) rename 1-js/04-object-basics/{05-constructor-new => 06-constructor-new}/2-calculator-constructor/task.md (100%) rename 1-js/04-object-basics/{05-constructor-new => 06-constructor-new}/3-accumulator/_js.view/solution.js (100%) rename 1-js/04-object-basics/{05-constructor-new => 06-constructor-new}/3-accumulator/_js.view/test.js (100%) rename 1-js/04-object-basics/{05-constructor-new => 06-constructor-new}/3-accumulator/solution.md (100%) rename 1-js/04-object-basics/{05-constructor-new => 06-constructor-new}/3-accumulator/task.md (100%) rename 1-js/04-object-basics/{05-constructor-new => 06-constructor-new}/article.md (100%) rename 1-js/04-object-basics/{07-symbol => 08-symbol}/article.md (100%) rename 1-js/04-object-basics/{08-object-toprimitive => 09-object-toprimitive}/article.md (100%) diff --git a/1-js/04-object-basics/02-object-copy/article.md b/1-js/04-object-basics/02-object-copy/article.md new file mode 100644 index 000000000..0d4c5c98d --- /dev/null +++ b/1-js/04-object-basics/02-object-copy/article.md @@ -0,0 +1,230 @@ +# অবজেক্ট কপি করা, রেফেরেন্স + +অবজেক্ট এবং প্রিমিটিভ দের মধ্যে অন্যতম পার্থক্য হলো যে অবজেক্ট গুলি কপি ও সংরখ্যন হয় রেফারেন্স এর মাধ্যমে । + + +প্রিমিটিভ মান: স্ট্রিং, সংখ্যা, বুলিয়ানস - "সম্পূর্ণ মান হিসাবে" এসাইন/কপি করা হয়। + +যেমন: + +```js +let message = "Hello!"; +let phrase = message; +``` + +As a result we have two independent variables, each one is storing the string `"Hello!"`. +এর ফলে আমরা দুটি স্বাধীন ভেরিয়েবল আছে, প্রতিটি "হেলো" স্ট্রিংটি সংরক্ষণ করছে । + +![](variable-copy-value.svg) + +অবজেক্ট রা এমন নয়। + +** একটি ভেরিএবল অবজেক্ট কে সংরক্ষণ করে না, বরং এর ঠিকানা সংরক্ষণ করে, অন্য কথায় এটির একটি "রেফারেন্স" * + +অবজেক্ট এর ছবিঃ + +```js +let user = { + name: "John" +}; +``` + +![](variable-contains-reference.svg) + +এখানে, বস্তুটি মেমোরির কোথাও সংরক্ষণ করা হয়েছে। এবং ভেরিয়েবল `user` এর কাছে এর রেফারেন্স আছে। + +** যখন কোনও বস্তুর ভেরিয়েবল কপি করা হয় - রেফারেন্সটি কপি হয়, বস্তুটি নকল হয় না * ** + +যেমন : + +```js no-beautify +let user = { name: "John" }; + +let admin = user; // রেফারেন্স করই হলো +``` + +এখন আমাদের দুটি ভেরিয়েবল রয়েছে, প্রত্যেকেই একই বস্তুর রেফারেন্স: + +![](variable-copy-reference.svg) + +আমরা এই দুটি ভেরিএবল এর যেকোনো টি ব্যাবহার করে অবজেক্ট টি এক্সেস করতে পারি ও এর ভেতরের কন্টেন্ট বা ডেটা গুলি পরিবর্তন করতে পারি। + +```js run +let user = { name: 'John' }; + +let admin = user; + +*!* +admin.name = 'Pete'; // এডমিন রেফারেন্সে এর মাদ্ধ্যমে পরিবর্তন হোল +*/!* + +alert(*!*user.name*/!*); // 'Pete', changes are seen from the "user" reference +``` + +উপরের উদাহরণটি প্রমাণ করে যে এখানে কেবল একটি অবজেক্ট রয়েছে।যেন আমাদের একি কক্ষের দুটি চাবি আছে আর আমরা একটি চাবি (`admin`) দিয়ে কক্ষে প্রবেশ করেছি ও অন্যটি (`user`) দিয়ে কক্ষের ভেতরে উকি দিয়েছি। + +## রেফারেন্স এর মাধ্যমে তুলনা + +ইকুয়ালিটি `==` ও স্ট্রিক্ট ইকুয়ালিটি `===` দুটোই অবজেক্টের ক্ষেত্রে সমানভাবে কাজ করে। + +**যদি দুটি অবজেক্ট একই বস্তু হয়, শুধুমাত্র তাহলেই তারা "ইকুয়াল" ** + +এখানে দুইটি ভেরিএবল একই অবজেক্ট কে রেফারেন্স করে, সুতরাং তারা ইকুয়াল: + +```js run +let a = {}; +let b = a; // রেফারেন্স কপি হোলো + +alert( a == b ); // true, দুটি অবজেক্ট ই সমান +alert( a === b ); // true +``` + +আর এখানে দুটি অবজেক্ট সমান নয়, যদিও তারা দুজনই খালি : + +```js run +let a = {}; +let b = {}; // দুটি স্বাধীন অবজেক্ট + +alert( a == b ); // false +``` + +`obj1 > obj2` এর মত তুলনা এর জন্য or অথবা কোন প্রিমিটিভ এর সাথে তুলনা করার জন্য `obj == 5`, অবজেক্ট কে প্রিমিটিভ এ রূপান্তর করা হয়। অবজেক্ট গুলোকে কিভাবে তুলনা করা হয় তা সম্পর্কে আমরা শিগ্রই জানব, কিন্তু সত্যি বলতে এই ধরনের তুলনা খুব কমি করা হয়, সাধারণত ভুলক্রমে। + +## ক্লোন করা ও মিলিত করা, Object.assign + +তো আমরা জানলাম অবজেক্ট ভেরিএবল কে কপি করলে তা শুধু একটি নতুন রেফারেন্স তৈরি করে। + +কিন্তু আমাদের যদি অবজেক্ট এর স্বাধীন নকল বা ক্লোন তৈরি করতে হয় তাহলে আমরা কই করব? + +তাও সম্ভব কিন্তু একটু কঠিন, কারণ এই কাজ করার জন্য জাভাস্ক্রিপ্ট এর কোন অন্তর্নির্মিত মেথড নেই। +আসলে এটি খুব কমই প্রয়োজন হয়। রেফারেন্সে কপি করাই বেশিরভাগ সময় যথেষ্ট। + +কিন্তু আমরা যদি আসলেই এটি চাই তাহলে আমাদের নতুন একটি অবজেক্ট বানাতে হবে, ও মুল অবজেক্ট তির সম্পূর্ণ কাঠামো কে নকল করে এর সকল প্রপার্টির প্রিমিটিভ স্তরে প্রতিলিতি তৈরি করতে হবে। + +যেমন: + +```js run +let user = { + name: "John", + age: 30 +}; + +*!* +let clone = {}; // নতুন খালি অবজেক্ট + +// এখন user অবজেক্ট এর সকল প্রপার্টি কে clone অবজেক্ট এ কপি করি +for (let key in user) { + clone[key] = user[key]; +} +*/!* + + +// এখন ক্লোন হচ্ছে একটি স্বাধীন অবজেক্ট যার কন্টেন্ট ইউজার এর সমান +clone.name = "Pete"; // ডাটা পরিবর্তন করলাম + +alert( user.name ); // মুল অবজেক্ট এ এখনো John +``` + +আমরা এর জন্য [Object.assign](mdn:js/Object/assign) মেথড টিও ব্যাবহার করতে পারি। + +এর সিনট্যাক্স হলো: + +```js +Object.assign(dest, [src1, src2, src3...]) +``` + +- প্রথম আর্গুমেন্ট `dest` হলো টার্গেট অবজেক্ট । +- বাকি আর্গুমেন্ট গুলো `src1, ..., srcN` (যতো প্রয়োজন দেয়া যাবে) হলো মুল অবজেক্ট। +- এটি মুল অবজেক্ট এর সকল প্রপার্টি `src1, ..., srcN` টার্গেট `dest` এ কপি করে। অন্য কথায়, দ্বিতীয় আর্গুমেন্ট থেকে বাকি সকল আর্গুমেন্ট এর প্রপার্টি গুলো প্রথম অবজেক্ট এ কপি হয়। +- এই কল টি `dest` কে রিটার্ন করে। + +আমরা এটি ব্যাবহার করে একাধিক অবজেক্ট এ একটি অবজেক্ট এ মিলিত করতে পারে: +```js +let user = { name: "John" }; + +let permissions1 = { canView: true }; +let permissions2 = { canEdit: true }; + +*!* +// copies all properties from permissions1 and permissions2 into user +Object.assign(user, permissions1, permissions2); +*/!* + +// now user = { name: "John", canView: true, canEdit: true } +``` + +কপি করা প্রপার্টি যদি ইতিমধ্যেই থেকে থাকে থাকলে এটি ওভাররাইট হয়ে যাবে: + +```js run +let user = { name: "John" }; + +Object.assign(user, { name: "Pete" }); + +alert(user.name); // now user = { name: "Pete" } +``` + +আমরা `for..in` এর জায়গায় `Object.assign` ব্যাবহার করে সাধারণ ক্লোনিং করতে পারি : + +```js +let user = { + name: "John", + age: 30 +}; + +*!* +let clone = Object.assign({}, user); +*/!* +``` + +এটি `user` এর সকল প্রপার্টি কে খালি অবজেক্ট এ কপি করে তাকে রিটার্ন করে । + +## অভ্যন্তরীণ ক্লোনিং (Nested cloning) + +এতখ্যন পর্জন্ত আমরা ধরে নিয়েছিলাম যে `user` এর সকল প্রপার্টি ই প্রিমিটিভ । কিন্তু প্রপার্টি গুলো তো অন্যান্য অবজেক্ট এর রেফারেন্স ও হতে পারে । সেক্ষেত্রে আমরা কি করবো? + +যেমন: +```js run +let user = { + name: "John", + sizes: { + height: 182, + width: 50 + } +}; + +alert( user.sizes.height ); // 182 +``` + +এখন এটি `clone.sizes = user.sizes` কে কপি করার জন্য যথেষ্ট নয়, কারণ `user.sizes` হলো একটি অবজেক্ট, এটি রেফারেন্সের মাধ্যমে কপি হবে। সুতরাং `clone` ও `user` একই size শেয়ার করবে: + +এমন: + +```js run +let user = { + name: "John", + sizes: { + height: 182, + width: 50 + } +}; + +let clone = Object.assign({}, user); + +alert( user.sizes === clone.sizes ); // true, একই অবজেক্ট + +// user এবং clone size কে শেয়ার করে +user.sizes.width++; // একটি জায়গা থেকে প্রপার্টি পরিবর্তন +alert(clone.sizes.width); // 51, অন্য জায়গায় রেসাল্ট দেখা +``` + +এটি সমাধান করার জন্য আমাদের একটি ক্লোনিং লুপ ব্যাবহার করা লাগবে যা `user[key]` এর প্রত্যেক মান কে প্রিক্ষা করবে, এবং যদি এটি অবজেক্ট হয়, তাহলে এর স্ট্রাকচার কেও কপি করবে। একে বলে "ডিপ ক্লোনিং". + +আমরা রিকার্সন ব্যাবহার করে এটি তৈরি করতে পারি অথবা ইতিমধ্যেই বাস্তবায়িত একটি ব্যাবহার করতে পারি, যেমন [lodash](https://lodash.com) এর [_.cloneDeep(obj)](https://lodash.com/docs#cloneDeep) ফাংশন। + +## সংক্ষিপ্ত + +অবজেক্ট গুলো রেফারেন্স এর মাধ্যমে কপি হয়। অন্য কথায়, একটি ভেরিয়েবল অবজেক্ট এর মান সংরক্ষণ করে না , বরং একটি রেফারেন্স (মেমোরি এড্রেস) সংরক্ষণ করে। সুতরাং এই ধরনের ভেরিয়েবল কে কপি করলে অবজেক্ট কপি হয় না বরং রেফারেন্স কপি হয়। + +রেফারেন্সে এর মাধ্যমে করে সকল কাজ (যেমন প্রপার্টি যোগ করা/মোছা) একই অবজেক্ট এ সম্পাদিত হয়। + +একটি "আসল কপি" (ক্লোন) তৈরি করতে আমরা ব্যাবহার করতে পারি `Object.assign` যাকে "শ্যালো কপি"(অভ্যন্তরীণ অবজেক্ট রেফারেন্সের মাধ্যমে কপি হয়) বলা হয় অথবা আমরা ব্যাবহার করতে পারি [_.cloneDeep(obj)](https://lodash.com/docs#cloneDeep) এর মত "ডিপ ক্লোনিং" ফাংশন। diff --git a/1-js/04-object-basics/02-object-copy/variable-contains-reference.svg b/1-js/04-object-basics/02-object-copy/variable-contains-reference.svg new file mode 100644 index 000000000..a5f057178 --- /dev/null +++ b/1-js/04-object-basics/02-object-copy/variable-contains-reference.svg @@ -0,0 +1 @@ +username diff --git a/1-js/04-object-basics/02-object-copy/variable-copy-reference.svg b/1-js/04-object-basics/02-object-copy/variable-copy-reference.svg new file mode 100644 index 000000000..18f80c2f2 --- /dev/null +++ b/1-js/04-object-basics/02-object-copy/variable-copy-reference.svg @@ -0,0 +1,2 @@ +useradminname + diff --git a/1-js/04-object-basics/02-object-copy/variable-copy-value.svg b/1-js/04-object-basics/02-object-copy/variable-copy-value.svg new file mode 100644 index 000000000..7435bb13f --- /dev/null +++ b/1-js/04-object-basics/02-object-copy/variable-copy-value.svg @@ -0,0 +1,3 @@ + +"Hello!"message"Hello!"phrase + diff --git a/1-js/04-object-basics/05-constructor-new/1-two-functions-one-object/solution.md b/1-js/04-object-basics/06-constructor-new/1-two-functions-one-object/solution.md similarity index 100% rename from 1-js/04-object-basics/05-constructor-new/1-two-functions-one-object/solution.md rename to 1-js/04-object-basics/06-constructor-new/1-two-functions-one-object/solution.md diff --git a/1-js/04-object-basics/05-constructor-new/1-two-functions-one-object/task.md b/1-js/04-object-basics/06-constructor-new/1-two-functions-one-object/task.md similarity index 100% rename from 1-js/04-object-basics/05-constructor-new/1-two-functions-one-object/task.md rename to 1-js/04-object-basics/06-constructor-new/1-two-functions-one-object/task.md diff --git a/1-js/04-object-basics/05-constructor-new/2-calculator-constructor/_js.view/solution.js b/1-js/04-object-basics/06-constructor-new/2-calculator-constructor/_js.view/solution.js similarity index 100% rename from 1-js/04-object-basics/05-constructor-new/2-calculator-constructor/_js.view/solution.js rename to 1-js/04-object-basics/06-constructor-new/2-calculator-constructor/_js.view/solution.js diff --git a/1-js/04-object-basics/05-constructor-new/2-calculator-constructor/_js.view/test.js b/1-js/04-object-basics/06-constructor-new/2-calculator-constructor/_js.view/test.js similarity index 100% rename from 1-js/04-object-basics/05-constructor-new/2-calculator-constructor/_js.view/test.js rename to 1-js/04-object-basics/06-constructor-new/2-calculator-constructor/_js.view/test.js diff --git a/1-js/04-object-basics/05-constructor-new/2-calculator-constructor/solution.md b/1-js/04-object-basics/06-constructor-new/2-calculator-constructor/solution.md similarity index 100% rename from 1-js/04-object-basics/05-constructor-new/2-calculator-constructor/solution.md rename to 1-js/04-object-basics/06-constructor-new/2-calculator-constructor/solution.md diff --git a/1-js/04-object-basics/05-constructor-new/2-calculator-constructor/task.md b/1-js/04-object-basics/06-constructor-new/2-calculator-constructor/task.md similarity index 100% rename from 1-js/04-object-basics/05-constructor-new/2-calculator-constructor/task.md rename to 1-js/04-object-basics/06-constructor-new/2-calculator-constructor/task.md diff --git a/1-js/04-object-basics/05-constructor-new/3-accumulator/_js.view/solution.js b/1-js/04-object-basics/06-constructor-new/3-accumulator/_js.view/solution.js similarity index 100% rename from 1-js/04-object-basics/05-constructor-new/3-accumulator/_js.view/solution.js rename to 1-js/04-object-basics/06-constructor-new/3-accumulator/_js.view/solution.js diff --git a/1-js/04-object-basics/05-constructor-new/3-accumulator/_js.view/test.js b/1-js/04-object-basics/06-constructor-new/3-accumulator/_js.view/test.js similarity index 100% rename from 1-js/04-object-basics/05-constructor-new/3-accumulator/_js.view/test.js rename to 1-js/04-object-basics/06-constructor-new/3-accumulator/_js.view/test.js diff --git a/1-js/04-object-basics/05-constructor-new/3-accumulator/solution.md b/1-js/04-object-basics/06-constructor-new/3-accumulator/solution.md similarity index 100% rename from 1-js/04-object-basics/05-constructor-new/3-accumulator/solution.md rename to 1-js/04-object-basics/06-constructor-new/3-accumulator/solution.md diff --git a/1-js/04-object-basics/05-constructor-new/3-accumulator/task.md b/1-js/04-object-basics/06-constructor-new/3-accumulator/task.md similarity index 100% rename from 1-js/04-object-basics/05-constructor-new/3-accumulator/task.md rename to 1-js/04-object-basics/06-constructor-new/3-accumulator/task.md diff --git a/1-js/04-object-basics/05-constructor-new/article.md b/1-js/04-object-basics/06-constructor-new/article.md similarity index 100% rename from 1-js/04-object-basics/05-constructor-new/article.md rename to 1-js/04-object-basics/06-constructor-new/article.md diff --git a/1-js/04-object-basics/07-symbol/article.md b/1-js/04-object-basics/08-symbol/article.md similarity index 100% rename from 1-js/04-object-basics/07-symbol/article.md rename to 1-js/04-object-basics/08-symbol/article.md diff --git a/1-js/04-object-basics/08-object-toprimitive/article.md b/1-js/04-object-basics/09-object-toprimitive/article.md similarity index 100% rename from 1-js/04-object-basics/08-object-toprimitive/article.md rename to 1-js/04-object-basics/09-object-toprimitive/article.md From 60c958c73a0bb64ffda0884778c5658e1f933b05 Mon Sep 17 00:00:00 2001 From: Muhib Al Hasan <37745982+tahnoonn@users.noreply.github.com> Date: Thu, 8 Oct 2020 00:29:58 +0600 Subject: [PATCH 2/4] Update article.md Minor typo fixes. --- .../02-object-copy/article.md | 35 +++++++++---------- 1 file changed, 17 insertions(+), 18 deletions(-) diff --git a/1-js/04-object-basics/02-object-copy/article.md b/1-js/04-object-basics/02-object-copy/article.md index 0d4c5c98d..38e5b675c 100644 --- a/1-js/04-object-basics/02-object-copy/article.md +++ b/1-js/04-object-basics/02-object-copy/article.md @@ -12,14 +12,13 @@ let message = "Hello!"; let phrase = message; ``` -As a result we have two independent variables, each one is storing the string `"Hello!"`. এর ফলে আমরা দুটি স্বাধীন ভেরিয়েবল আছে, প্রতিটি "হেলো" স্ট্রিংটি সংরক্ষণ করছে । ![](variable-copy-value.svg) অবজেক্ট রা এমন নয়। -** একটি ভেরিএবল অবজেক্ট কে সংরক্ষণ করে না, বরং এর ঠিকানা সংরক্ষণ করে, অন্য কথায় এটির একটি "রেফারেন্স" * +** একটি ভেরিএবল অবজেক্ট কে সংরক্ষণ করে না, বরং এর ঠিকানা সংরক্ষণ করে, অন্য কথায় এটির একটি "রেফারেন্স" ** অবজেক্ট এর ছবিঃ @@ -33,21 +32,21 @@ let user = { এখানে, বস্তুটি মেমোরির কোথাও সংরক্ষণ করা হয়েছে। এবং ভেরিয়েবল `user` এর কাছে এর রেফারেন্স আছে। -** যখন কোনও বস্তুর ভেরিয়েবল কপি করা হয় - রেফারেন্সটি কপি হয়, বস্তুটি নকল হয় না * ** +** যখন কোনও বস্তুর ভেরিয়েবল কপি করা হয় - রেফারেন্সটি কপি হয়, বস্তুটি নকল হয় না । ** যেমন : ```js no-beautify let user = { name: "John" }; -let admin = user; // রেফারেন্স করই হলো +let admin = user; // রেফারেন্স কপি হলো ``` এখন আমাদের দুটি ভেরিয়েবল রয়েছে, প্রত্যেকেই একই বস্তুর রেফারেন্স: ![](variable-copy-reference.svg) -আমরা এই দুটি ভেরিএবল এর যেকোনো টি ব্যাবহার করে অবজেক্ট টি এক্সেস করতে পারি ও এর ভেতরের কন্টেন্ট বা ডেটা গুলি পরিবর্তন করতে পারি। +আমরা এই দুটি ভেরিয়েবল এর যেকোনো টি ব্যাবহার করে অবজেক্ট টি এক্সেস করতে পারি ও এর ভেতরের কন্টেন্ট বা ডেটা গুলি পরিবর্তন করতে পারি। ```js run let user = { name: 'John' }; @@ -55,13 +54,13 @@ let user = { name: 'John' }; let admin = user; *!* -admin.name = 'Pete'; // এডমিন রেফারেন্সে এর মাদ্ধ্যমে পরিবর্তন হোল +admin.name = 'Pete'; // এডমিন রেফারেন্সের এর মাধ্যমে পরিবর্তন হলো */!* -alert(*!*user.name*/!*); // 'Pete', changes are seen from the "user" reference +alert(*!*user.name*/!*); // 'Pete', পরিবর্তন টি "user" রেফারেন্স থেকে দেখা যাচ্ছে ``` -উপরের উদাহরণটি প্রমাণ করে যে এখানে কেবল একটি অবজেক্ট রয়েছে।যেন আমাদের একি কক্ষের দুটি চাবি আছে আর আমরা একটি চাবি (`admin`) দিয়ে কক্ষে প্রবেশ করেছি ও অন্যটি (`user`) দিয়ে কক্ষের ভেতরে উকি দিয়েছি। +উপরের উদাহরণটি প্রমাণ করে যে এখানে কেবল একটি অবজেক্ট রয়েছে। যেন আমাদের একি কক্ষের দুটি চাবি আছে আর আমরা একটি চাবি (`admin`) দিয়ে কক্ষে প্রবেশ করেছি ও অন্যটি (`user`) দিয়ে কক্ষের ভেতরে উকি দিয়েছি। ## রেফারেন্স এর মাধ্যমে তুলনা @@ -88,7 +87,7 @@ let b = {}; // দুটি স্বাধীন অবজেক্ট alert( a == b ); // false ``` -`obj1 > obj2` এর মত তুলনা এর জন্য or অথবা কোন প্রিমিটিভ এর সাথে তুলনা করার জন্য `obj == 5`, অবজেক্ট কে প্রিমিটিভ এ রূপান্তর করা হয়। অবজেক্ট গুলোকে কিভাবে তুলনা করা হয় তা সম্পর্কে আমরা শিগ্রই জানব, কিন্তু সত্যি বলতে এই ধরনের তুলনা খুব কমি করা হয়, সাধারণত ভুলক্রমে। +`obj1 > obj2` এর মত তুলনা এর জন্য অথবা কোন প্রিমিটিভ এর সাথে তুলনা করার জন্য `obj == 5`, অবজেক্ট কে প্রিমিটিভ এ রূপান্তর করা হয়। অবজেক্ট গুলোকে কিভাবে তুলনা করা হয় তা সম্পর্কে আমরা শিগ্রই জানব, কিন্তু সত্যি বলতে এই ধরনের তুলনা খুব কমই করা হয়, সাধারণত ভুলক্রমে। ## ক্লোন করা ও মিলিত করা, Object.assign @@ -99,7 +98,7 @@ alert( a == b ); // false তাও সম্ভব কিন্তু একটু কঠিন, কারণ এই কাজ করার জন্য জাভাস্ক্রিপ্ট এর কোন অন্তর্নির্মিত মেথড নেই। আসলে এটি খুব কমই প্রয়োজন হয়। রেফারেন্সে কপি করাই বেশিরভাগ সময় যথেষ্ট। -কিন্তু আমরা যদি আসলেই এটি চাই তাহলে আমাদের নতুন একটি অবজেক্ট বানাতে হবে, ও মুল অবজেক্ট তির সম্পূর্ণ কাঠামো কে নকল করে এর সকল প্রপার্টির প্রিমিটিভ স্তরে প্রতিলিতি তৈরি করতে হবে। +কিন্তু আমরা যদি আসলেই এটি চাই তাহলে আমাদের নতুন একটি অবজেক্ট বানাতে হবে, ও মুল অবজেক্ট টির সম্পূর্ণ কাঠামো কে নকল করে এর সকল প্রপার্টির প্রিমিটিভ স্তরে প্রতিলিতি তৈরি করতে হবে। যেমন: @@ -138,7 +137,7 @@ Object.assign(dest, [src1, src2, src3...]) - এটি মুল অবজেক্ট এর সকল প্রপার্টি `src1, ..., srcN` টার্গেট `dest` এ কপি করে। অন্য কথায়, দ্বিতীয় আর্গুমেন্ট থেকে বাকি সকল আর্গুমেন্ট এর প্রপার্টি গুলো প্রথম অবজেক্ট এ কপি হয়। - এই কল টি `dest` কে রিটার্ন করে। -আমরা এটি ব্যাবহার করে একাধিক অবজেক্ট এ একটি অবজেক্ট এ মিলিত করতে পারে: +আমরা এটি ব্যাবহার করে একাধিক অবজেক্টকে একটি অবজেক্ট এ মিলিত করতে পারি: ```js let user = { name: "John" }; @@ -146,11 +145,11 @@ 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 } ``` কপি করা প্রপার্টি যদি ইতিমধ্যেই থেকে থাকে থাকলে এটি ওভাররাইট হয়ে যাবে: @@ -160,7 +159,7 @@ let user = { name: "John" }; Object.assign(user, { name: "Pete" }); -alert(user.name); // now user = { name: "Pete" } +alert(user.name); // এখন user = { name: "Pete" } ``` আমরা `for..in` এর জায়গায় `Object.assign` ব্যাবহার করে সাধারণ ক্লোনিং করতে পারি : @@ -180,7 +179,7 @@ let clone = Object.assign({}, user); ## অভ্যন্তরীণ ক্লোনিং (Nested cloning) -এতখ্যন পর্জন্ত আমরা ধরে নিয়েছিলাম যে `user` এর সকল প্রপার্টি ই প্রিমিটিভ । কিন্তু প্রপার্টি গুলো তো অন্যান্য অবজেক্ট এর রেফারেন্স ও হতে পারে । সেক্ষেত্রে আমরা কি করবো? +এতক্ষণ পর্যন্ত আমরা ধরে নিয়েছিলাম যে `user` এর সকল প্রপার্টি ই প্রিমিটিভ । কিন্তু প্রপার্টি গুলো তো অন্যান্য অবজেক্ট এর রেফারেন্স ও হতে পারে । সেক্ষেত্রে আমরা কি করবো? যেমন: ```js run @@ -217,7 +216,7 @@ user.sizes.width++; // একটি জায়গা থেকে প্র alert(clone.sizes.width); // 51, অন্য জায়গায় রেসাল্ট দেখা ``` -এটি সমাধান করার জন্য আমাদের একটি ক্লোনিং লুপ ব্যাবহার করা লাগবে যা `user[key]` এর প্রত্যেক মান কে প্রিক্ষা করবে, এবং যদি এটি অবজেক্ট হয়, তাহলে এর স্ট্রাকচার কেও কপি করবে। একে বলে "ডিপ ক্লোনিং". +এটি সমাধান করার জন্য আমাদের একটি ক্লোনিং লুপ ব্যাবহার করা লাগবে যা `user[key]` এর প্রত্যেক মান কে পরীক্ষা করবে, এবং যদি এটি অবজেক্ট হয়, তাহলে এর স্ট্রাকচার কেও কপি করবে। একে বলে "ডিপ ক্লোনিং"। আমরা রিকার্সন ব্যাবহার করে এটি তৈরি করতে পারি অথবা ইতিমধ্যেই বাস্তবায়িত একটি ব্যাবহার করতে পারি, যেমন [lodash](https://lodash.com) এর [_.cloneDeep(obj)](https://lodash.com/docs#cloneDeep) ফাংশন। @@ -225,6 +224,6 @@ alert(clone.sizes.width); // 51, অন্য জায়গায় রেসাল অবজেক্ট গুলো রেফারেন্স এর মাধ্যমে কপি হয়। অন্য কথায়, একটি ভেরিয়েবল অবজেক্ট এর মান সংরক্ষণ করে না , বরং একটি রেফারেন্স (মেমোরি এড্রেস) সংরক্ষণ করে। সুতরাং এই ধরনের ভেরিয়েবল কে কপি করলে অবজেক্ট কপি হয় না বরং রেফারেন্স কপি হয়। -রেফারেন্সে এর মাধ্যমে করে সকল কাজ (যেমন প্রপার্টি যোগ করা/মোছা) একই অবজেক্ট এ সম্পাদিত হয়। +কপি করা রেফারেন্সে এর মাধ্যমে করে সকল কাজ (যেমন প্রপার্টি যোগ করা/মোছা) একই অবজেক্ট এ সম্পাদিত হয়। -একটি "আসল কপি" (ক্লোন) তৈরি করতে আমরা ব্যাবহার করতে পারি `Object.assign` যাকে "শ্যালো কপি"(অভ্যন্তরীণ অবজেক্ট রেফারেন্সের মাধ্যমে কপি হয়) বলা হয় অথবা আমরা ব্যাবহার করতে পারি [_.cloneDeep(obj)](https://lodash.com/docs#cloneDeep) এর মত "ডিপ ক্লোনিং" ফাংশন। +একটি "বাস্তব কপি" (ক্লোন) তৈরি করতে আমরা ব্যাবহার করতে পারি `Object.assign` যাকে "শ্যালো কপি"(অভ্যন্তরীণ অবজেক্ট রেফারেন্সের মাধ্যমে কপি হয়) বলা হয় অথবা আমরা ব্যাবহার করতে পারি [_.cloneDeep(obj)](https://lodash.com/docs#cloneDeep) এর মত "ডিপ ক্লোনিং" ফাংশন। From 8ab1e4871aadcd746e68c6a4f030104272e790d5 Mon Sep 17 00:00:00 2001 From: Muhib Al Hasan <37745982+tahnoonn@users.noreply.github.com> Date: Thu, 8 Oct 2020 00:37:06 +0600 Subject: [PATCH 3/4] Update article.md even more minor fixes --- 1-js/04-object-basics/02-object-copy/article.md | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/1-js/04-object-basics/02-object-copy/article.md b/1-js/04-object-basics/02-object-copy/article.md index 38e5b675c..4eb1556b5 100644 --- a/1-js/04-object-basics/02-object-copy/article.md +++ b/1-js/04-object-basics/02-object-copy/article.md @@ -1,4 +1,4 @@ -# অবজেক্ট কপি করা, রেফেরেন্স +# অবজেক্ট কপি করা, রেফারেন্স অবজেক্ট এবং প্রিমিটিভ দের মধ্যে অন্যতম পার্থক্য হলো যে অবজেক্ট গুলি কপি ও সংরখ্যন হয় রেফারেন্স এর মাধ্যমে । @@ -18,7 +18,7 @@ let phrase = message; অবজেক্ট রা এমন নয়। -** একটি ভেরিএবল অবজেক্ট কে সংরক্ষণ করে না, বরং এর ঠিকানা সংরক্ষণ করে, অন্য কথায় এটির একটি "রেফারেন্স" ** +**একটি ভেরিএবল অবজেক্ট কে সংরক্ষণ করে না, বরং এর ঠিকানা সংরক্ষণ করে, অন্য কথায় এটির একটি "রেফারেন্স"।** অবজেক্ট এর ছবিঃ @@ -32,7 +32,7 @@ let user = { এখানে, বস্তুটি মেমোরির কোথাও সংরক্ষণ করা হয়েছে। এবং ভেরিয়েবল `user` এর কাছে এর রেফারেন্স আছে। -** যখন কোনও বস্তুর ভেরিয়েবল কপি করা হয় - রেফারেন্সটি কপি হয়, বস্তুটি নকল হয় না । ** +**যখন কোনও বস্তুর ভেরিয়েবল কপি করা হয় - রেফারেন্সটি কপি হয়, বস্তুটি নকল হয় না ।** যেমন : @@ -66,7 +66,7 @@ alert(*!*user.name*/!*); // 'Pete', পরিবর্তন টি "user" র ইকুয়ালিটি `==` ও স্ট্রিক্ট ইকুয়ালিটি `===` দুটোই অবজেক্টের ক্ষেত্রে সমানভাবে কাজ করে। -**যদি দুটি অবজেক্ট একই বস্তু হয়, শুধুমাত্র তাহলেই তারা "ইকুয়াল" ** +**যদি দুটি অবজেক্ট একই বস্তু হয়, শুধুমাত্র তাহলেই তারা "ইকুয়াল"।** এখানে দুইটি ভেরিএবল একই অবজেক্ট কে রেফারেন্স করে, সুতরাং তারা ইকুয়াল: @@ -93,7 +93,7 @@ alert( a == b ); // false তো আমরা জানলাম অবজেক্ট ভেরিএবল কে কপি করলে তা শুধু একটি নতুন রেফারেন্স তৈরি করে। -কিন্তু আমাদের যদি অবজেক্ট এর স্বাধীন নকল বা ক্লোন তৈরি করতে হয় তাহলে আমরা কই করব? +কিন্তু আমাদের যদি অবজেক্ট এর স্বাধীন নকল বা ক্লোন তৈরি করতে হয় তাহলে আমরা কি করব? তাও সম্ভব কিন্তু একটু কঠিন, কারণ এই কাজ করার জন্য জাভাস্ক্রিপ্ট এর কোন অন্তর্নির্মিত মেথড নেই। আসলে এটি খুব কমই প্রয়োজন হয়। রেফারেন্সে কপি করাই বেশিরভাগ সময় যথেষ্ট। From 1935ff03724aefd8943edd371453dc6f1119ce46 Mon Sep 17 00:00:00 2001 From: Muhib Al Hasan <37745982+tahnoonn@users.noreply.github.com> Date: Thu, 22 Oct 2020 21:59:25 +0600 Subject: [PATCH 4/4] minor fixes because the original english article got updated. --- .../02-object-copy/article.md | 40 ++++++++++++------- 1 file changed, 26 insertions(+), 14 deletions(-) diff --git a/1-js/04-object-basics/02-object-copy/article.md b/1-js/04-object-basics/02-object-copy/article.md index 4eb1556b5..3561b2231 100644 --- a/1-js/04-object-basics/02-object-copy/article.md +++ b/1-js/04-object-basics/02-object-copy/article.md @@ -1,11 +1,12 @@ -# অবজেক্ট কপি করা, রেফারেন্স +# অবজেক্ট রেফারেন্স এবং কপি করা -অবজেক্ট এবং প্রিমিটিভ দের মধ্যে অন্যতম পার্থক্য হলো যে অবজেক্ট গুলি কপি ও সংরখ্যন হয় রেফারেন্স এর মাধ্যমে । +অবজেক্ট এবং প্রিমিটিভ দের মধ্যে অন্যতম পার্থক্য হলো যে অবজেক্ট গুলি কপি ও সংরখ্যন হয় রেফারেন্স এর মাধ্যমে, যেখানে প্রিমিটিভ মানঃ স্ট্রিং, বুলিয়ান, ইত্যাদি -- যেগুলো সবসময় "সম্পুর্ন মান" হিসেবে কপি হয়। +একটি মান কপি করলে কি হয় তা একটু গভীরভাবে দেখলেই আমরা এটি আরো ভালোভাবে বুঝতে পারব। -প্রিমিটিভ মান: স্ট্রিং, সংখ্যা, বুলিয়ানস - "সম্পূর্ণ মান হিসাবে" এসাইন/কপি করা হয়। +স্ট্রিং এর মত একটি প্রিমিটিভ নিয়েই শুরু করা যাক। -যেমন: +এখানে আমরা `message` এর একটি কপি কে `phrase` এ রাখলামঃ ```js let message = "Hello!"; @@ -16,11 +17,13 @@ let phrase = message; ![](variable-copy-value.svg) +খুব স্বাবাভিক ই মনে হচ্ছে, তাই না? + অবজেক্ট রা এমন নয়। -**একটি ভেরিএবল অবজেক্ট কে সংরক্ষণ করে না, বরং এর ঠিকানা সংরক্ষণ করে, অন্য কথায় এটির একটি "রেফারেন্স"।** +**একটি অবজেক্ট এর জন্য নির্ধারিত ভেরিয়েবল সেই অবজেক্ট কে সংরক্ষণ করে না, বরং এর ঠিকানা সংরক্ষণ করে, অন্য কথায় এটির একটি "রেফারেন্স"।** -অবজেক্ট এর ছবিঃ +এমন একটি ভেরিয়েবল এর উদাহরণ দেখা যাকঃ ```js let user = { @@ -28,9 +31,17 @@ let user = { }; ``` +এটি স্মৃতি তে কিভাবে সংরক্ষণ করা হয় তা নিচের ছবিতে দেখানো হলোঃ + ![](variable-contains-reference.svg) -এখানে, বস্তুটি মেমোরির কোথাও সংরক্ষণ করা হয়েছে। এবং ভেরিয়েবল `user` এর কাছে এর রেফারেন্স আছে। +অবজেক্ট টি স্মৃতির কোথাও সংরক্ষণ করা আছে (ডানে), আর `user` ভেরিয়েবল এর কাছে এর একটি রেফারেন্স আছে। + +আমরা `user` এর মতো অবজেক্ট কে একটি কাগজের টুকরো হিসেবে ভাবতে পারি, যাতে ঠিকানা লেখা আছে । + +যখন আমরা অবজেক্ট এর উপরে কোন কাজ করি, যেমন `user.name` প্রপার্টি কে নেয়া, জাভাস্ক্রিপ্ট ইঞ্জিন ঠিকানা থেকে অবজেক্ট টি বের তার উপরে কাজ টি সম্পাদন করে । + +এটি গুরুতপুর্ন কারণ **যখন কোনও বস্তুর ভেরিয়েবল কপি করা হয় - রেফারেন্সটি কপি হয়, বস্তুটি নকল হয় না ।** @@ -46,6 +57,8 @@ let admin = user; // রেফারেন্স কপি হলো ![](variable-copy-reference.svg) +আমরা দেখতে পাচ্ছি যে, অবজেক্ট একটাই আছে কিন্তু এখন একে দুটি ভেরিয়েবল রেফারেন্স করছে । + আমরা এই দুটি ভেরিয়েবল এর যেকোনো টি ব্যাবহার করে অবজেক্ট টি এক্সেস করতে পারি ও এর ভেতরের কন্টেন্ট বা ডেটা গুলি পরিবর্তন করতে পারি। ```js run @@ -60,15 +73,14 @@ admin.name = 'Pete'; // এডমিন রেফারেন্সের এর alert(*!*user.name*/!*); // 'Pete', পরিবর্তন টি "user" রেফারেন্স থেকে দেখা যাচ্ছে ``` -উপরের উদাহরণটি প্রমাণ করে যে এখানে কেবল একটি অবজেক্ট রয়েছে। যেন আমাদের একি কক্ষের দুটি চাবি আছে আর আমরা একটি চাবি (`admin`) দিয়ে কক্ষে প্রবেশ করেছি ও অন্যটি (`user`) দিয়ে কক্ষের ভেতরে উকি দিয়েছি। -## রেফারেন্স এর মাধ্যমে তুলনা +উপরের উদাহরণটি প্রমাণ করে যে এখানে কেবল একটি অবজেক্ট রয়েছে। যেন আমাদের একি কক্ষের দুটি চাবি আছে আর আমরা একটি চাবি (`admin`) দিয়ে কক্ষে প্রবেশ করেছি। পরে অন্যটি (`user`) দিয়ে কক্ষের ভেতরে দেখেছি। -ইকুয়ালিটি `==` ও স্ট্রিক্ট ইকুয়ালিটি `===` দুটোই অবজেক্টের ক্ষেত্রে সমানভাবে কাজ করে। +## রেফারেন্স এর মাধ্যমে তুলনা -**যদি দুটি অবজেক্ট একই বস্তু হয়, শুধুমাত্র তাহলেই তারা "ইকুয়াল"।** +যদি দুটি অবজেক্ট একই বস্তু হয়, শুধুমাত্র তাহলেই তারা "ইকুয়াল"। -এখানে দুইটি ভেরিএবল একই অবজেক্ট কে রেফারেন্স করে, সুতরাং তারা ইকুয়াল: +যেমন, এখানে `a` এবং `b` একই অবজেক্ট কে রেফারেন্স করে, সুতরাং তারা ইকুয়াল: ```js run let a = {}; @@ -78,7 +90,7 @@ alert( a == b ); // true, দুটি অবজেক্ট ই সমান alert( a === b ); // true ``` -আর এখানে দুটি অবজেক্ট সমান নয়, যদিও তারা দুজনই খালি : +আর এখানে দুটি অবজেক্ট সমান নয়, যদিও তারা দেখতে একই (দুজনই খালি) : ```js run let a = {}; @@ -87,7 +99,7 @@ let b = {}; // দুটি স্বাধীন অবজেক্ট alert( a == b ); // false ``` -`obj1 > obj2` এর মত তুলনা এর জন্য অথবা কোন প্রিমিটিভ এর সাথে তুলনা করার জন্য `obj == 5`, অবজেক্ট কে প্রিমিটিভ এ রূপান্তর করা হয়। অবজেক্ট গুলোকে কিভাবে তুলনা করা হয় তা সম্পর্কে আমরা শিগ্রই জানব, কিন্তু সত্যি বলতে এই ধরনের তুলনা খুব কমই করা হয়, সাধারণত ভুলক্রমে। +`obj1 > obj2` এর মত তুলনা এর জন্য অথবা কোন প্রিমিটিভ এর সাথে তুলনা করার জন্য `obj == 5`, অবজেক্ট কে প্রিমিটিভ এ রূপান্তর করা হয়। অবজেক্ট গুলোকে কিভাবে তুলনা করা হয় তা সম্পর্কে আমরা শিগ্রই জানব, কিন্তু সত্যি বলতে এই ধরনের তুলনা খুব কমই প্রয়োজন হয়, সাধারণত এগুলি ভুলক্রমে চলে আসে। ## ক্লোন করা ও মিলিত করা, Object.assign