مفهوم شی گرایی در زبان‌های برنامه نویسی بسیار مهم است که در این آموزش سعی می‌کنیم به ساده ترین روش آن را برای شما عزیزان تشریح کنیم.

پیشتر در این پست به مفهوم شی گرایی پرداختیم.

 به صورت خلاصه می‌توان گفت شی گرایی، صورت بسیار پیشرفته تر توابع در برنامه نویسی است.

با شی گرایی برنامه نویسی حرفه‌ای تر و کاربردی تر است. اساسا برنامه‌ای که بر اساس شی گرایی نوشته شده باشد بسیار راحت تر توسعه و رفع عیب داده می‌شود.

لازم به ذکر است برنامه‌های شی گرا برای کارهای گروهی نیز مناسب تر هستند، و برای ورود به برنامه نویسی حرفه‌ای نا گذیرید شی گرایی را فرا بگیرید.

اساس کلاس‌ها بر پایه کلاس‌ها و ارتباط آن‌ها شکل می‌گیرد. ما در شی گرایی یک کلاس داریم که مجموعی‌ای از متدها را در بر می‌گیرد. متدها در کلاس وظیفه انجام عملیات و یا تهیه خروجی را بر عهده دارند.

در دیگر زبان‌های برنامه نویسی معمولا از کلمه کلیدی class استفاده می‌شود ولی در جاوا اسکریپت نیازی به استفاده از این نام کلیدی نیست.

مثال زیر را ببینید:

function Cars(){
	this.maxSpeed= "";
	this.wheel= "";
	
	this.getMaxSpeed= function(){
		return "the max speed is: " + this.maxSpeed + "KM";
	}
	this.getNumOfWheel= function(){
		return "the wheel is: " + this.wheel;
	}
}

var BMW = new Cars();
BMW.maxSpeed= "200";
BMW.wheel= "4";
console.log(BMW.getMaxSpeed());
console.log(BMW.getNumOfWheel());

همانطور که در سطر اول می‌بینید پس از کلمه کلیدی function یک نام آوردیم.

در بلوک برنامه دو ویژگی یا خصیصه به نام‌های maxSpeed و wheel داریم. این دو ویژگی که درون یک کلاس قرار دارند با کلمه کلیدی this تعریف می‌کنیم. منظور از this این است که این خصیصه متعلق به این کلاس است.

getMaxSpeed و getNumOfWheel نیز دو متد هستند که در این کلاس مسئولیت دادن اطلاعات را بر عهده دارند، و همانطور که می‌بینید هر کدام خروجی مناسب به خود را دارد.

در سطر 13 یک شی از روی این کلاس ایجاد می‌کنیم و نام آن را BMW می‌گذاریم.

در سطر 14 دو خصیصه maxSpeed و wheel را مقدار دهی می‌کنیم.

در سطر 15 و 16 دو متد getMaxSpeed و getNumOfWheel را برای این شی جدید اجرا می‌کنیم.

در مثال فوق به دو روش می‌توان مقدار خصیصهها را دریافت کرد:

console.log(BMW.maxSpeed);
console.log(BMW["maxSpeed"]);

در جاوا راه دیگری برای تعریف کلاس‌ها وجود دارد. به مثال زیر دقت کنید:

var Cars= {
	maxSpeed: "",
	wheel: "",
	getMaxSpeed: function(){
		return "the max speed is: " + this.maxSpeed + "KM";
		
	},
	getNumOfWheel: function(){
		return "the wheel is: " + this.wheel;
	}

}
Cars.maxSpeed= "400";
console.log(Cars.getMaxSpeed());

کلاس بالا عملکرد مشابهی با کلاس فوق دارد با این تفاوت که در این جا لازم نیست حتما یک شی از روی کلاس ایجاد کنیم.

هر چند که امکان این کار نیز وجود دارد که کمی پیچیده تر است:

var Cars= {
	maxSpeed: "",
	wheel: "",
	getMaxSpeed: function(){
		return "the max speed is: " + this.maxSpeed + "KM";
		
	},
	getNumOfWheel: function(){
		return "the wheel is: " + this.wheel;
	}

}

var BMW = Object.create(Cars);
BMW.maxSpeed= "400";
console.log(BMW.getMaxSpeed());

مثال بالا کمی پیچیده تر است. ما در سطر 12 شی جدید را با کلمه کلیدی Object و دستور create ایجاد کردیم. نام شی جدید BMW است.

در سطرهای بعدی به سادگی به آن مقدار دهی و مقادیر لازم را چاپ می‌کنیم.

متدهای call و apply

این مبحث که مربوط به بخش‌های پیشرفته javascript است در آینده به کار شما می‌آید. در مباحث پیشرفته از این متدها استفاده خواهد شد. مثال زیر را ببینید:

var BMW= {maxSpeed: "200", wheel: "4"}
var BENZ= {maxSpeed: "220", wheel: "4"}

var getMaxSpeed= function(){
	console.log("the max speed is: " + this.maxSpeed + "KM");
}

