یک شیء با سازنده یکسان ایجاد کنید
تصور کنید، یک شیء دلخواه obj داریم که توسط یک تابع سازنده ایجاد شده است – نمیدانیم کدام یک، اما میخواهیم با استفاده از آن یک شیء جدید ایجاد کنیم.
میتوانیم آن را انجام دهیم؟
let obj2 = new obj.constructor();
مثالی از یک تابع سازنده برای obj بیاورید که به این کد اجازه میدهد درست کار کند. و مثالی که باعث میشود اشتباه کار کند.
اگر مطمئن باشیم که ویژگی "constructor" مقدار صحیحی دارد، میتوانیم از چنین رویکردی استفاده کنیم.
برای مثال، اگر "prototype" پیشفرض را تغییر ندهیم، این کد مطمئناً کار میکند:
function User(name) {
this.name = name;
}
let user = new User('John');
let user2 = new user.constructor('Pete');
alert( user2.name ); // Pete (کار کرد!)
کار کرد، زیرا User.prototype.constructor == User.
…اما اگر شخصی، به اصطلاح، User.prototype را بازنویسی کند و فراموش کند constructor را برای ارجاع به User بازآفرینی کند، آنگاه شکست خواهد خورد.
برای مثال:
function User(name) {
this.name = name;
}
User.prototype = {}; // (*)
let user = new User('John');
let user2 = new user.constructor('Pete');
alert( user2.name ); // undefined
چرا user2.name برابر با undefined است؟
در اینجا نحوه عملکرد new user.constructor('Pete') وجود دارد:
- ابتدا، به دنبال
constructorدرuserمیگردد. هیچچیز. - سپس از زنجیره پروتوتایپ پیروی میکند. پروتوتایپ
userبرابر باUser.prototypeاست، و همچنینconstructorندارد (زیرا ما «فراموش کردیم» آن را درست تنظیم کنیم!). - در ادامه زنجیره،
User.prototypeیک شیء ساده است، پروتوتایپ آنObject.prototypeداخلی است. - در نهایت، برای
Object.prototypeداخلی،Object.prototype.constructor == Objectداخلی وجود دارد. بنابراین استفاده میشود.
سرانجام، در پایان، let user2 = new Object('Pete') را داریم.
احتمالاً این چیزی نیست که ما میخواهیم. ما میخواهیم new User ایجاد کنیم، نه new Object. این نتیجه constructor گم شده است.
(فقط در صورتی که کنجکاو باشید، فراخوانی new Object(...) آرگومان خود را به یک شیء تبدیل میکند. این یک چیز تئوری است، در عمل هیچکس new Object را با مقدار نمینامد، و عموماً ما اصلاً از new Object برای ساختن اشیاء استفاده نمیکنیم).