diff --git a/1-js/07-object-properties/01-property-descriptors/article.md b/1-js/07-object-properties/01-property-descriptors/article.md index f8f8d21d4..4b222c0a8 100644 --- a/1-js/07-object-properties/01-property-descriptors/article.md +++ b/1-js/07-object-properties/01-property-descriptors/article.md @@ -1,40 +1,40 @@ -# Property flags and descriptors +# প্রপার্টি ফ্ল্যাগ এবং ডেস্ক্রিপ্টর -As we know, objects can store properties. +আমরা জানি, অবজেক্টে প্রপার্টি এবং ভ্যালু থাকে। -Until now, a property was a simple "key-value" pair to us. But an object property is actually a more flexible and powerful thing. +পূর্বের অধ্যায়গুলোতে আমরা শিখেছি প্রপার্টি হল "key-value" এর একটি জোড়া। তবে জাভাস্ক্রিপ্ট প্রপার্টি আরো বেশি ফ্লেক্সিবল এবং শক্তিশালী। -In this chapter we'll study additional configuration options, and in the next we'll see how to invisibly turn them into getter/setter functions. +এই অধ্যায়ের এই অনুচ্ছেদে আমরা প্রপার্টির কনফিগারেশন সম্পর্কে জানব, পরবর্তী অধ্যায়ে getter/setter ফাংশন নিয়ে জানব। -## Property flags +## প্রপার্টি ফ্ল্যাগ -Object properties, besides a **`value`**, have three special attributes (so-called "flags"): +অবজেক্ট প্রপার্টিতে **`value`** এর পাশাপাশি আরো তিনটি বিশেষ অ্যাট্রিবিউট আছে এদের বলা হয় ফ্ল্যাগ: -- **`writable`** -- if `true`, the value can be changed, otherwise it's read-only. -- **`enumerable`** -- if `true`, then listed in loops, otherwise not listed. -- **`configurable`** -- if `true`, the property can be deleted and these attributes can be modified, otherwise not. +- **`writable`** -- `true` হলে ভ্যালু পরিবর্তন করা যেতে পারে, অন্যথায় এটি শুধুমাত্র রিড-অনলি। +- **`enumerable`** -- `true` হলে এটি লুপের মধ্যে দেখাবে অন্যথায় লুপে প্রপার্টিটি দেখাবে না। +- **`configurable`** -- `true` হলে প্রপার্টি পরিবর্তন বা ডিলিট করা যায়, অন্যথায় করা যাবে না। -We didn't see them yet, because generally they do not show up. When we create a property "the usual way", all of them are `true`. But we also can change them anytime. +এইসব আমরা এখনো দেখিনি, কেননা সাধারণ নিয়মে কোন প্রপার্টি তৈরি করার সময় এদের প্রয়োজন হয় না, এরা ডিফল্ট `true` থাকে। তবে আমরা এদের পরিবর্তন করতে পারি। -First, let's see how to get those flags. +প্রথমত, চলুন কোন প্রপার্টির ফ্ল্যাগ কীভাবে দেখা যায় তা দেখি। -The method [Object.getOwnPropertyDescriptor](mdn:js/Object/getOwnPropertyDescriptor) allows to query the *full* information about a property. +এই মেথডটি কোন একটি প্রপার্টির সকল তথ্য দেখাবে [Object.getOwnPropertyDescriptor](mdn:js/Object/getOwnPropertyDescriptor)। -The syntax is: +লিখার নিয়ম: ```js let descriptor = Object.getOwnPropertyDescriptor(obj, propertyName); ``` `obj` -: The object to get information from. +: যে অবজেক্ট এর প্রপার্টির মান জানতে চাই `propertyName` -: The name of the property. +: প্রপার্টির নাম -The returned value is a so-called "property descriptor" object: it contains the value and all the flags. +রিটার্নকৃত মানকে বলা হয় "প্রপার্টি ডেস্ক্রিপ্টর"। এটি ঐ প্রপার্টির মান এবং ফ্ল্যাগগুলো দেখাবে। -For instance: +যেমন: ```js run let user = { @@ -54,23 +54,23 @@ alert( JSON.stringify(descriptor, null, 2 ) ); */ ``` -To change the flags, we can use [Object.defineProperty](mdn:js/Object/defineProperty). +নিজস্ব ফ্ল্যাগ সেট করতে ব্যবহার করি [Object.defineProperty](mdn:js/Object/defineProperty)। -The syntax is: +সিনট্যাক্স হল: ```js Object.defineProperty(obj, propertyName, descriptor) ``` `obj`, `propertyName` -: The object and its property to apply the descriptor. +: অবজেক্ট এবং প্রপার্টির নাম `descriptor` -: Property descriptor object to apply. +: প্রপার্টি ডেস্ক্রিপ্টর একটি অবজেক্ট নেই। -If the property exists, `defineProperty` updates its flags. Otherwise, it creates the property with the given value and flags; in that case, if a flag is not supplied, it is assumed `false`. +যেটি অবজেক্টে প্রপার্টি ইতোমধ্যে বিদ্যমান থাকে, তাহলে `defineProperty` ফ্ল্যাগ সমূহকে আপডেট করবে। অন্যথায়, এটি ভ্যালু এবং ফ্ল্যাগ অনুযায়ী প্রপার্টি তৈরি করবে, আর যদি ফ্ল্যাগ পাস করা না হয় তাহলে ফ্ল্যাগসমূহের মান `false` ধরে নেই। -For instance, here a property `name` is created with all falsy flags: +যেমন, এখানে `name` প্রপার্টির জন্য ফ্ল্যাগসমূহের মান `false` সেট হবে: ```js run let user = {}; @@ -96,13 +96,13 @@ alert( JSON.stringify(descriptor, null, 2 ) ); */ ``` -Compare it with "normally created" `user.name` above: now all flags are falsy. If that's not what we want then we'd better set them to `true` in `descriptor`. +সাধারণ নিয়মে `user.name` অবজেক্টের প্রপার্টি অ্যাসাইন করা আর উপরেরটির মধ্যে পার্থক্য হল এখানে সকল ফ্ল্যাগ এর মান falsy আর সাধারণ নিয়মে ফ্ল্যাগসমূহের মান `true` সেট হয়। -Now let's see effects of the flags by example. +চলুন আরো কিছু উদাহরণের মাধ্যমে বিস্তারিত দেখি। -## Non-writable +## অপরিবর্তিনীয় -Let's make `user.name` non-writable (can't be reassigned) by changing `writable` flag: +চলুন `user.name` কে আমরা `writable` ফ্ল্যাগের মাধ্যমে কনস্ট্যান্ট হিসেবে সেট করি: ```js run let user = { @@ -120,13 +120,13 @@ user.name = "Pete"; // Error: Cannot assign to read only property 'name' */!* ``` -Now no one can change the name of our user, unless they apply their own `defineProperty` to override ours. +এখন আমাদের `name` প্রপার্টিকে অন্য কোন অপারেশনের মাধ্যমে আর পরিবর্তন করা যাবে না, যতক্ষণ না আমরা `defineProperty` এর মাধ্যমে ফ্ল্যাগটিকে পুনরায় পরিবর্তন করব। -```smart header="Errors appear only in strict mode" -In the non-strict mode, no errors occur when writing to non-writable properties and such. But the operation still won't succeed. Flag-violating actions are just silently ignored in non-strict. +```smart header="শুধুমাত্র strict mode এ এরর দেখাবে" +non-strict mode এ কোন এরর দেখাবে না। তবে আমাদের রি-অ্যাসাইন অপারেশনও এক্সিকিউট হবে না। এক্ষেত্রে ফ্ল্যাগ ভায়োলেট এর এররগুলো শুধু উপেক্ষা করে যাবে। ``` -Here's the same example, but the property is created from scratch: +আগের উদাহরনণটি পুনরায় দেখুন, তবে এখানে প্রপার্টি তৈরি করা হচ্ছে `defineProperty` এর মাধ্যমে: ```js run let user = { }; @@ -134,7 +134,7 @@ let user = { }; Object.defineProperty(user, "name", { *!* value: "John", - // for new properties we need to explicitly list what's true + // আমরা ফ্ল্যাগের মান false এভাবেও সেট করতে পারি। এখানে অন্য দুটি ফ্ল্যাগ true করার মাধ্যমে writable কে false সেট করা হচ্ছে enumerable: true, configurable: true */!* @@ -144,11 +144,11 @@ alert(user.name); // John user.name = "Pete"; // Error ``` -## Non-enumerable +## অগণনাযোগ্য -Now let's add a custom `toString` to `user`. +এখন চলুন `user` এ একটি `toString` মেথড লিখি `toString`। -Normally, a built-in `toString` for objects is non-enumerable, it does not show up in `for..in`. But if we add a `toString` of our own, then by default it shows up in `for..in`, like this: +সাধারণত বিল্ট-ইন অবজেক্টসমূহে `toString` মেথড থাকে, তবে এটি non-enumerable। অর্থাৎ `for..in` লুপে এটি দেখায় না। কিন্তু যদি আমরা আমাদের নিজস্ব অবজেক্টে `toString` লিখি, তাহলে এটি লুপে দেখাবে, যেমন: ```js run let user = { @@ -158,11 +158,11 @@ let user = { } }; -// By default, both our properties are listed: +// ডিফল্টভাবে উভয়ই প্রপার্টির নাম লুপে দেখাবে for (let key in user) alert(key); // name, toString ``` -If we don't like it, then we can set `enumerable:false`. Then it won't appear in a `for..in` loop, just like the built-in one: +যদি আমরা এটি দেখাতে না চাই, তাহলে `enumerable:false` ফ্ল্যাগ সেট করব। তাহলে এটি বিল্ট-ইন অবজেক্টের মত `for..in` লুপে দেখাবে না: ```js run let user = { @@ -179,12 +179,12 @@ Object.defineProperty(user, "toString", { }); *!* -// Now our toString disappears: +// এখন toString এর নাম দেখাবে না: */!* for (let key in user) alert(key); // name ``` -Non-enumerable properties are also excluded from `Object.keys`: +Non-enumerable প্রপার্টি সমূহ `Object.keys` এও লিস্টেড হবে না: ```js alert(Object.keys(user)); // name @@ -192,11 +192,11 @@ alert(Object.keys(user)); // name ## Non-configurable -The non-configurable flag (`configurable:false`) is sometimes preset for built-in objects and properties. +এই non-configurable ফ্ল্যাগটি (`configurable:false`) কিছু বিল্ট-ইন অবজেক্টের প্রপার্টির জন্য সেট করা আছে। -A non-configurable property can not be deleted. +non-configurable ফ্ল্যাগ সেট করা হলে প্রপার্টিটি ডিলিট করা সম্ভব না। -For instance, `Math.PI` is non-writable, non-enumerable and non-configurable: +যেমন, `Math.PI` হল non-writable, non-enumerable এবং non-configurable: ```js run let descriptor = Object.getOwnPropertyDescriptor(Math, 'PI'); @@ -211,25 +211,21 @@ alert( JSON.stringify(descriptor, null, 2 ) ); } */ ``` -So, a programmer is unable to change the value of `Math.PI` or overwrite it. +সুতরাং আপনি চাইলেও `Math.PI` এর মান পরিবর্তন বা ডিলিট করতে পারবেন না। ```js run Math.PI = 3; // Error -// delete Math.PI won't work either +// delete Math.PI এটিও কাজ করবে না ``` -Making a property non-configurable is a one-way road. We cannot change it back with `defineProperty`. +কোন একটি প্রপার্টিকে non-configurable হিসেবে শুধুমাত্র একবার সেট করতে পারবেন। আমরা পুনরায় এটিকে `defineProperty` এর মাধ্যমে পরিবর্তন করতে পারব না। -To be precise, non-configurability imposes several restrictions on `defineProperty`: -1. Can't change `configurable` flag. -2. Can't change `enumerable` flag. -3. Can't change `writable: false` to `true` (the other way round works). -4. Can't change `get/set` for an accessor property (but can assign them if absent). +সুস্পষ্ট ভাবে বলতে গেলে non-configurability এর জন্য `defineProperty` এর মধ্যে কিছু বিধিনিষেধ তৈরি হয়: +1. `configurable`, `enumerable`, `writable` ফ্ল্যাগ কে `false` হতে `true` সেট করা যাবে না। +2. `get/set` দ্বারা পরিবর্তন করা যাবে না। -**The idea of "configurable: false" is to prevent changes of property flags and its deletion, while allowing to change its value.** - -Here `user.name` is non-configurable, but we can still change it (as it's writable): +এখানে `user.name` non-configurable, তবে আমরা চাইলে একে রি-অ্যাসাইন করতে পারি: ```js run let user = { @@ -244,7 +240,7 @@ user.name = "Pete"; // works fine delete user.name; // Error ``` -And here we make `user.name` a "forever sealed" constant: +এবং এখানে আমরা `user.name` কে যদি একেবারে কনস্ট্যান্ট করে দিতে চাই: ```js run let user = { @@ -256,8 +252,8 @@ Object.defineProperty(user, "name", { configurable: false }); -// won't be able to change user.name or its flags -// all this won't work: +// user.name এর ফ্ল্যাগ বা ভ্যালু আর পরিবর্তন করা সম্ভব না +// নিচের কোনটিই কাজ করবে না: user.name = "Pete"; delete user.name; Object.defineProperty(user, "name", { value: "Pete" }); @@ -266,9 +262,9 @@ Object.defineProperty(user, "name", { value: "Pete" }); ## Object.defineProperties -There's a method [Object.defineProperties(obj, descriptors)](mdn:js/Object/defineProperties) that allows to define many properties at once. +আরেকটি মেথড আছে যেটি দ্বারা একবারে একাধিক প্রপার্টি সেট করা যায় [Object.defineProperties(obj, descriptors)](mdn:js/Object/defineProperties)। -The syntax is: +সিনট্যাক্সটি হল: ```js Object.defineProperties(obj, { @@ -278,7 +274,7 @@ Object.defineProperties(obj, { }); ``` -For instance: +যেমন: ```js Object.defineProperties(user, { @@ -288,19 +284,19 @@ Object.defineProperties(user, { }); ``` -So, we can set many properties at once. +সুতরাং আমরা চাইলে একবারে একাধিক প্রপার্টি সেট করতে পারি। ## Object.getOwnPropertyDescriptors -To get all property descriptors at once, we can use the method [Object.getOwnPropertyDescriptors(obj)](mdn:js/Object/getOwnPropertyDescriptors). +অবজেক্টের সকল প্রপার্টির বর্ণনা পেতে আমরা ব্যবহার করতে পারি এই মেথডটি ব্যবহার করে [Object.getOwnPropertyDescriptors(obj)](mdn:js/Object/getOwnPropertyDescriptors)। -Together with `Object.defineProperties` it can be used as a "flags-aware" way of cloning an object: +এই `Object.getOwnPropertyDescriptors` এবং `Object.defineProperties` মেথডের এর মাধ্যমে আমরা প্রপার্টির ফ্ল্যাগ সহ ক্লোন অবজেক্ট তৈরি করতে পারি: ```js let clone = Object.defineProperties({}, Object.getOwnPropertyDescriptors(obj)); ``` -Normally when we clone an object, we use an assignment to copy properties, like this: +সাধারণত আমরা কোন অবজেক্টকে ক্লোন করি এভাবে: ```js for (let key in user) { @@ -308,34 +304,34 @@ for (let key in user) { } ``` -...But that does not copy flags. So if we want a "better" clone then `Object.defineProperties` is preferred. +...কিন্তু এটি ফ্ল্যাগসমূহকে কপি করবে না। সুতরাং আমরা ফ্ল্যাগসহ ক্লোন করতে ব্যবহার করব `Object.defineProperties`। -Another difference is that `for..in` ignores symbolic properties, but `Object.getOwnPropertyDescriptors` returns *all* property descriptors including symbolic ones. +আরেকটি পার্থক্য হল `for..in` সাধারণত সিম্বলিক প্রপার্টিসমূহ উপেক্ষা করে, তবে `Object.getOwnPropertyDescriptors` এর জন্য সকল প্রপার্টি (সিম্বল প্রপার্টি গুলো সহ) রিটার্ন হয়। -## Sealing an object globally +## গ্লোবালি কোন অবজেক্টকে সিল করা -Property descriptors work at the level of individual properties. +প্রপার্টির ডেস্ক্রিপ্টর সকল আলাদা আলাদা প্রপার্টির জন্য কাজ করে। -There are also methods that limit access to the *whole* object: +এছাড়াও আরো কিছু মেথড আছে যাদের সাহায্যে *সম্পূর্ণ* অবজেক্টের জন্য কাজ করতে পারি: [Object.preventExtensions(obj)](mdn:js/Object/preventExtensions) -: Forbids the addition of new properties to the object. +: অবজেক্টে নতুন কোন প্রপার্টির সংযোজন করা যাবে না। [Object.seal(obj)](mdn:js/Object/seal) -: Forbids adding/removing of properties. Sets `configurable: false` for all existing properties. +: সকল প্রপার্টিতে `configurable: false` সেট করতে। ফলে কোন প্রপার্টি ডিলিট বা সংযোজন করা যাবে না। [Object.freeze(obj)](mdn:js/Object/freeze) -: Forbids adding/removing/changing of properties. Sets `configurable: false, writable: false` for all existing properties. +: কোন প্রপার্টি ডিলিট, সংযোজন, পরিবর্তন এড়াতে। সকল প্রপার্টিতে `configurable: false, writable: false` সেট হয়। -And also there are tests for them: +এছাড়াও অবজেক্টের অবস্থা যাচাইয়ের জন্যও কিছু মেথড আছে: [Object.isExtensible(obj)](mdn:js/Object/isExtensible) -: Returns `false` if adding properties is forbidden, otherwise `true`. +: যদি নতুন প্রপার্টির সংযোজন বন্ধ থাকে তাহলে `false` রিটার্ন করবে অন্যথায় `true`। [Object.isSealed(obj)](mdn:js/Object/isSealed) -: Returns `true` if adding/removing properties is forbidden, and all existing properties have `configurable: false`. +: যদি কোন প্রপার্টি ডিলিট বা সংযোজন বন্ধ থাকে তাহলে `true` রিটার্ন করবে, এবং সকল প্রপার্টিতে `configurable: false` ফ্ল্যাগ সেট করা থাকে। [Object.isFrozen(obj)](mdn:js/Object/isFrozen) -: Returns `true` if adding/removing/changing properties is forbidden, and all current properties are `configurable: false, writable: false`. +: যদি কোন প্রপার্টি ডিলিট, সংযোজন, পরিবর্তন করার অপশন বন্ধ থাকে তাহলে `true` রিটার্ন করবে, এবং সকল প্রপার্টিতে `configurable: false, writable: false` ফ্ল্যাগ সেট করা থাকে। -These methods are rarely used in practice. +তবে বাস্তবক্ষেত্রে এই মেথডসমূহ তেমন ব্যবহার করা হয় না।