var getNumOfWheel= function(){
	console.log("the number of wheel is: " + this.wheel);
}

getMaxSpeed();
getNumOfWheel();

در بالا ابتدا دو آبجکت به نام‌های BMW و BENZ و دو متد به نام‌های getMaxSpeed و getNumOfWheel ایجاد کردیم.

وقتی در دو سطر آخر قصد داریم دو متد getMaxSpeed و getNumOfWheel را استفاده کنیم نتیجه مانند زیر خواهد بود:

the max speed is: undefinedKM
the number of wheel is: undefined

برای ارتباط بین این دو متد و آبجکت‌های BMW و BENZ از متدهای call و apply استفاده می‌شود:

var BMW= {maxSpeed: "200", wheel: "4"}
var BENZ= {maxSpeed: "220", wheel: "4"}

var getMaxSpeed= function(){
	console.log("the max speed is: " + this.maxSpeed + "KM");
}

var getNumOfWheel= function(){
	console.log("the number of wheel is: " + this.wheel);
}

getMaxSpeed.call(BMW);
getNumOfWheel.call(BMW);

که نتیجه مانند زیر خواهد بود:

the max speed is: 200KM
the number of wheel is: 4

اگر به جای call از apply استفاده می‌کردیم نتیجه تفاوتی نمی‌کرد.

می توان call را بیشتر شخصی سازی کرد. مثال فوق را به شکل زیر باز نویسی می‌کنیم:

var BMW= {maxSpeed: "200", wheel: "4"}
var BENZ= {maxSpeed: "220", wheel: "4"}

var getMaxSpeed= function(message, unit){
	console.log(message + this.maxSpeed + unit);	
}

var getNumOfWheel= function(message){
	console.log(message + this.wheel);
}

getMaxSpeed.call(BMW, "the max speed is: ", "KM");
getNumOfWheel.call(BMW, "the number of wheel is: ");

 همانطور که می‌بینید به متد getMaxSpeed دو ورودی دادیم و به متد getNumOfWheel یک ورودی. و آن‌ها را در call استفاده کردیم.

اگر در مثال بالا می‌خواستیم از apply استفاده کنیم مجبور بودیم پارامترها را به عنوان آرایه اعلام کنیم. پس دو خط آخر با وجود apply به شکل زیر خواهند بود:

var BMW= {maxSpeed: "200", wheel: "4"}
var BENZ= {maxSpeed: "220", wheel: "4"}

var getMaxSpeed= function(message, unit){
	console.log(message + this.maxSpeed + unit);	
}

var getNumOfWheel= function(message){
	console.log(message + this.wheel);
}

getMaxSpeed.apply(BMW, ["the max speed is: ", "KM"]);
getNumOfWheel.apply(BMW, ["the number of wheel is: "]);

در ادامه قصد داریم یک تابع برای تغییر مشخصات ماشین‌ها ایجاد کنیم. مثال زیر را ببینید:

var BMW= {maxSpeed: "200", wheel: "4"}
var BENZ= {maxSpeed: "220", wheel: "4"}

var getMaxSpeed= function(message, unit){
	console.log(message + this.maxSpeed + unit);	
}

var getNumOfWheel= function(message){
	console.log(message + this.wheel);
}

var updateCarInfo= function(new_maxSpeed, new_wheel){
	this.maxSpeed = new_maxSpeed;
	this.wheel= new_wheel;
}

updateCarInfo.call(BMW, "230", "4");
getMaxSpeed.call(BMW, "the max speed is: ", "KM");

 تابع updateCarInfo به عنوان ورودی new_maxSpeed و new_wheel را می‌گیرد.

در نهایت مشخصات BMW تغییر کرده و سرعت از 200 به 230 افزایش می‌یابد.

در ادامه یک تابع کلی درست می‌کنیم که کلیه اعمال را به صورت منسجم تر برای ما انجام دهد:

var BMW= {maxSpeed: "200", wheel: "4"}
var BENZ= {maxSpeed: "220", wheel: "4"}

var getMaxSpeed= function(message, unit){
	console.log(message + this.maxSpeed + unit);	
}

var getNumOfWheel= function(message){
	console.log(message + this.wheel);
}

var updateCarInfo= function(new_maxSpeed, new_wheel){
	this.maxSpeed = new_maxSpeed;
	this.wheel= new_wheel;
}

var supperFunction= function(object_name, method_name, args){
	method_name.apply(object_name, args);
}

supperFunction(BMW, getMaxSpeed, ["the max speed is: ", "KM"]);

 در مثال فوق با تابع supperFunction می‌توانید هر سه تابع فوق را فراخوانی کنید. همانطور که می‌بینید این تابع سه ورودی نام آبجکت، نام متد و آرگومان‌ها را از ما می‌خواهد.

در این تابع نا گزیریم از apply استفاده کنیم چون ممکن است args‌ها چند آیتمی باشند.

نتیجه اجرای کدهای فوق نمایش پیغام the max speed is: 200KM خواهد بود.