ما قصد داریم این پروژهٔ متنباز را در دسترس همهٔ مردم در سرتاسر دنیا قرار دهیم.
به ترجمهٔ محتوای این آموزش به زبان خودتان کمک کنید/a>.
سازنده، عملگر "new"
سینتکس معمولی {…} اجازه ساخت یک شیء را می دهد. اما غالبا ما نیاز داریم که شیء های متشابه زیادی ایجاد کنیم، مثل چند کاربر یا آیتم های منو و…
این می تواند با استفاده از تابع های سازنده و عملگر new انجام شود.
تابع سازنده
تابع های سازنده از لحاظ فنی همان تابع های معمولی هستند. با این حال دو قرارداد وجود دارد:
- آنها با حرف بزرگ انگلیسی نامگذاری می شوند.
- آنها باید فقط با عملگر
newاجرا شوند.
برای مثال:
زمانی که یک تابع با new اجرا می شود، مراحل زیر را انجام می دهد:
- یک شیء خالی جدید ساخته می شود و به
thisاختصاص می یابد. - بدنه ی تابع اجرا می شود. معمولا
thisرا تغییر می دهد، ویژگی های جدید را به آن اضافه می کند. - مقدار
thisبرگردانده می شود.
به عبارتی دیگر، new User(...) چیزی مانند این را انجام می دهد:
function User(name) {
// this = {}; (به صورت ضمنی)
// ویژگی ها را به this اضافه میکند
this.name = name;
this.isAdmin = false;
// return this; (به صورت ضمنی)
}
پس let user = new User("Jack") نتیجه مشابهی مانند کد زیر را می دهد:
let user = {
name: "Jack",
isAdmin: false
};
حالا اگر ما بخواهیم که user های دیگری بسازیم، می توانیم new User("Ann")، new User("Alice") و … را صدا بزنیم. این کار بسیار کوتاه تر از استفاده همیشگی از literal ها است، و همچنین برای خواندن آسان است.
این هدف اصلی سازنده ها است – پیاده سازی کد قابل استفاده مجدد ساخت شیء.
بیایید دوباره به این موضوع اشاره کنیم – از لحاظ فنی، هر تابعی می تواند به عنوان سازنده استفاده شود. به این معنی که: هر تابعی می تواند با new اجرا شود، و الگوریتم بالا را اجرا کند. “حرف اول بزرگ انگلیسی” یک قرارداد عمومی است، تا این موضوع را که یک تابع باید با new اجرا شود را شفاف سازی کند.
اگر ما خطوط زیادی از کد که همه آنها مربوط به ساخت یک شیء پیچیده هستند را داشته باشیم، می توانیم آنها را درون تابع سازنده بپیچیم، به این صورت:
// create a function and immediately call it with new
let user = new function() {
this.name = "John";
this.isAdmin = false;
// ... کد های دیگر برای ساخت user
// شاید شامل منطق و دستورالعمل پیچیده ای باشد
// متغیرهای محلی و...
};
سازنده نمی تواند دوباره صدا زده شود، چون در جایی ذخیره نشده، فقط ساخته و صدا زده شده است. پس این ترفند، کپسول کردن کدی که یک شیء می سازد و در آینده استفاده نمی شود را مورد هدف قرار می دهد.
سازنده هایی با سینتکس دوگانه: new.target
سینتکس این بخش به ندرت استفاده می شود، آن را از قلم بندازید مگر اینکه بخواهید همه چیز را بدانید.
درون یک تابع، ما می توانیم چک کنیم که همراه با new صدا زده شده یا بدون آن، با استفاده از ویژگی new.target.
آن(new.target) برای مواقعی که تابع به صورت معمولی صدا زده می شود undefined است و درصورتی که همراه با new صدا زده شود برابر با تابع است:
از آن می توان استفاده کرد تا هم صدا زدن تابع با new و هم صدا زدن معمولی تابع به یک شکل کار کنند. یعنی اینکه شیء متشابه بسازند:
این شیوه بعضی اوقات درون کتابخانه ها استفاده می شود تا سینتکس را منعطف تر کند. با این روش شاید مردم تابع را همراه با یا بدون new صدا بزنند، و آن همچنان کار میکند.
اگرچه شاید خوب نباشد همه جا استفاده شود، چون حذف کردن new مقداری از واضح بودن اینکه چه چیزی در حال رخ دادن است کم میکند. همراه با new همه ما میدانیم که شیء جدیدی در حال ساخته شدن است.
برگرداندن از سازنده ها
معمولا، سازنده ها دستور return ندارند. وظیفه آنها این است که تمام چیزهای ضروری را داخل this بریزند، و آن(this) تبدیل به نتیجه می شود.
اما اگر دستور return وجود داشته باشد، سپس قاعده ساده است:
- اگر
returnهمراه با شیء صدا زده شود، سپس شیء به جایthisبرگردانده می شود. - اگر
returnهمراه با یک primitive صدا شده شود، نادیده گرفته می شود.
به عبارتی دیگر، return همراه با یک شیء همان شیء را برمیگرداند، در دیگر موارد this برگردانده می شود.
برای مثال، اینجا return با برگرداندن یک شیء this را نادیده میگیرد:
و اینجا هم یک مثال با یک return خالی داریم (یا می توانستیم بعد از آن یک primitive بگذاریم، فرقی ندارد):
معمولا سازنده ها دستور return ندارند. اینجا ما این رفتار خاص برگرداندن شیءها را تنها برای کامل بودن خاطر نشان کردیم.
راستی، اگر هیچ آرگومانی در کار نباشد، ما می توانیم پرانترهای بعد از new را حذف کنیم:
let user = new User; // <-- بدون پرانتز
// مشابه است با
let user = new User();
اینجا حذف کردن پرانتزها به عنوان یک “سبک خوب” فرض نمی شود، اما سینتکس طبق خصوصیات مجاز است.
متدها در سازنده
استفاده از تابع های سازنده برای ساخت شیءها انعطاف زیادی به ما میدهد. تابع سازنده ممکن است پارامترهایی داشته باشد که تعیین میکند چگونه شیء ساخته شود، و چه چیزی داخل آن قرار داده شود.
قطعا ما می توانیم علاوه بر ویژگی ها، متدها را هم به this اضافه کنیم.
برای مثال، new User(name) که در زیر قرار دارد یک شیء میسازد که به آن name و متد sayHi داده شده است:
برای ساخت شیءهای پیچیده، یک سینتکس پیشرفته تر، کلاس ها، وجود دارد که ما بعدا آن را پوشش می دهیم.
خلاصه
- تابع های سازنده، یا به اختصار، سازنده ها، تابع هایی معمولی هستند، اما یک توافق عمومی وجود دارد که آنها را با حرف بزرگ انگلیسی نامگذاری کنیم.
- تابع های سازنده باید تنها با
newصدا زده شوند. چنین صدا زدنی به ساخت یکthisخالی در آغاز و برگرداندن پر شده ی آن در پایان اشاره می کند.
ما می توانیم از تابع های سازنده برای ساخت چند شیء متشابه استفاده کنیم.
جاوااسکریپت تابع های سازنده را برای بسیاری از شیءهایی که درون زبان ساخته شده اند فراهم میکند: مثل Date برای زمان ها، Set برای set ها و بقیه که ما مطالعه آنها را در نظر داریم.
در این فصل ما فقط اصول اولیه را برای شیءها و سازنده ها را پوشش می دهیم. آنها برای یادگیری بیشتر درباره انواع داده و تابع ها در فصل های آینده ضروری هستند.
بعد از اینکه آن را یاد گرفتیم، در فصل مقاله "object-oriented-programming" پیدا نشد (برنامه نویسی شیءگرا) به شیءها بر می گردیم و آنها را به صورت عمیق پوشش می دهیم، که شامل وراثت و کلاس ها هم می شود.
تمارین
آیا امکان دارد که تابع های A و B را به گونه ای ساخت که new A()==new B()؟
function A() { ... }
function B() { ... }
let a = new A();
let b = new B();
alert( a == b ); // درست
اگر امکان دارد، پس یک مثال از کدهایشان تهیه کنید.
یک تابع سازنده Calculator بسازید که شیء هایی با 3 متد ایجاد می کند.
read()با استفاده ازpromptبرای دو مقدار درخواست می کند و آنها را با نامهایaوbبه عنوان ویژگی های شیء به خاطر می سپارد.sum()مجموع این ویژگی ها را بر می گرداند.mul()حاصل ضرب این ویژگی ها را بر می گرداند.
برای مثال:
let calculator = new Calculator();
calculator.read();
alert( "Sum=" + calculator.sum() );
alert( "Mul=" + calculator.mul() );
[دمو]
function Calculator() {
this.read = function() {
this.a = +prompt('a?', 0);
this.b = +prompt('b?', 0);
};
this.sum = function() {
return this.a + this.b;
};
this.mul = function() {
return this.a * this.b;
};
}
let calculator = new Calculator();
calculator.read();
alert( "Sum=" + calculator.sum() );
alert( "Mul=" + calculator.mul() );
یک تابع سازنده Accumulator(startingValue) بسازید.
شیء ای که می سازد باید:
- “مقدار حال حاضر” را در ویژگی
valueذخیره کند. مقدار آغازین در آرگومانstartingValueسازنده قرار می گیرد. - متد
read()باید ازpromptبرای خواندن یک عدد جدید استفاده کند و آن را بهvalueاضافه کند.
به عبارتی دیگر، ویژگی value حاصلِ جمع تمام مقدارهایی که کاربر وارد کرده با مقدار اولیه ی startingValue است.
اینجا نسخه دموی کد وجود دارد:
let accumulator = new Accumulator(1); // مقدار اولیه 1
accumulator.read(); // مقداری که کاربر وارد کرده را اضافه می کند
accumulator.read(); // مقداری که کاربر وارد کرده را اضافه می کند
alert(accumulator.value); // مجموع این مقدارها را نشان می دهد
[دمو]
- © 2007—2026 Ilya Kantor
- دربارهٔ پروژه
- تماس با ما
نظرات
<code>استفاده کنید، برای چندین خط – کد را درون تگ<pre>قرار دهید، برای بیش از ده خط کد – از یک جعبهٔ شنی استفاده کنید. (plnkr، jsbin، codepen…)