مصطفی لوائی
مصطفی لوائی
خواندن ۲ دقیقه·۵ سال پیش

Primitive vs Non-Primitive

توی جاوااسکریپت متغیرها بر اساس تایپشون به دو دسته تقسیم می شن: Primitive و Non-Primitive. شاید بگید مگه جاوااسکریپت تایپ داره؟ بله متغیرها توی همه زبون ها تایپ دارن، اما توی بعضی از زبون ها مثل Java شما باید موقع تعریف متغیر تایپش رو مشخص کنید ولی توی زبونهایی مثل Javascript نوع متغیر، زمان اجرا و با توجه به مقدار درون متغیر مشخص می شه.

به بحثمون برگردیم. تایپ های Number، String، Boolean، Symbol، Undefined و Null از نوع Primitive هستن. هر چیزی غیر از ۶ تایپی که گفته شد Non-Primitive یا Object Reference هستن.

نحوه برخورد جاوااسکریپت با متغیرهای Primitive و Non-Primitive متفاوته، برای همین برای هر برنامه نویس جاوااسکریپت ضروریه که خصوصیاتشون رو بدونه. توی ادامه مطلب به تفاوت تایپ های Primitive و Non-Primitive می پردازم:

  1. تغییر ناپذیری: متغیرهایی که از نوع Primitive هستن، بر خلاف Non-Primitive ها، غیر قابل تغییرن. مثلا کد زیر رو ببینید:
let primitive = 'Hello World'; primitive[0] = 'M'; console.log(primitive); //Hello World

شاید توی کد بالا انتظار داشتید که عبارت Mello World نمایش داده بشه، ولی از اونجایی که تایپ String یه تایپ Primitive ه، غیر قابل تغییره. کد اصلاح شده اینطوریه:

let primitive = 'Hello World'; primitive = 'Mello World'; console.log(primitive); //Mello World

خاصیت تغییر ناپذیری توی تایپ های Non-Primitive وجود نداره، مثلا کد زیر رو ببینید:

let nonPrimitive = { foo: &quotbaz&quot } nonPrimitive.foo = &quotbaz&quot console.log(nonPrimitive); //{foo: &quotbaz&quot}

کد بالا همونطور که انتظار داریم کار می کنه.

مقایسه: نحوه مقایسه دو متغیر از نوع Primitive با دو متغیر از نوع Non-Primitive کاملا متفاوته. متغیرها Primitive با مقدارشون مقایسه می شن، اما متغیرهای Non-Primitive بر اساس Reference مقایسه می شن. برای این که موضوع واضح تر بشه کد زیر رو ببینید:

let num1= 110, num2= 110; console.log(num1 === num2) //true

اما دو متغیر Non-Primitive حتی اگه مقادیر یکسانی داشته باشن با هم برابر نیستن. کد زیر رو ببینید:

let arr1= [110], arr2= [110]; console.log(arr1 === arr2) //false

دو متغیر Non-Primitive فقط وقتی با هم برابرن که به یه جا اشاره کنن (بله متغیرهای Non-Primitive در واقع اشاره گر هستن)

let arr1= [110], arr2= [110], arr3= arr1; console.log(arr1 === arr2) //false console.log(arr1 === arr3) //true

ارسال به صورت پارامتر: از اونجا که یه متغیر Non-Primitive در واقع یه اشاره گره (برای همین به نام Object Reference هم شناخته می شن)، وقتی به صورت پارامتر برای تابعی ارسال بشه و اون تابع توی پارامتر ارسالی تغییری ایجاد کنه، متغیر اصلی هم تغییر می کنه:

let primitive = 1, nonPrimitive = { foo: &quotbar&quot }; test(primitive, nonPrimitive); function test(primitiveArg, nonPrimitiveArg){ primitiveArg = 3; nonPrimitiveArg.foo = &quotbaz&quot } console.log(primitive) //1 console.log(nonPrimitive) //{foo: &quotbaz&quot}

پس باید حواستون باشه وقتی یه متغیر Non-Primitive رو برای تابعی می فرستید، اگر نمی خواید توی مقدار متغیر اصلی تغییری ایجاد کنید، حتما پارامتر ارسالی یه کپی بگیرید و بعد ازش استفاده کنید:

let primitive = 1, nonPrimitive = { foo: &quotbar&quot }; test(primitive, nonPrimitive); function test(primitiveArg, nonPrimitiveArg){ let cloneNonPrimitive = {...nonPrimitiveArg}; primitiveArg = 3; cloneNonPrimitive.foo = &quotbaz&quot } console.log(primitive) //1 console.log(nonPrimitive) //{foo: &quotbar&quot}


javascriptprimitiveobject referenceecmascriptnon primitive
یه برنامه نویس که دوست داره داشته هاشو در اختیار دیگران بذاره
شاید از این پست‌ها خوشتان بیاید