From fcefb3a1b92e110446d0afbcddebc59f43be03ba Mon Sep 17 00:00:00 2001 From: mahdiHash Date: Thu, 6 Jan 2022 01:13:00 +0330 Subject: [PATCH 1/9] Translate a part of article Line 7 needs more attention --- 1-js/09-classes/07-mixins/article.md | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/1-js/09-classes/07-mixins/article.md b/1-js/09-classes/07-mixins/article.md index 06001d900..3e95cb775 100644 --- a/1-js/09-classes/07-mixins/article.md +++ b/1-js/09-classes/07-mixins/article.md @@ -1,16 +1,16 @@ -# Mixins +# Mixinها -In JavaScript we can only inherit from a single object. There can be only one `[[Prototype]]` for an object. And a class may extend only one other class. +در جاوااسکریپت ما فقط می‌توانیم از یک شیء ارث‌بری کنیم. فقط یک `[[Prototype]]` برای هر شیء می‌تواند وجود داشته باشد. و یک کلاس فقط می‌تواند یک کلاس دیگر را تعمیم دهد. -But sometimes that feels limiting. For instance, we have a class `StreetSweeper` and a class `Bicycle`, and want to make their mix: a `StreetSweepingBicycle`. +اما گاهی اوقات این حس محدود بودن را دارد. برای مثال، ما کلاس `StreetSweeper` و کلاس `Bicycle` را داریم و می‌خواهیم ترکیب آن‌ها را بسازیم: یک `StreetSweepingBicycle`. -Or we have a class `User` and a class `EventEmitter` that implements event generation, and we'd like to add the functionality of `EventEmitter` to `User`, so that our users can emit events. +یا ما کلاس `User` و کلاس `EventEmitter` که پیاده‌سازی ایجاد رویداد (event) انجام می‌دهد را داریم و می‌خواهیم که عملکرد `EventEmitter` را به `User` اضافه کنیم تا کاربران ما بتوانند رویدادها را خارج کنند. -There's a concept that can help here, called "mixins". +یک راه‌کار وجود دارد که اینجا به کمک می‌آید، به نام "mixins". -As defined in Wikipedia, a [mixin](https://en.wikipedia.org/wiki/Mixin) is a class containing methods that can be used by other classes without a need to inherit from it. +همانطور که در ویکی‌پدیا تعریف شده است، یک [mixin](https://en.wikipedia.org/wiki/Mixin) کلاسی شامل متدهایی است که می‌توانند بدون نیاز به ارث‌بری از کلاس، توسط کلاس‌های دیگر استفاده شوند. -In other words, a *mixin* provides methods that implement a certain behavior, but we do not use it alone, we use it to add the behavior to other classes. +به عبارتی دیگر، یک *mixin* متدهایی که یک کار مشخص انجام می‌دهند را فراهم می‌کند اما از آن به تنهایی استفاده نمی‌کنیم بلکه از آن برای اضافه کردن همان کار مشخص به کلاس‌های دیگر استفاده می‌کنیم. ## A mixin example From 165c8cb91f89a7a2b3ee97a77bb88508fa44ebb7 Mon Sep 17 00:00:00 2001 From: mahdiHash Date: Thu, 6 Jan 2022 20:53:08 +0330 Subject: [PATCH 2/9] Translate a part of article Line 19 needs more attention. --- 1-js/09-classes/07-mixins/article.md | 34 ++++++++++++++-------------- 1 file changed, 17 insertions(+), 17 deletions(-) diff --git a/1-js/09-classes/07-mixins/article.md b/1-js/09-classes/07-mixins/article.md index 3e95cb775..d75d41f24 100644 --- a/1-js/09-classes/07-mixins/article.md +++ b/1-js/09-classes/07-mixins/article.md @@ -12,11 +12,11 @@ به عبارتی دیگر، یک *mixin* متدهایی که یک کار مشخص انجام می‌دهند را فراهم می‌کند اما از آن به تنهایی استفاده نمی‌کنیم بلکه از آن برای اضافه کردن همان کار مشخص به کلاس‌های دیگر استفاده می‌کنیم. -## A mixin example +## یک مثال mixin -The simplest way to implement a mixin in JavaScript is to make an object with useful methods, so that we can easily merge them into a prototype of any class. +ساده‌ترین راه برای پیاده‌سازی یک mixin در جاوااسکریپت ایجاد شیءای شامل متدهایی مفید است تا بتوانیم به راحتی آن‌ها را درون پروتوتایپ هر کلاسی ادغام کنیم. -For instance here the mixin `sayHiMixin` is used to add some "speech" for `User`: +برای مثال اینجا `sayHiMixin` برای اضافه کردن «گفتار» به `User` استفاده شده است: ```js run *!* @@ -32,7 +32,7 @@ let sayHiMixin = { }; *!* -// usage: +// :کاربرد */!* class User { constructor(name) { @@ -40,14 +40,14 @@ class User { } } -// copy the methods +// کپی کردن متدها Object.assign(User.prototype, sayHiMixin); -// now User can say hi +// بگوید (hi) می‌تواند سلام User حالا new User("Dude").sayHi(); // Hello Dude! ``` -There's no inheritance, but a simple method copying. So `User` may inherit from another class and also include the mixin to "mix-in" the additional methods, like this: +ارث‌بری در کار نیست، فقط یک کپی کردن متد ساده است. پس `User` می‌تواند از کلاس دیگری ارث‌بری کند و همچنین mixin را هم شامل شود تا متدهای اضافی را «ترکیب» کند، مثل این: ```js class User extends Person { @@ -57,9 +57,9 @@ class User extends Person { Object.assign(User.prototype, sayHiMixin); ``` -Mixins can make use of inheritance inside themselves. +mixinها می‌توانند درون خود از ارث‌بری استفاده کنند. -For instance, here `sayHiMixin` inherits from `sayMixin`: +برای مثال، اینجا `sayHiMixin` از `sayMixin` ارث‌بری می‌کند: ```js run let sayMixin = { @@ -69,11 +69,11 @@ let sayMixin = { }; let sayHiMixin = { - __proto__: sayMixin, // (or we could use Object.setPrototypeOf to set the prototype here) + __proto__: sayMixin, // (برای تنظیم پروتوتایپ استفاده کنیم `Object.setPrototypeOf` یا می‌توانستیم اینجا از) sayHi() { *!* - // call parent method + // فراخوانی متد والد */!* super.say(`Hello ${this.name}`); // (*) }, @@ -88,22 +88,22 @@ class User { } } -// copy the methods +// کپی کردن متدها Object.assign(User.prototype, sayHiMixin); -// now User can say hi +// بگوید (hi) می‌تواند سلام User حالا new User("Dude").sayHi(); // Hello Dude! ``` -Please note that the call to the parent method `super.say()` from `sayHiMixin` (at lines labelled with `(*)`) looks for the method in the prototype of that mixin, not the class. +لطفا توجه کنید که فراخوانی متد `super.say()` از `sayHiMixin` (در خطی که با `(*)` برچسب‌گذاری شده) در پروتوتایپ mixin به دنبال متد می‌گردد نه کلاس. -Here's the diagram (see the right part): +اینجا شکل آن را داریم (قسمت راست را ببینید): ![](mixin-inheritance.svg) -That's because methods `sayHi` and `sayBye` were initially created in `sayHiMixin`. So even though they got copied, their `[[HomeObject]]` internal property references `sayHiMixin`, as shown in the picture above. +دلیلش این است که `sayHi` و `sayBye` از اول درون `sayHiMixin` ایجاد شده‌اند. پس حتی با اینکه کپی شدند، ویژگی درونی `[[HomeObject]]` آن‌ها به `sayHiMixin` رجوع می‌کند، همانطور که در تصویر بالا نشان داده شده است. -As `super` looks for parent methods in `[[HomeObject]].[[Prototype]]`, that means it searches `sayHiMixin.[[Prototype]]`, not `User.[[Prototype]]`. +چون `super` درون `[[HomeObject]].[[Prototype]]` به دنبال متدهای والد می‌گردد، یعنی `sayHiMixin.[[Prototype]]` را جست‌وجو می‌کند نه `User.[[Prototype]]` را. ## EventMixin From 68ed64034ae9da672d3ad2dad9883dfdd8c7dac5 Mon Sep 17 00:00:00 2001 From: mahdiHash Date: Fri, 7 Jan 2022 22:41:20 +0330 Subject: [PATCH 3/9] Translate a part of article Line 115, 127 and 139 need more attention. --- 1-js/09-classes/07-mixins/article.md | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/1-js/09-classes/07-mixins/article.md b/1-js/09-classes/07-mixins/article.md index d75d41f24..3e396dca0 100644 --- a/1-js/09-classes/07-mixins/article.md +++ b/1-js/09-classes/07-mixins/article.md @@ -107,24 +107,24 @@ new User("Dude").sayHi(); // Hello Dude! ## EventMixin -Now let's make a mixin for real life. +حالا بیایید یک mixin برای زندگی واقعی بسازیم. -An important feature of many browser objects (for instance) is that they can generate events. Events are a great way to "broadcast information" to anyone who wants it. So let's make a mixin that allows us to easily add event-related functions to any class/object. +یک خاصیت مهم در تعداد زیادی از شیءهای مرورگر (برای مثال) این است که آن‌ها می‌توانند رویداد (event) ایجاد کنند. رویدادها راهی عالی برای «انتشار اطلاعات» به هر کسی که آن را بخواهد هستند. پس بیایید یک mixin بسازیم که به ما این امکان را می‌دهد تا به راحتی تابع‌های مربوط به رویداد را به هر شیء/کلاسی اضافه کنیم. -- The mixin will provide a method `.trigger(name, [...data])` to "generate an event" when something important happens to it. The `name` argument is a name of the event, optionally followed by additional arguments with event data. -- Also the method `.on(name, handler)` that adds `handler` function as the listener to events with the given name. It will be called when an event with the given `name` triggers, and get the arguments from the `.trigger` call. -- ...And the method `.off(name, handler)` that removes the `handler` listener. +- این mixin متد `.trigger(name, [...data])` را برای «ایجاد یک رویداد» زمانی که اتفاقی برای آن می‌افتد فراهم می‌کند. آرگومان `name` اسم رویداد است که بعد از آن آرگومان‌های اضافی اختیاری شامل دادۀ رویداد می‌آید. +- همچنین متد `.on(name, handler)` را فراهم می‌کند که تابع `handler` را به عنوان کنترل‌کننده به رویدادهایی با نام داده شده اضافه می‌کند. این تابع زمانی که رویدادی همراه با `name` داده شده راه می‌افتد (trigger) اجرا می‌شود و آرگومان‌ها را از فراخوانی `.trigger` دریافت می‌کند. +- ...و متد `.off(name, handler)` را هم فراهم می‌کند که کنترل‌کننده `handler` را حذف می‌کند. -After adding the mixin, an object `user` will be able to generate an event `"login"` when the visitor logs in. And another object, say, `calendar` may want to listen for such events to load the calendar for the logged-in person. +بعد از اضافه کردن `mixin`، یک شیء `user` خواهد توانست زمانی که بازدیدکننده وارد می‌شود (log in) یک رویداد `"login"` ایجاد کند. و شیء دیگر، مثلا `calendar` (تقویم) شاید بخواهد چنین رویدادهایی را کنترل کند تا تقویم را برای شخص وارد شده بارگیری کند. -Or, a `menu` can generate the event `"select"` when a menu item is selected, and other objects may assign handlers to react on that event. And so on. +یا یک `menu` (فهرست) می‌تواند زمانی که چیزی از فهرست انتخاب شود رویداد `"select"` (انتخاب) را ایجاد کند و شیءهای دیگر ممکن است کنترل‌کننده‌هایی را برای واکنش دادن به این رویداد داشته باشند. و مثال‌هایی دیگر. -Here's the code: +اینجا کد آن را داریم: ```js run let eventMixin = { /** - * Subscribe to event, usage: + * :متعهد ساختن به یک رویداد، کاربرد * menu.on('select', function(item) { ... } */ on(eventName, handler) { @@ -136,7 +136,7 @@ let eventMixin = { }, /** - * Cancel the subscription, usage: + * :لغو کردن تعهد، کاربرد * menu.off('select', handler) */ off(eventName, handler) { @@ -150,15 +150,15 @@ let eventMixin = { }, /** - * Generate an event with the given name and data + * ایجاد یک رویداد همراه با داده و نام داده شده * this.trigger('select', data1, data2); */ trigger(eventName, ...args) { if (!this._eventHandlers?.[eventName]) { - return; // no handlers for that event name + return; // کنترل‌کننده‌ای برای این نام رویداد وجود ندارد } - // call the handlers + // فراخوانی کنترل‌کننده‌ها this._eventHandlers[eventName].forEach(handler => handler.apply(this, args)); } }; From 89171ebbbc830633955daddb41ee107295a66efe Mon Sep 17 00:00:00 2001 From: mahdiHash Date: Sat, 8 Jan 2022 16:23:28 +0330 Subject: [PATCH 4/9] Translate a part of article Line 168 needs more attention. --- 1-js/09-classes/07-mixins/article.md | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/1-js/09-classes/07-mixins/article.md b/1-js/09-classes/07-mixins/article.md index 3e396dca0..73f681642 100644 --- a/1-js/09-classes/07-mixins/article.md +++ b/1-js/09-classes/07-mixins/article.md @@ -165,37 +165,37 @@ let eventMixin = { ``` -- `.on(eventName, handler)` -- assigns function `handler` to run when the event with that name occurs. Technically, there's an `_eventHandlers` property that stores an array of handlers for each event name, and it just adds it to the list. -- `.off(eventName, handler)` -- removes the function from the handlers list. -- `.trigger(eventName, ...args)` -- generates the event: all handlers from `_eventHandlers[eventName]` are called, with a list of arguments `...args`. +- متد `.on(eventName, handler)` -- مشخص می‌کند که تابع `handler` هنگامی که رویدادی با این نام رخ می‌دهد اجرا شود. از لحاظ فنی، یک ویژگی `_eventHandlers` وجود دارد که آرایه‌ای از کنترل‌کننده‌ها را برای هر رویداد ذخیره می‌کند و این متد فقط کنترل‌کننده را به لیست اضافه می‌کند. +- متد `.off(eventName, handler)` -- تابع را از لیست کنترل‌کننده‌ها حذف می‌کند. +- متد `.trigger(eventName, ...args)` -- رویداد را ایجاد می‌کند: تمام کنترل‌کننده‌ها از `_eventHandlers[eventName]` همراه با لیستی از آرگومان‌ها `...args` فراخوانی می‌شوند. -Usage: +کاربرد: ```js run -// Make a class +// ایجاد یک کلاس class Menu { choose(value) { this.trigger("select", value); } } -// Add the mixin with event-related methods +// شامل متدهای مربوط به رویداد mixin اضافه کردن Object.assign(Menu.prototype, eventMixin); let menu = new Menu(); -// add a handler, to be called on selection: +// :فراخوانی شود (select) اضافه کردن یک کنترل‌کننده، تا هنگام انتخاب *!* menu.on("select", value => alert(`Value selected: ${value}`)); */!* -// triggers the event => the handler above runs and shows: +// :رویداد را راه می‌اندازد => کنترل‌کننده بالا اجرا می‌شود و این را نمایش می‌دهد // Value selected: 123 menu.choose("123"); ``` -Now, if we'd like any code to react to a menu selection, we can listen for it with `menu.on(...)`. +حالا اگر ما بخواهیم هر کدی به انتخاب چیزی از فهرست واکنش نشان دهد، می‌توانیم با `menu.on(...)` آن را کنترل کنیم. -And `eventMixin` mixin makes it easy to add such behavior to as many classes as we'd like, without interfering with the inheritance chain. +و `eventMixin` اضافه کردن چنین رفتاری به هر چند کلاسی که بخواهیم را آسان می‌کند، بدون اینکه کاری به زنجیره ارث‌بری داشته باشیم. ## Summary From 3ab392645585124ed1bb7af55ac4bf7ba47de8d4 Mon Sep 17 00:00:00 2001 From: mahdiHash Date: Sat, 8 Jan 2022 16:32:15 +0330 Subject: [PATCH 5/9] Translate article Line 206 needs more attention. --- 1-js/09-classes/07-mixins/article.md | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/1-js/09-classes/07-mixins/article.md b/1-js/09-classes/07-mixins/article.md index 73f681642..32ab141c3 100644 --- a/1-js/09-classes/07-mixins/article.md +++ b/1-js/09-classes/07-mixins/article.md @@ -197,12 +197,12 @@ menu.choose("123"); و `eventMixin` اضافه کردن چنین رفتاری به هر چند کلاسی که بخواهیم را آسان می‌کند، بدون اینکه کاری به زنجیره ارث‌بری داشته باشیم. -## Summary +## خلاصه -*Mixin* -- is a generic object-oriented programming term: a class that contains methods for other classes. +*Mixin* -- یک عبارت عام برنامه‌نویسی شیءگرا است: کلاسی که متدهایی را برای کلاس‌های دیگر دربرمی‌گیرد. -Some other languages allow multiple inheritance. JavaScript does not support multiple inheritance, but mixins can be implemented by copying methods into prototype. +بعضی از زبان‌های دیگر ارث‌بری چندگانه را ممکن می‌سازند. جاوااسکریپت از ارث‌بری چندگانه پشتیبانی نمی‌کند اما با کپی کردن متدها درون پروتوتایپ mixinها می‌توانند پیاده‌سازی شوند. -We can use mixins as a way to augment a class by adding multiple behaviors, like event-handling as we have seen above. +ما می‌توانیم با اضافه کردن چند عملکرد، از mixinها به عنوان راهی برای قدرتمند کردن یک کلاس استفاده کنیم، مانند کنترل کردن رویداد که بالاتر آن را دیدیم. -Mixins may become a point of conflict if they accidentally overwrite existing class methods. So generally one should think well about the naming methods of a mixin, to minimize the probability of that happening. +اگر mixinها به طور تصادفی متدهای موجود در کلاس را بازنویسی کنند، ممکن است باعث ایجاد تناقض شوند. پس به طور کلی باید درباره نام‌گذاری متدهای یک mixin به خوبی فکر کنید تا احتمال اتفاق افتادن چنین چیزی را کم کنید. From be0c46afd67fcb8c4d5a47fa05c7841beb3ee6cc Mon Sep 17 00:00:00 2001 From: mahdiHash Date: Sat, 8 Jan 2022 16:59:53 +0330 Subject: [PATCH 6/9] Translate comments of "head.html" --- 1-js/09-classes/07-mixins/head.html | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/1-js/09-classes/07-mixins/head.html b/1-js/09-classes/07-mixins/head.html index 20e3a6354..e8bc09015 100644 --- a/1-js/09-classes/07-mixins/head.html +++ b/1-js/09-classes/07-mixins/head.html @@ -2,7 +2,7 @@ let eventMixin = { /** - * Subscribe to event, usage: + * :متعهد ساختن به یک رویداد، کاربرد * menu.on('select', function(item) { ... } */ on(eventName, handler) { @@ -14,7 +14,7 @@ }, /** - * Cancel the subscription, usage: + * :لغو کردن تعهد، کاربرد * menu.off('select', handler) */ off(eventName, handler) { @@ -28,15 +28,15 @@ }, /** - * Generate the event and attach the data to it + * ایجاد یک رویداد همراه با داده و نام داده شده * this.trigger('select', data1, data2); */ trigger(eventName, ...args) { if (!this._eventHandlers || !this._eventHandlers[eventName]) { - return; // no handlers for that event name + return; // کنترل‌کننده‌ای برای این نام رویداد وجود ندارد } - // call the handlers + // فراخوانی کنترل‌کننده‌ها this._eventHandlers[eventName].forEach(handler => handler.apply(this, args)); } }; From c4e040ea7d0f25cf4f873b9e5069ebc3b088fa47 Mon Sep 17 00:00:00 2001 From: mahdiHash Date: Sun, 9 Jan 2022 21:38:18 +0330 Subject: [PATCH 7/9] Apply suggestions from code review Co-authored by: Mahdyar Hasanpour --- 1-js/09-classes/07-mixins/article.md | 4 ++-- 1-js/09-classes/07-mixins/head.html | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/1-js/09-classes/07-mixins/article.md b/1-js/09-classes/07-mixins/article.md index 32ab141c3..c0b39be4b 100644 --- a/1-js/09-classes/07-mixins/article.md +++ b/1-js/09-classes/07-mixins/article.md @@ -16,7 +16,7 @@ ساده‌ترین راه برای پیاده‌سازی یک mixin در جاوااسکریپت ایجاد شیءای شامل متدهایی مفید است تا بتوانیم به راحتی آن‌ها را درون پروتوتایپ هر کلاسی ادغام کنیم. -برای مثال اینجا `sayHiMixin` برای اضافه کردن «گفتار» به `User` استفاده شده است: +برای مثال اینجا میکسین `sayHiMixin` برای اضافه کردن «گفتار» به `User` استفاده شده است: ```js run *!* @@ -136,7 +136,7 @@ let eventMixin = { }, /** - * :لغو کردن تعهد، کاربرد + * :لغو کردن اشتراک، استفاده * menu.off('select', handler) */ off(eventName, handler) { diff --git a/1-js/09-classes/07-mixins/head.html b/1-js/09-classes/07-mixins/head.html index e8bc09015..6bc4d1f02 100644 --- a/1-js/09-classes/07-mixins/head.html +++ b/1-js/09-classes/07-mixins/head.html @@ -14,7 +14,7 @@ }, /** - * :لغو کردن تعهد، کاربرد + * :لغو کردن اشتراک، استفاده * menu.off('select', handler) */ off(eventName, handler) { From 89b3ec1de76ca4b93d1ab6a61f43dd6b0bfd6c2d Mon Sep 17 00:00:00 2001 From: mahdiHash Date: Mon, 10 Jan 2022 12:50:17 +0330 Subject: [PATCH 8/9] Change a line Co-authored by: Mahdyar Hasanpour --- 1-js/09-classes/07-mixins/article.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/1-js/09-classes/07-mixins/article.md b/1-js/09-classes/07-mixins/article.md index c0b39be4b..dc9344936 100644 --- a/1-js/09-classes/07-mixins/article.md +++ b/1-js/09-classes/07-mixins/article.md @@ -124,7 +124,7 @@ new User("Dude").sayHi(); // Hello Dude! ```js run let eventMixin = { /** - * :متعهد ساختن به یک رویداد، کاربرد + * :مشترک شدن در یک رویداد، کاربرد * menu.on('select', function(item) { ... } */ on(eventName, handler) { From f3b1569d7642f3e871a987ab03db2b43b19ca6ed Mon Sep 17 00:00:00 2001 From: mahdiHash Date: Mon, 10 Jan 2022 12:54:10 +0330 Subject: [PATCH 9/9] Change a line Co-authored by: @Beroozam --- 1-js/09-classes/07-mixins/article.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/1-js/09-classes/07-mixins/article.md b/1-js/09-classes/07-mixins/article.md index dc9344936..13ec0543e 100644 --- a/1-js/09-classes/07-mixins/article.md +++ b/1-js/09-classes/07-mixins/article.md @@ -107,7 +107,7 @@ new User("Dude").sayHi(); // Hello Dude! ## EventMixin -حالا بیایید یک mixin برای زندگی واقعی بسازیم. +حالا بیایید یک mixin برای دنیای واقعی بسازیم. یک خاصیت مهم در تعداد زیادی از شیءهای مرورگر (برای مثال) این است که آن‌ها می‌توانند رویداد (event) ایجاد کنند. رویدادها راهی عالی برای «انتشار اطلاعات» به هر کسی که آن را بخواهد هستند. پس بیایید یک mixin بسازیم که به ما این امکان را می‌دهد تا به راحتی تابع‌های مربوط به رویداد را به هر شیء/کلاسی اضافه کنیم.