برنامه نویسی

OOPS در JS – Ultimate

Summarize this content to 400 words in Persian Lang

🔥اتصال: https://www.subham.online

🔥تویتر: https://twitter.com/TheSubhamMaity

▶️ معرفی

⭐ OOPs چیست؟

برنامه نویسی شی گرا رویکردی برای حل مسائل با ایجاد اشیا است.

⭐ 4 ستون OOP

اصطلاحات در OOP

انتزاع – پنهان کردن جزئیات داخلی (فقط اطلاعات ضروری را نشان دهید!)

کپسولاسیون – عمل کنار هم قرار دادن اجزای مختلف (در یک کپسول)

ارث – عمل به دست آوردن چیزهای جدید از چیزهای موجود

چند شکلی – یک موجودیت، اشکال متعدد

▶️ نمونه های اولیه و پروتو

اشیاء جاوا اسکریپت دارای ویژگی خاصی به نام هستند prototype یعنی یا null یا به شی دیگری ارجاع می دهد

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

⭐ تنظیم یک نمونه اولیه

ما می توانیم نمونه اولیه را با تنظیم تنظیم کنیم __proto__. اگر یک ویژگی را از یک شی بخوانیم که در شی نیست اما در نمونه اولیه وجود دارد، جاوا اسکریپت آن را از نمونه اولیه می گیرد. اگر متدی در شیء داشته باشیم از شیء فراخوانی می شود. اگر در شیء موجود نباشد و در نمونه اولیه وجود داشته باشد، از نمونه اولیه فراخوانی می شود.

⭐ مثال:

//It will work properly
let p = {
run : () => {
console.log(“run”)
}
}

p.run()//Output: – run

//Let’s define another property
let a = {
name : ” subham”
}

a.run() //TypeError: a.run is not a function

//Now with proto
let b = {
name : ” subham”
}
b.__proto__ = p
b.run() //Output: – run

وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

به سادگی، شما می توانید نمونه اولیه یک شی را در یک شی دیگر به ارث ببرید. این وراثت نمونه اولیه نامیده می شود.

//It will work properly
let p = {
run : () => {
console.log(“p run”)
}
}

p.run()//Output: – p run

//Now with proto
let b = {
run : () => {
console.log(“b run”)
}
}
b.__proto__ = p
b.run() //Output: – b run

وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

اگر یک ویژگی یا متد از قبل در شی وجود داشته باشد، جاوا اسکریپت از آن ویژگی یا متد استفاده خواهد کرد. اگر در شی وجود نداشته باشد اما در نمونه اولیه وجود داشته باشد، جاوا اسکریپت آن را از نمونه اولیه می گیرد. در این مثال، از آنجایی که run روش قبلاً در b شی، «b run» را چاپ خواهد کرد.

▶️ کلاس ها و شی

در برنامه نویسی شی گرا، کلاس یک تعریف قالبی از متدها و متغیرها در یک نوع خاص از شی است.
در برنامه نویسی شی گرا، یک شی یک نمونه خاص از یک کلاس (یا ساختار) است که در حافظه تخصیص داده شده است.

⭐ مثال:

//class
class GoogleForm {
submit() {
console.log(this.name + ” ” + this.roll + ” Your form submitted”)
}
cancel() {
console.log(this.name + ” ” + this.roll +” Your form cancelled”)
}
fill(given_name , roll) {
this.name = given_name
this.roll = roll
}
}

//object
const student1Form = new GoogleForm()

student1Form.fill(“Rahul” , 24)

const student2Form = new GoogleForm()

student2Form.fill(“Raj” , 25)

student2Form.cancel()

student1Form.submit()

student2Form.submit()

وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

▶️ سازنده

در جاوا اسکریپت، سازنده یک است عملکرد ویژه که اشیاء را ایجاد و مقداردهی اولیه می کند و حالت و خصوصیات اولیه آنها را تنظیم می کند.

فرض کنید آنها فراموش کرده اند فرم را پر کنند و روی دکمه ارسال کلیک کنند و به صورت تعریف نشده پرتاب می شود!

class Form {

submit() {
console.log(this.name + “: Your form is submitted for train number: ” + this.trainno)
}

cancel() {
console.log(this.name + “: This form is cancelled for train number: ” + this.trainno)
this.trainno = 0
}
fill(givenname, trainno) {
this.name = givenname
this.trainno = trainno
}

}

let myForm1 = new Form()

let myForm2 = new Form()
//
// myForm1.fill(“Gaurav”, 1234)
//
// myForm2.fill(“Rahul”, 5678)

myForm1.submit()

myForm2.submit()

myForm2.cancel()

// Output: undefined: Your form is submitted for train number: undefined
// Output: undefined: Your form is submitted for train number: undefined
// Output: undefined: This form is cancelled for train number: undefined

وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

اکنون سازنده ایجاد کنید،

class Form {

constructor() {
this.name = “Gaurav”
this.trainno = 0
}

submit() {
console.log(this.name + “: Your form is submitted for train number: ” + this.trainno)
}

cancel() {
console.log(this.name + “: This form is cancelled for train number: ” + this.trainno)
this.trainno = 0
}
fill(givenname, trainno) {
this.name = givenname
this.trainno = trainno
}

}

let myForm1 = new Form()

let myForm2 = new Form()

// myForm1.fill(“Gaurav”, 1234)
//
// myForm2.fill(“Rahul”, 5678)

myForm1.submit()

myForm2.submit()

myForm2.cancel()

// Output: Gaurav: Your form is submitted for train number: 0
// Output: Gaurav: Your form is submitted for train number: 0
// Output: Gaurav: This form is cancelled for train number: 0

وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

⭐ انواع سازنده

سازنده بدون پارامتر: سازنده ای که آرگومان ندارد.

class Example {
constructor() {
this.property = “default value”;
}
}

وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

سازنده پارامتری شده: سازنده ای که پارامترها را می گیرد.

class Example {
constructor(value) {
this.property = value;
}
}

وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

سازنده کپی: جاوا اسکریپت سازنده کپی داخلی مانند C++ یا جاوا ندارد. با این حال، می توانید روشی برای کپی کردن یک شی ایجاد کنید.

class Example {
constructor(value) {
this.property = value;
}

copy() {
return new Example(this.property);
}
}

const original = new Example(“original value”);
const copy = original.copy();

وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

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

▶️ ارث

توانایی یک کلاس برای استخراج خصوصیات و خصوصیات از کلاس دیگر وراثت نامیده می شود.

⭐ چرا؟

اگر نمی دانید ارث چیست

class Animal {
constructor(name, color , age) {
this.name = name
this.color = color
this.age = age
}
run() {
console.log(this.name + ‘ is running’)
}

shout() {

console.log(this.name + ‘ is shouting’)
}

sleep() {
console.log(this.name + ‘ is sleeping’)
}
}

//If you are nub developer you will do
class Monkey {
constructor(name, color) {
this.name = name
this.color = color
}
run() {
console.log(this.name + ‘ is running’)
}

shout() {

console.log(this.name + ‘ is shouting’)
}

sleep() {
console.log(this.name + ‘ is sleeping’)
}

eatBanana() {
console.log(this.name + ‘ is eating banana’)
}
}

const animal_1 = new Monkey(‘Simba monkey’, ‘Brown’, 2)

const animal_2 = new Animal(‘Donkey’, ‘White’, 3)

animal_1.eatBanana()

animal_2.shout()

وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

اگر می دانید

//Parent Class – Base Class
class Animal {
constructor(name, color , age) {
this.name = name
this.color = color
this.age = age
}
run() {
console.log(this.name + ‘ is running’)
}

shout() {

console.log(this.name + ‘ is shouting’)
}

sleep() {
console.log(this.name + ‘ is sleeping’)
}
}

//Child Class – Derived Class
class Monkey extends Animal{
eatBanana() {
console.log(this.name + ‘ is eating banana’)
}
//you can also add new methods
hide() {
console.log(this.name + ‘ is hiding’)
}
}

const animal_1 = new Monkey(‘Simba monkey’, ‘Brown’, 2)

const animal_2 = new Animal(‘Donkey’, ‘White’, 3)

animal_1.eatBanana()
animal_1.run()
animal_1.hide()

animal_2.shout()

وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

⭐ انواع ارث

وراثت تکی زمانی که یک کلاس کلاس دیگری را به ارث می برد، به عنوان وراثت تک سطحی شناخته می شود.

class Shape {
area() {
console.log(“Displays Area of Shape”);
}
}

class Triangle extends Shape {
area(h, b) {
console.log((1/2) * b * h);
}
}

const triangle = new Triangle();
triangle.area(10, 5); // Output: 25

وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

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

class Shape {
area() {
console.log(“Displays Area of Shape”);
}
}

class Triangle extends Shape {
area(h, b) {
console.log((1/2) * b * h);
}
}

class Circle extends Shape {
area(r) {
console.log(3.14 * r * r);
}
}

const triangle = new Triangle();
triangle.area(10, 5); // Output: 25

const circle = new Circle();
circle.area(7); // Output: 153.86

وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

وراثت چندسطحی فرآیندی است که در آن یک کلاس از یک کلاس مشتق شده دیگر استخراج می شود.

class Shape {
area() {
console.log(“Displays Area of Shape”);
}
}

class Triangle extends Shape {
area(h, b) {
console.log((1/2) * b * h);
}
}

class EquilateralTriangle extends Triangle {
constructor(side) {
super();
this.side = side;
}

area() {
console.log((Math.sqrt(3) / 4) * this.side * this.side);
}
}

const equilateralTriangle = new EquilateralTriangle(5);
equilateralTriangle.area(); // Output: 10.825317547305486

وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

وراثت ترکیبی ترکیبی از وراثت ساده، چندگانه و وراثت سلسله مراتبی است. جاوا اسکریپت به طور مستقیم از وراثت چندگانه پشتیبانی نمی کند، اما می توانیم با استفاده از میکسین به رفتار مشابهی دست یابیم.

class Shape {
area() {
console.log(“Displays Area of Shape”);
}
}

class Triangle extends Shape {
area(h, b) {
console.log((1/2) * b * h);
}
}

class Circle extends Shape {
area(r) {
console.log(3.14 * r * r);
}
}

const mixin = (Base) => class extends Base {
perimeter() {
console.log(“Calculates Perimeter”);
}
};

class EquilateralTriangle extends mixin(Triangle) {
constructor(side) {
super();
this.side = side;
}

area() {
console.log((Math.sqrt(3) / 4) * this.side * this.side);
}
}

const equilateralTriangle = new EquilateralTriangle(5);
equilateralTriangle.area(); // Output: 10.825317547305486
equilateralTriangle.perimeter(); // Output: Calculates Perimeter

وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

▶️ Overriding روش

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

class human {
constructor(name , age , body_type) {
this.name = name
this.age = age
this.body_type = body_type
}

getName() {
console.log(“The name of the human is : “, this.name)
}

getAge() {

console.log(“The age of the human is :”, this.age)
}

getBodyType() {
console.log(“The body type of the human is :”, this.body_type)
}
}

class student extends human {}

const student_1 = new student(“Subham” , 24 , “Thin”)

student_1.getAge() //The age of the human is : 24

وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

⭐ کلید واژه فوق العاده – انواع

کلمه کلیدی super برای فراخوانی سازنده کلاس والد برای دسترسی به ویژگی ها و متدهای آن استفاده می شود.

نادیده گرفتن سازنده

class Human {
constructor(name, age, bodyType) {
this.name = name;
this.age = age;
this.bodyType = bodyType;
}

getName() {
console.log(“The name of the human is:”, this.name);
}

getAge() {
console.log(“The age of the human is:”, this.age);
}

getBodyType() {
console.log(“The body type of the human is:”, this.bodyType);
}
}

class Student extends Human {
constructor() {
super(“Rahul”, 80, “Fat”);
}
}

const student1 = new Student();

student1.getName(); // The name of the human is: Rahul

وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

نادیده گرفتن یک روش

class Human {
constructor(name, age, bodyType) {
this.name = name;
this.age = age;
this.bodyType = bodyType;
}

getName() {
console.log(“The name of the human is:”, this.name);
}

getAge() {
console.log(“The age of the human is:”, this.age);
}

getBodyType() {
console.log(“The body type of the human is:”, this.bodyType);
}
}

class Student extends Human {
constructor() {
super(“Rahul”, 80, “Fat”);
}

// Overriding using super keyword in child class
getAge() {
super.getAge();
console.log(“The age of the student is:”, 20);
}
}

const student1 = new Student();

student1.getAge(); // The age of the human is: 80
// The age of the student is: 20

وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

⭐ نکات کلیدی نادیده گرفتن روش

نام روش مشابه: متد در کلاس فرزند باید همان نام کلاس والد را داشته باشد.
پارامترهای مشابه: متد در کلاس فرزند باید دارای لیست پارامترهای مشابه با متد کلاس والد باشد.
IS-A رابطه: overriding متد فقط در دو کلاس که رابطه IS-A دارند (ارث) اتفاق می افتد.
دسترسی به اصلاح کننده ها: روش overriding می تواند یک اصلاح کننده دسترسی محدودتر داشته باشد، اما نه محدود کننده تر.
کلمه کلیدی فوق العاده: می توانید از super کلمه کلیدی برای فراخوانی متد overrid شده از کلاس والد.

⭐ یادداشت های اضافی

تبصره 1

class human {
constructor() {
console.log(“Human class constructor”)
}
eat() {
console.log(“Human can eat”)
}
}
class student extends human {
}
const student_1 = new student()
student_1.eat()

//Human class constructor
// Human can eat

وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

اگر به صراحت سازنده ای را در یک زیر کلاس تعریف نکنید، جاوا اسکریپت به طور خودکار برای شما یک سازنده ایجاد می کند که سازنده کلاس والد را با استفاده از super() فراخوانی می کند.مثل این

class human {
constructor() {
console.log(“Human class constructor”)
}
eat() {
console.log(“Human can eat”)
}
}
class student extends human {
constructor(…arg) {
super(…arg);
}
}
const student_1 = new student()
student_1.eat()

وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

تبصره 2

class human {
constructor() {
console.log(“Human class constructor”)
}
eat() {
console.log(“Human can eat”)
}
}
class student extends human {
constructor() {
console.log(“This is student class constructor”)
}
}
const student_1 = new student()
student_1.eat()

// console.log(“This is student class constructor”)
//ReferenceError: Must call super constructor in derived class before accessing ‘this’ or returning from derived constructor

وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

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

class human {
constructor() {
console.log(“Human class constructor”)
}
eat() {
console.log(“Human can eat”)
}
}
class student extends human {
constructor() {
super()
console.log(“This is student class constructor”)
}
}
const student_1 = new student()
student_1.eat()

وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

تبصره 3

class human {
constructor(name) {
console.log(“Human class constructor” , name)
this.name = name
}
eat() {
console.log(“Human can eat”)
}
}
class student extends human {
constructor(name) {
this.name = name //not allow
super()
console.log(“Student class constructor” , name)

}
}
const student_1 = new student(“subham”)
student_1.eat()

// this.name = name
// ReferenceError: Must call super constructor in derived class before accessing ‘this’ or returning from derived constructor

وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

بعد از کلمه کلیدی فوق العاده می توانید از این استفاده کنید

class human {
constructor(name) {
console.log(“Human class constructor” , name)
this.name = name
}
eat() {
console.log(“Human can eat”)
}
}
class student extends human {
constructor(name) {
super()
this.name = name
console.log(“Student class constructor” , name)

}
}
const student_1 = new student(“subham”)
student_1.eat()

// Human class constructor undefined
// Student class constructor subham
// Human can eat

وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

▶️ روش اضافه بار

داشتن دو یا چند متد (یا تابع) در یک کلاس با همان نام و آرگومان ها (یا پارامترهای) متفاوت

⭐ آیا می‌توانیم یک تابع را در جاوا اسکریپت بارگذاری کنیم؟

در جاوا اسکریپت، بارگذاری بیش از حد متد، همانطور که در برخی از زبان‌های دیگر (مانند جاوا) دیده می‌شود، به صورت بومی پشتیبانی نمی‌شود. این بدان معناست که شما نمی توانید چندین متد را با نام یکسان اما پارامترهای مختلف در یک کلاس تعریف کنید. با این حال، می‌توانید با استفاده از تکنیک‌هایی مانند بررسی تعداد و نوع آرگومان‌ها در یک متد به عملکردی مشابه دست پیدا کنید.

شما نمی توانید این کار را در JS انجام دهید

class Calculator {
add(a, b) {
return a + b;
}

add(a, b, c) {
return a + b + c;
}
}

const calc = new Calculator();
console.log(calc.add(1, 2)); // This will throw an error because the first add method is overwritten

وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

اگر بخواهید می توانید با این کار به موفقیت برسید

class Calculator {
add(…args) {
if (args.length === 2) {
return args[0] + args[1];
} else if (args.length === 3) {
return args[0] + args[1] + args[2];
} else {
throw new Error(“Invalid number of arguments”);
}
}
}

const calc = new Calculator();

console.log(calc.add(1, 2)); // Output: 3
console.log(calc.add(1, 2, 3)); // Output: 6

وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

▶️ به اصلاح کننده ها دسترسی پیدا کنید

Access Modifier یک کلمه کلیدی است که برای تنظیم دسترسی یک عضو کلاس استفاده می شود

⭐ انواع اصلاح کننده های دسترسی

عمومی: اعضای اعلام شده به عنوان عمومی از هر کلاس دیگری قابل دسترسی هستند.

محافظت شده است: اعضای اعلام شده به عنوان محافظت شده در همان کلاس و توسط نمونه های کلاس مشتق شده قابل دسترسی هستند.

خصوصی: اعضای اعلام شده به عنوان خصوصی فقط در همان کلاس قابل دسترسی هستند.

⭐ جدول دسترسی

اصلاح کننده
کلاس والدین
کلاس کودک
خارج از کلاس

عمومی
✔️
✔️
✔️

محافظت شده است
✔️
✔️

خصوصی
✔️

⭐ مثال

1. اعضای عمومی

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

class Parent {
publicProperty = “I’m public”;

publicMethod() {
return “This is a public method”;
}
}

class Child extends Parent {
useParentPublic() {
console.log(this.publicProperty);
console.log(this.publicMethod());
}
}

const parent = new Parent();
const child = new Child();

console.log(parent.publicProperty); // Output: I’m public
console.log(parent.publicMethod()); // Output: This is a public method
child.useParentPublic();
// Output:
// I’m public
// This is a public method

وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

در این مثال، publicProperty و publicMethod قابل دسترسی هستند از:

در کلاس پدر و مادر
در کلاس کودک
خارج از هر کلاسی

2. اعضای محافظت شده (شبیه سازی شده)

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

class Parent {
_protectedProperty = “I’m protected”;

_protectedMethod() {
return “This is a protected method”;
}
}

class Child extends Parent {
useParentProtected() {
console.log(this._protectedProperty);
console.log(this._protectedMethod());
}
}

const parent = new Parent();
const child = new Child();

child.useParentProtected();
// Output:
// I’m protected
// This is a protected method

// These work, but violate the convention:
console.log(parent._protectedProperty);
console.log(parent._protectedMethod());

وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

در این سناریو:

_protectedProperty و _protectedMethod در Parent قابل دسترسی هستند
آنها همچنین در داخل فرزند (ارث) در دسترس هستند
آنها از نظر فنی در خارج قابل دسترسی هستند، اما این قرارداد را نقض می کند

3. اعضای خصوصی

اعضای خصوصی واقعا خصوصی هستند و فقط در کلاسی که در آن تعریف شده اند قابل دسترسی هستند.

class Parent {
#privateProperty = “I’m private”;

#privateMethod() {
return “This is a private method”;
}

usePrivate() {
console.log(this.#privateProperty);
console.log(this.#privateMethod());
}
}

class Child extends Parent {
tryToUseParentPrivate() {
// These would cause errors if uncommented:
// console.log(this.#privateProperty);
// console.log(this.#privateMethod());
}
}

const parent = new Parent();
const child = new Child();

parent.usePrivate();
// Output:
// I’m private
// This is a private method

// These would cause errors:
// console.log(parent.#privateProperty);
// console.log(parent.#privateMethod());
// child.tryToUseParentPrivate();

وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

در این مورد:

#privateProperty و #privateMethod فقط در داخل والدین قابل دسترسی هستند
آنها در Child در دسترس نیستند، حتی اگر والد را گسترش دهد
اصلاً خارج از کلاس قابل دسترسی نیستند

خوراکی های کلیدی

اعضای عمومی (پیش‌فرض) در همه جا قابل دسترسی هستند.
اعضای حفاظت شده (کنوانسیون با _) در داخل کلاس و زیر کلاس ها قابل دسترسی هستند، اما نباید در خارج به آنها دسترسی داشت (اگرچه از نظر فنی می توان به آنها دسترسی داشت).
اعضای خصوصی (با #) فقط در کلاس تعریف کننده قابل دسترسی هستند، نه در زیر کلاس ها یا خارج.
هنگام استفاده از اعضای محافظت شده، از نظر دسترسی مانند اعضای عمومی رفتار می کنند، اما توسعه دهندگان موافقت می کنند که با آنها به گونه ای رفتار کنند که گویی محافظت شده اند.
حریم خصوصی و کپسوله سازی واقعی تنها با استفاده از اعضای خصوصی به دست می آید # نحو

▶️ ایستا

کلمه کلیدی static یک متد یا فیلد ثابت را برای یک کلاس تعریف می کند

متد استاتیک متدی است که به خود کلاس تعلق دارد، نه به نمونه خاصی از کلاس.

class Animal {
constructor(name) {
this.name = Animal.capitalize(name);
}

static capitalize(name) {
return name.charAt(0).toUpperCase() + name.slice(1);
}

walk() {
console.log(`Animal ${this.name} is walking`);
}
}

const animal = new Animal(“lion”);
animal.walk(); // Output: Animal Lion is walking

console.log(Animal.capitalize(“elephant”)); // Output: Elephant

وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

نکات کلیدی:

این capitalize روش با استفاده از عبارت استاتیک اعلام می شود static کلمه کلیدی
در کلاس نامیده می شود (Animal.capitalize) نه در موارد.
می توان آن را در داخل سازنده یا سایر روش ها با استفاده از نام کلاس استفاده کرد.

⭐ روش های وراثت و استاتیک

روش های استاتیک توسط زیر کلاس ها به ارث می رسند:

class Human extends Animal {
static greet() {
console.log(“Hello!”);
}
}

const human = new Human(“john”);
human.walk(); // Output: Animal John is walking

console.log(Human.capitalize(“sarah”)); // Output: Sarah
Human.greet(); // Output: Hello!

وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

توجه:

این Human کلاس استاتیک را به ارث می برد capitalize روش از Animal.

Human همچنین می تواند روش های استاتیک خود را تعریف کند، مانند greet.

⭐ فراخوانی روش های استاتیک از روش های غیر استاتیک

می توانید متدهای استاتیک را از متدهای غیراستاتیک فراخوانی کنید، اما باید از نام کلاس استفاده کنید:

class Calculator {
static add(a, b) {
return a + b;
}

multiply(a, b) {
// Using a static method in a non-static method
return Calculator.add(a, 0) * b;
}
}

const calc = new Calculator();
console.log(calc.multiply(3, 4)); // Output: 12
console.log(Calculator.add(5, 6)); // Output: 11

وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

⭐ روش‌های استاتیک در مقابل روش‌های نمونه

در اینجا مقایسه ای برای نشان دادن تفاوت وجود دارد:

class MyClass {
static staticMethod() {
return “I’m a static method”;
}

instanceMethod() {
return “I’m an instance method”;
}
}

console.log(MyClass.staticMethod()); // Output: I’m a static method

const obj = new MyClass();
console.log(obj.instanceMethod()); // Output: I’m an instance method

// This would throw an error:
// console.log(MyClass.instanceMethod());

// This would also throw an error:
// console.log(obj.staticMethod());

وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

⭐ موارد استفاده برای روش های استاتیک

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

روش های کارخانه ای: ایجاد نمونه هایی با ویژگی های خاص.

Cache یا Fixed-Configuration: ذخیره داده های مشترک برای همه موارد.

نمونه ای از روش کارخانه ای:

class User {
constructor(name, role) {
this.name = name;
this.role = role;
}

static createAdmin(name) {
return new User(name, “admin”);
}
}

const admin = User.createAdmin(“Alice”);
console.log(admin.role); // Output: admin

وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

⭐ خوراکی های کلیدی

متدهای استاتیک بر روی کلاس تعریف می شوند، نه نمونه ها.
آنها با استفاده از نام کلاس فراخوانی می شوند: ClassName.methodName().
آنها را می توان توسط زیر کلاس ها به ارث برد.
آنها نمی توانند مستقیماً به ویژگی ها یا متدهای نمونه دسترسی داشته باشند.
آنها برای توابع ابزار، روش های کارخانه، و مدیریت داده های سطح کلاس مفید هستند.
شما نمی توانید متدهای استاتیک را در نمونه ها فراخوانی کنید، و نمی توانید متدهای نمونه را در کلاس فراخوانی کنید.

▶️ گیرنده و تنظیم کننده

گیرنده ها و تنظیم کننده ها توابعی هستند که به شما امکان می دهند به ترتیب مقادیر شی را دریافت و تنظیم کنید

//getter setter
class human {
constructor(name, age) {
this._name = name;
}
get getName() {
return this._name;
}
set setName(name) {
this._name = name;
}
}

const person = new human(“”, 0);
person.setName = “Raj”;
person.setAge = 25;

console.log(person.getName);
console.log(person.getAge);

//Raj
//25

وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

▶️ instanceOf Operator

بررسی کنید که آیا یک شی نمونه ای از یک کلاس، زیر کلاس یا رابط است

//getter setter
class human {
constructor(name, age) {
this.name = name;
this.age = age;
}
get getName() {
return this.name;
}
set setName(name) {
this.name = name;
}
get getAge() {
return this.age;
}
set setAge(age) {
this.age = age;
}
}

const person = new human(“”, 0);
person.setName = “Raj”;
person.setAge = 25;

console.log(person.getName);
console.log(person.getAge);

const person1 = “Subham”

console.log( person instanceof human)//true
console.log( person1 instanceof human)//false

وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

همچنین true را برای زیر کلاس برمی گرداند

//getter setter
class human {
constructor(name, age) {
this.name = name;
this.age = age;
}
get getName() {
return this.name;
}
set setName(name) {
this.name = name;
}
get getAge() {
return this.age;
}
set setAge(age) {
this.age = age;
}
}

class Coder extends human {
constructor(name, age, language) {
super(name, age);
this.language = language;
}
}

const person = new human(“”, 0);
const subham = new Coder(“subham”, 22, “java”);
person.setName = “Raj”;
person.setAge = 25;

console.log( person instanceof human)
console.log( subham instanceof human)

وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

بابت سوء تفاهم پیش آمده پوزش می طلبم. حق با شماست، من باید مختصرتر می گفتم. اجازه دهید توضیح ساده‌تر و متمرکزتری درباره کپسوله‌سازی در جاوا اسکریپت ارائه کنم، به دنبال الگویی که نشان داده‌اید:

▶️ کپسولاسیون

کپسولاسیون راهی برای محدود کردن دسترسی مستقیم به برخی از اجزای یک شی است

class BankAccount {
#balance; // Private field

constructor(initialBalance) {
this.#balance = initialBalance;
}

deposit(amount) {
if (amount > 0) {
this.#balance += amount;
}
}

getBalance() {
return this.#balance;
}
}

const account = new BankAccount(1000);
account.deposit(500);
console.log(account.getBalance()); // 1500
// console.log(account.#balance); // Syntax error: private field

وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

//Encapsulation
const user = {
firstName: “John”,
lastName: “Doe”,
age: 25,
getAgeYear: function() {
return new Date().getFullYear() – this.age;
}
}
console.log(user.getAgeYear());

وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

▶️ چند شکلی

Polymorphism به معنای “شکل های متعدد” است و زمانی اتفاق می افتد که ما کلاس های زیادی داشته باشیم که از طریق ارث به یکدیگر مرتبط هستند.

// Parent class
class Animal {
makeSound() {
console.log(“The animal makes a sound”);
}
}

// Child classes
class Dog extends Animal {
makeSound() {
console.log(“The dog barks”);
}
}

class Cat extends Animal {
makeSound() {
console.log(“The cat meows”);
}
}

// Function to demonstrate polymorphism
function animalSound(animal) {
animal.makeSound();
}

// Usage
const animal = new Animal();
const dog = new Dog();
const cat = new Cat();

animalSound(animal); // Output: The animal makes a sound
animalSound(dog); // Output: The dog barks
animalSound(cat); // Output: The cat meows

وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

▶️ انتزاع

انتزاع مفهوم پنهان کردن جزئیات پیاده سازی پیچیده و نشان دادن تنها ویژگی های ضروری یک شی است.

// Abstraction: Hiding complex implementation details and showing only the necessary features of an object.

// Abstract class
class Vehicle {
constructor(brand) {
this.brand = brand;
}

// Abstract method
start() {
throw new Error(“Method ‘start()’ must be implemented.”);
}

getBrand() {
return this.brand;
}
}

// Concrete class
class Car extends Vehicle {
start() {
return `${this.brand} car is starting…`;
}
}

// Usage
const myCar = new Car(“Toyota”);
console.log(myCar.getBrand()); // Output: Toyota
console.log(myCar.start()); // Output: Toyota car is starting…

وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

فهرست مطالب

🔥اتصال: https://www.subham.online

🔥تویتر: https://twitter.com/TheSubhamMaity


▶️ معرفی

⭐ OOPs چیست؟

برنامه نویسی شی گرا رویکردی برای حل مسائل با ایجاد اشیا است.

⭐ 4 ستون OOP

اصطلاحات در OOP

  1. انتزاع – پنهان کردن جزئیات داخلی (فقط اطلاعات ضروری را نشان دهید!)
  2. کپسولاسیون – عمل کنار هم قرار دادن اجزای مختلف (در یک کپسول)
  3. ارث – عمل به دست آوردن چیزهای جدید از چیزهای موجود
  4. چند شکلی – یک موجودیت، اشکال متعدد

▶️ نمونه های اولیه و پروتو

اشیاء جاوا اسکریپت دارای ویژگی خاصی به نام هستند prototype یعنی یا null یا به شی دیگری ارجاع می دهد

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

⭐ تنظیم یک نمونه اولیه

ما می توانیم نمونه اولیه را با تنظیم تنظیم کنیم __proto__. اگر یک ویژگی را از یک شی بخوانیم که در شی نیست اما در نمونه اولیه وجود دارد، جاوا اسکریپت آن را از نمونه اولیه می گیرد. اگر متدی در شیء داشته باشیم از شیء فراخوانی می شود. اگر در شیء موجود نباشد و در نمونه اولیه وجود داشته باشد، از نمونه اولیه فراخوانی می شود.

⭐ مثال:

//It will work properly
let p = {
    run : () => {
        console.log("run")
    }
}

p.run()//Output: - run

//Let's define another property
let a = {
    name : " subham"
}

a.run() //TypeError: a.run is not a function

//Now with proto
let b = {
    name : " subham"
}
b.__proto__ = p
b.run() //Output: - run
وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

به سادگی، شما می توانید نمونه اولیه یک شی را در یک شی دیگر به ارث ببرید. این وراثت نمونه اولیه نامیده می شود.

//It will work properly
let p = {
    run : () => {
        console.log("p run")
    }
}

p.run()//Output: - p run

//Now with proto
let b = {
    run : () => {
        console.log("b run")
    }
}
b.__proto__ = p
b.run() //Output: - b run

وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

اگر یک ویژگی یا متد از قبل در شی وجود داشته باشد، جاوا اسکریپت از آن ویژگی یا متد استفاده خواهد کرد. اگر در شی وجود نداشته باشد اما در نمونه اولیه وجود داشته باشد، جاوا اسکریپت آن را از نمونه اولیه می گیرد. در این مثال، از آنجایی که run روش قبلاً در b شی، «b run» را چاپ خواهد کرد.

▶️ کلاس ها و شی

  • در برنامه نویسی شی گرا، کلاس یک تعریف قالبی از متدها و متغیرها در یک نوع خاص از شی است.
  • در برنامه نویسی شی گرا، یک شی یک نمونه خاص از یک کلاس (یا ساختار) است که در حافظه تخصیص داده شده است.

⭐ مثال:

//class
class GoogleForm {
    submit() {
       console.log(this.name + " " + this.roll + " Your form submitted")
    }
    cancel() {
        console.log(this.name + " " + this.roll +" Your form cancelled")
    }
    fill(given_name , roll) {
        this.name = given_name
        this.roll = roll
    }
}


//object
const student1Form = new GoogleForm()

student1Form.fill("Rahul" , 24)

const student2Form = new GoogleForm()

student2Form.fill("Raj" , 25)

student2Form.cancel()


student1Form.submit()

student2Form.submit()
وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

▶️ سازنده

در جاوا اسکریپت، سازنده یک است عملکرد ویژه که اشیاء را ایجاد و مقداردهی اولیه می کند و حالت و خصوصیات اولیه آنها را تنظیم می کند.

فرض کنید آنها فراموش کرده اند فرم را پر کنند و روی دکمه ارسال کلیک کنند و به صورت تعریف نشده پرتاب می شود!

class Form {

    submit() {
        console.log(this.name + ": Your form is submitted for train number: " + this.trainno)
    }

    cancel() {
        console.log(this.name + ": This form is cancelled for train number: " + this.trainno)
        this.trainno = 0
    }
    fill(givenname, trainno) {
        this.name = givenname
        this.trainno = trainno
    }

}

let myForm1 = new Form()

let myForm2 = new Form()
//
// myForm1.fill("Gaurav", 1234)
//
// myForm2.fill("Rahul", 5678)

myForm1.submit()

myForm2.submit()

myForm2.cancel()

// Output: undefined: Your form is submitted for train number: undefined
// Output: undefined: Your form is submitted for train number: undefined
// Output: undefined: This form is cancelled for train number: undefined

وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

اکنون سازنده ایجاد کنید،

class Form {

    constructor() {
        this.name = "Gaurav"
        this.trainno = 0
    }

    submit() {
        console.log(this.name + ": Your form is submitted for train number: " + this.trainno)
    }

    cancel() {
        console.log(this.name + ": This form is cancelled for train number: " + this.trainno)
        this.trainno = 0
    }
    fill(givenname, trainno) {
        this.name = givenname
        this.trainno = trainno
    }

}

let myForm1 = new Form()

let myForm2 = new Form()

// myForm1.fill("Gaurav", 1234)
//
// myForm2.fill("Rahul", 5678)

myForm1.submit()

myForm2.submit()

myForm2.cancel()

// Output: Gaurav: Your form is submitted for train number: 0
// Output: Gaurav: Your form is submitted for train number: 0
// Output: Gaurav: This form is cancelled for train number: 0
وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

⭐ انواع سازنده

  1. سازنده بدون پارامتر: سازنده ای که آرگومان ندارد.
    class Example {
        constructor() {
            this.property = "default value";
        }
    }
وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

  1. سازنده پارامتری شده: سازنده ای که پارامترها را می گیرد.
    class Example {
        constructor(value) {
            this.property = value;
        }
    }
وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

  1. سازنده کپی: جاوا اسکریپت سازنده کپی داخلی مانند C++ یا جاوا ندارد. با این حال، می توانید روشی برای کپی کردن یک شی ایجاد کنید.
    class Example {
        constructor(value) {
            this.property = value;
        }

        copy() {
            return new Example(this.property);
        }
    }

    const original = new Example("original value");
    const copy = original.copy();
وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

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

▶️ ارث

توانایی یک کلاس برای استخراج خصوصیات و خصوصیات از کلاس دیگر وراثت نامیده می شود.

⭐ چرا؟

اگر نمی دانید ارث چیست

class Animal {
    constructor(name, color , age) {
        this.name = name
        this.color = color
        this.age = age
    }
    run() {
        console.log(this.name + ' is running')
    }

    shout() {

        console.log(this.name + ' is shouting')
    }

    sleep() {
        console.log(this.name + ' is sleeping')
    }
}

//If you are nub developer you will do
class Monkey {
    constructor(name, color) {
        this.name = name
        this.color = color
    }
    run() {
        console.log(this.name + ' is running')
    }

    shout() {

        console.log(this.name + ' is shouting')
    }

    sleep() {
        console.log(this.name + ' is sleeping')
    }

    eatBanana() {
        console.log(this.name + ' is eating banana')
    }
}

const animal_1 = new Monkey('Simba monkey', 'Brown', 2)

const animal_2 = new Animal('Donkey', 'White', 3)

animal_1.eatBanana()

animal_2.shout()
وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

اگر می دانید

//Parent Class - Base Class
class Animal {
    constructor(name, color , age) {
        this.name = name
        this.color = color
        this.age = age
    }
    run() {
        console.log(this.name + ' is running')
    }

    shout() {

        console.log(this.name + ' is shouting')
    }

    sleep() {
        console.log(this.name + ' is sleeping')
    }
}

//Child Class - Derived Class
class Monkey extends Animal{
    eatBanana() {
        console.log(this.name + ' is eating banana')
    }
    //you can also add new methods
    hide() {
        console.log(this.name + ' is hiding')
    }
}

const animal_1 = new Monkey('Simba monkey', 'Brown', 2)

const animal_2 = new Animal('Donkey', 'White', 3)

animal_1.eatBanana()
animal_1.run()
animal_1.hide()

animal_2.shout()
وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

⭐ انواع ارث

  1. وراثت تکی زمانی که یک کلاس کلاس دیگری را به ارث می برد، به عنوان وراثت تک سطحی شناخته می شود.
class Shape {
  area() {
    console.log("Displays Area of Shape");
  }
}

class Triangle extends Shape {
  area(h, b) {
    console.log((1/2) * b * h);
  }
}

const triangle = new Triangle();
triangle.area(10, 5); // Output: 25
وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

  1. وراثت سلسله مراتبی به عنوان فرآیند استخراج بیش از یک کلاس از یک کلاس پایه تعریف می شود.
class Shape {
  area() {
    console.log("Displays Area of Shape");
  }
}

class Triangle extends Shape {
  area(h, b) {
    console.log((1/2) * b * h);
  }
}

class Circle extends Shape {
  area(r) {
    console.log(3.14 * r * r);
  }
}

const triangle = new Triangle();
triangle.area(10, 5); // Output: 25

const circle = new Circle();
circle.area(7); // Output: 153.86
وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

  1. وراثت چندسطحی فرآیندی است که در آن یک کلاس از یک کلاس مشتق شده دیگر استخراج می شود.
class Shape {
  area() {
    console.log("Displays Area of Shape");
  }
}

class Triangle extends Shape {
  area(h, b) {
    console.log((1/2) * b * h);
  }
}

class EquilateralTriangle extends Triangle {
  constructor(side) {
    super();
    this.side = side;
  }

  area() {
    console.log((Math.sqrt(3) / 4) * this.side * this.side);
  }
}

const equilateralTriangle = new EquilateralTriangle(5);
equilateralTriangle.area(); // Output: 10.825317547305486
وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

  1. وراثت ترکیبی ترکیبی از وراثت ساده، چندگانه و وراثت سلسله مراتبی است. جاوا اسکریپت به طور مستقیم از وراثت چندگانه پشتیبانی نمی کند، اما می توانیم با استفاده از میکسین به رفتار مشابهی دست یابیم.
class Shape {
  area() {
    console.log("Displays Area of Shape");
  }
}

class Triangle extends Shape {
  area(h, b) {
    console.log((1/2) * b * h);
  }
}

class Circle extends Shape {
  area(r) {
    console.log(3.14 * r * r);
  }
}

const mixin = (Base) => class extends Base {
  perimeter() {
    console.log("Calculates Perimeter");
  }
};

class EquilateralTriangle extends mixin(Triangle) {
  constructor(side) {
    super();
    this.side = side;
  }

  area() {
    console.log((Math.sqrt(3) / 4) * this.side * this.side);
  }
}

const equilateralTriangle = new EquilateralTriangle(5);
equilateralTriangle.area(); // Output: 10.825317547305486
equilateralTriangle.perimeter(); // Output: Calculates Perimeter
وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

▶️ Overriding روش

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

class human {
    constructor(name , age , body_type) {
        this.name = name
        this.age = age
        this.body_type = body_type
    }

    getName() {
        console.log("The name of the human is : ", this.name)
    }

    getAge() {

        console.log("The age of the human is :", this.age)
    }

    getBodyType() {
        console.log("The body type of the human is :", this.body_type)
    }
}

class student extends human {}

const student_1 = new student("Subham" , 24 , "Thin")

student_1.getAge() //The age of the human is : 24
وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

⭐ کلید واژه فوق العاده – انواع

کلمه کلیدی super برای فراخوانی سازنده کلاس والد برای دسترسی به ویژگی ها و متدهای آن استفاده می شود.

نادیده گرفتن سازنده

class Human {
    constructor(name, age, bodyType) {
        this.name = name;
        this.age = age;
        this.bodyType = bodyType;
    }

    getName() {
        console.log("The name of the human is:", this.name);
    }

    getAge() {
        console.log("The age of the human is:", this.age);
    }

    getBodyType() {
        console.log("The body type of the human is:", this.bodyType);
    }
}

class Student extends Human {
    constructor() {
        super("Rahul", 80, "Fat");
    }
}

const student1 = new Student();

student1.getName(); // The name of the human is: Rahul
وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

نادیده گرفتن یک روش

class Human {
    constructor(name, age, bodyType) {
        this.name = name;
        this.age = age;
        this.bodyType = bodyType;
    }

    getName() {
        console.log("The name of the human is:", this.name);
    }

    getAge() {
        console.log("The age of the human is:", this.age);
    }

    getBodyType() {
        console.log("The body type of the human is:", this.bodyType);
    }
}

class Student extends Human {
    constructor() {
        super("Rahul", 80, "Fat");
    }

    // Overriding using super keyword in child class
    getAge() {
        super.getAge();
        console.log("The age of the student is:", 20);
    }
}

const student1 = new Student();

student1.getAge(); // The age of the human is: 80
                   // The age of the student is: 20

وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

⭐ نکات کلیدی نادیده گرفتن روش

  1. نام روش مشابه: متد در کلاس فرزند باید همان نام کلاس والد را داشته باشد.

  2. پارامترهای مشابه: متد در کلاس فرزند باید دارای لیست پارامترهای مشابه با متد کلاس والد باشد.

  3. IS-A رابطه: overriding متد فقط در دو کلاس که رابطه IS-A دارند (ارث) اتفاق می افتد.

  4. دسترسی به اصلاح کننده ها: روش overriding می تواند یک اصلاح کننده دسترسی محدودتر داشته باشد، اما نه محدود کننده تر.

  5. کلمه کلیدی فوق العاده: می توانید از super کلمه کلیدی برای فراخوانی متد overrid شده از کلاس والد.

⭐ یادداشت های اضافی

تبصره 1

class human {
    constructor() {
        console.log("Human class constructor")
    }
    eat() {
        console.log("Human can eat")
    }
}
class student extends human {
}
const student_1 = new student()
student_1.eat()

//Human class constructor
// Human can eat
وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

اگر به صراحت سازنده ای را در یک زیر کلاس تعریف نکنید، جاوا اسکریپت به طور خودکار برای شما یک سازنده ایجاد می کند که سازنده کلاس والد را با استفاده از super() فراخوانی می کند.
مثل این

class human {
    constructor() {
        console.log("Human class constructor")
    }
    eat() {
        console.log("Human can eat")
    }
}
class student extends human {
    constructor(...arg) {
        super(...arg);
    }
}
const student_1 = new student()
student_1.eat()
وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

تبصره 2

class human {
    constructor() {
        console.log("Human class constructor")
    }
    eat() {
        console.log("Human can eat")
    }
}
class student extends human {
    constructor() {
        console.log("This is student class constructor")
    }
}
const student_1 = new student()
student_1.eat()

// console.log("This is student class constructor")
//ReferenceError: Must call super constructor in derived class before accessing 'this' or returning from derived constructor

وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

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

class human {
    constructor() {
        console.log("Human class constructor")
    }
    eat() {
        console.log("Human can eat")
    }
}
class student extends human {
    constructor() {
        super()
        console.log("This is student class constructor")
    }
}
const student_1 = new student()
student_1.eat()
وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

تبصره 3

class human {
    constructor(name) {
        console.log("Human class constructor" , name)
        this.name = name
    }
    eat() {
        console.log("Human can eat")
    }
}
class student extends human {
    constructor(name) {
        this.name = name //not allow
        super()
        console.log("Student class constructor" , name)

    }
}
const student_1 = new student("subham")
student_1.eat()

// this.name = name
// ReferenceError: Must call super constructor in derived class before accessing 'this' or returning from derived constructor
وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

بعد از کلمه کلیدی فوق العاده می توانید از این استفاده کنید

class human {
    constructor(name) {
        console.log("Human class constructor" , name)
        this.name = name
    }
    eat() {
        console.log("Human can eat")
    }
}
class student extends human {
    constructor(name) {
        super()
        this.name = name
        console.log("Student class constructor" , name)

    }
}
const student_1 = new student("subham")
student_1.eat()

// Human class constructor undefined
// Student class constructor subham
// Human can eat
وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

▶️ روش اضافه بار

داشتن دو یا چند متد (یا تابع) در یک کلاس با همان نام و آرگومان ها (یا پارامترهای) متفاوت

⭐ آیا می‌توانیم یک تابع را در جاوا اسکریپت بارگذاری کنیم؟

در جاوا اسکریپت، بارگذاری بیش از حد متد، همانطور که در برخی از زبان‌های دیگر (مانند جاوا) دیده می‌شود، به صورت بومی پشتیبانی نمی‌شود. این بدان معناست که شما نمی توانید چندین متد را با نام یکسان اما پارامترهای مختلف در یک کلاس تعریف کنید. با این حال، می‌توانید با استفاده از تکنیک‌هایی مانند بررسی تعداد و نوع آرگومان‌ها در یک متد به عملکردی مشابه دست پیدا کنید.

شما نمی توانید این کار را در JS انجام دهید

class Calculator {
    add(a, b) {
        return a + b;
    }

    add(a, b, c) {
        return a + b + c;
    }
}

const calc = new Calculator();
console.log(calc.add(1, 2)); // This will throw an error because the first add method is overwritten
وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

اگر بخواهید می توانید با این کار به موفقیت برسید

class Calculator {
    add(...args) {
        if (args.length === 2) {
            return args[0] + args[1];
        } else if (args.length === 3) {
            return args[0] + args[1] + args[2];
        } else {
            throw new Error("Invalid number of arguments");
        }
    }
}

const calc = new Calculator();

console.log(calc.add(1, 2)); // Output: 3
console.log(calc.add(1, 2, 3)); // Output: 6
وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

▶️ به اصلاح کننده ها دسترسی پیدا کنید

Access Modifier یک کلمه کلیدی است که برای تنظیم دسترسی یک عضو کلاس استفاده می شود

⭐ انواع اصلاح کننده های دسترسی

  1. عمومی: اعضای اعلام شده به عنوان عمومی از هر کلاس دیگری قابل دسترسی هستند.
  2. محافظت شده است: اعضای اعلام شده به عنوان محافظت شده در همان کلاس و توسط نمونه های کلاس مشتق شده قابل دسترسی هستند.
  3. خصوصی: اعضای اعلام شده به عنوان خصوصی فقط در همان کلاس قابل دسترسی هستند.

⭐ جدول دسترسی

اصلاح کنندهکلاس والدینکلاس کودکخارج از کلاس
عمومی✔️✔️✔️
محافظت شده است✔️✔️
خصوصی✔️

⭐ مثال

1. اعضای عمومی

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

class Parent {
    publicProperty = "I'm public";

    publicMethod() {
        return "This is a public method";
    }
}

class Child extends Parent {
    useParentPublic() {
        console.log(this.publicProperty);
        console.log(this.publicMethod());
    }
}

const parent = new Parent();
const child = new Child();

console.log(parent.publicProperty);  // Output: I'm public
console.log(parent.publicMethod());  // Output: This is a public method
child.useParentPublic();
// Output: 
// I'm public
// This is a public method
وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

در این مثال، publicProperty و publicMethod قابل دسترسی هستند از:

  • در کلاس پدر و مادر
  • در کلاس کودک
  • خارج از هر کلاسی

2. اعضای محافظت شده (شبیه سازی شده)

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

class Parent {
    _protectedProperty = "I'm protected";

    _protectedMethod() {
        return "This is a protected method";
    }
}

class Child extends Parent {
    useParentProtected() {
        console.log(this._protectedProperty);
        console.log(this._protectedMethod());
    }
}

const parent = new Parent();
const child = new Child();

child.useParentProtected();
// Output:
// I'm protected
// This is a protected method

// These work, but violate the convention:
console.log(parent._protectedProperty);
console.log(parent._protectedMethod());
وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

در این سناریو:

  • _protectedProperty و _protectedMethod در Parent قابل دسترسی هستند
  • آنها همچنین در داخل فرزند (ارث) در دسترس هستند
  • آنها از نظر فنی در خارج قابل دسترسی هستند، اما این قرارداد را نقض می کند

3. اعضای خصوصی

اعضای خصوصی واقعا خصوصی هستند و فقط در کلاسی که در آن تعریف شده اند قابل دسترسی هستند.

class Parent {
    #privateProperty = "I'm private";

    #privateMethod() {
        return "This is a private method";
    }

    usePrivate() {
        console.log(this.#privateProperty);
        console.log(this.#privateMethod());
    }
}

class Child extends Parent {
    tryToUseParentPrivate() {
        // These would cause errors if uncommented:
        // console.log(this.#privateProperty);
        // console.log(this.#privateMethod());
    }
}

const parent = new Parent();
const child = new Child();

parent.usePrivate();
// Output:
// I'm private
// This is a private method

// These would cause errors:
// console.log(parent.#privateProperty);
// console.log(parent.#privateMethod());
// child.tryToUseParentPrivate();
وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

در این مورد:

  • #privateProperty و #privateMethod فقط در داخل والدین قابل دسترسی هستند
  • آنها در Child در دسترس نیستند، حتی اگر والد را گسترش دهد
  • اصلاً خارج از کلاس قابل دسترسی نیستند

خوراکی های کلیدی

  1. اعضای عمومی (پیش‌فرض) در همه جا قابل دسترسی هستند.
  2. اعضای حفاظت شده (کنوانسیون با _) در داخل کلاس و زیر کلاس ها قابل دسترسی هستند، اما نباید در خارج به آنها دسترسی داشت (اگرچه از نظر فنی می توان به آنها دسترسی داشت).
  3. اعضای خصوصی (با #) فقط در کلاس تعریف کننده قابل دسترسی هستند، نه در زیر کلاس ها یا خارج.
  4. هنگام استفاده از اعضای محافظت شده، از نظر دسترسی مانند اعضای عمومی رفتار می کنند، اما توسعه دهندگان موافقت می کنند که با آنها به گونه ای رفتار کنند که گویی محافظت شده اند.
  5. حریم خصوصی و کپسوله سازی واقعی تنها با استفاده از اعضای خصوصی به دست می آید # نحو

▶️ ایستا

کلمه کلیدی static یک متد یا فیلد ثابت را برای یک کلاس تعریف می کند

متد استاتیک متدی است که به خود کلاس تعلق دارد، نه به نمونه خاصی از کلاس.

class Animal {
    constructor(name) {
        this.name = Animal.capitalize(name);
    }

    static capitalize(name) {
        return name.charAt(0).toUpperCase() + name.slice(1);
    }

    walk() {
        console.log(`Animal ${this.name} is walking`);
    }
}

const animal = new Animal("lion");
animal.walk(); // Output: Animal Lion is walking

console.log(Animal.capitalize("elephant")); // Output: Elephant
وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

نکات کلیدی:

  1. این capitalize روش با استفاده از عبارت استاتیک اعلام می شود static کلمه کلیدی
  2. در کلاس نامیده می شود (Animal.capitalize) نه در موارد.
  3. می توان آن را در داخل سازنده یا سایر روش ها با استفاده از نام کلاس استفاده کرد.

⭐ روش های وراثت و استاتیک

روش های استاتیک توسط زیر کلاس ها به ارث می رسند:

class Human extends Animal {
    static greet() {
        console.log("Hello!");
    }
}

const human = new Human("john");
human.walk(); // Output: Animal John is walking

console.log(Human.capitalize("sarah")); // Output: Sarah
Human.greet(); // Output: Hello!
وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

توجه:

  1. این Human کلاس استاتیک را به ارث می برد capitalize روش از Animal.
  2. Human همچنین می تواند روش های استاتیک خود را تعریف کند، مانند greet.

⭐ فراخوانی روش های استاتیک از روش های غیر استاتیک

می توانید متدهای استاتیک را از متدهای غیراستاتیک فراخوانی کنید، اما باید از نام کلاس استفاده کنید:

class Calculator {
    static add(a, b) {
        return a + b;
    }

    multiply(a, b) {
        // Using a static method in a non-static method
        return Calculator.add(a, 0) * b;
    }
}

const calc = new Calculator();
console.log(calc.multiply(3, 4)); // Output: 12
console.log(Calculator.add(5, 6)); // Output: 11
وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

⭐ روش‌های استاتیک در مقابل روش‌های نمونه

در اینجا مقایسه ای برای نشان دادن تفاوت وجود دارد:

class MyClass {
    static staticMethod() {
        return "I'm a static method";
    }

    instanceMethod() {
        return "I'm an instance method";
    }
}

console.log(MyClass.staticMethod()); // Output: I'm a static method

const obj = new MyClass();
console.log(obj.instanceMethod()); // Output: I'm an instance method

// This would throw an error:
// console.log(MyClass.instanceMethod());

// This would also throw an error:
// console.log(obj.staticMethod());
وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

⭐ موارد استفاده برای روش های استاتیک

  1. توابع سودمند: روش هایی که به حالت شی نیاز ندارند.
  2. روش های کارخانه ای: ایجاد نمونه هایی با ویژگی های خاص.
  3. Cache یا Fixed-Configuration: ذخیره داده های مشترک برای همه موارد.

نمونه ای از روش کارخانه ای:

class User {
    constructor(name, role) {
        this.name = name;
        this.role = role;
    }

    static createAdmin(name) {
        return new User(name, "admin");
    }
}

const admin = User.createAdmin("Alice");
console.log(admin.role); // Output: admin
وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

⭐ خوراکی های کلیدی

  1. متدهای استاتیک بر روی کلاس تعریف می شوند، نه نمونه ها.
  2. آنها با استفاده از نام کلاس فراخوانی می شوند: ClassName.methodName().
  3. آنها را می توان توسط زیر کلاس ها به ارث برد.
  4. آنها نمی توانند مستقیماً به ویژگی ها یا متدهای نمونه دسترسی داشته باشند.
  5. آنها برای توابع ابزار، روش های کارخانه، و مدیریت داده های سطح کلاس مفید هستند.
  6. شما نمی توانید متدهای استاتیک را در نمونه ها فراخوانی کنید، و نمی توانید متدهای نمونه را در کلاس فراخوانی کنید.

▶️ گیرنده و تنظیم کننده

گیرنده ها و تنظیم کننده ها توابعی هستند که به شما امکان می دهند به ترتیب مقادیر شی را دریافت و تنظیم کنید

//getter setter
class human {
    constructor(name, age) {
        this._name = name;
    }
    get getName() {
        return this._name;
    }
    set setName(name) {
        this._name = name;
    }
}

const person = new human("", 0);
person.setName = "Raj";
person.setAge = 25;

console.log(person.getName);
console.log(person.getAge);

//Raj
//25
وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

▶️ instanceOf Operator

بررسی کنید که آیا یک شی نمونه ای از یک کلاس، زیر کلاس یا رابط است

//getter setter
class human {
    constructor(name, age) {
        this.name = name;
        this.age = age;
    }
    get getName() {
        return this.name;
    }
    set setName(name) {
        this.name = name;
    }
    get getAge() {
        return this.age;
    }
    set setAge(age) {
        this.age = age;
    }
}

const person = new human("", 0);
person.setName = "Raj";
person.setAge = 25;

console.log(person.getName);
console.log(person.getAge);

const person1 = "Subham"

console.log( person instanceof human)//true
console.log( person1 instanceof human)//false
وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

همچنین true را برای زیر کلاس برمی گرداند

//getter setter
class human {
    constructor(name, age) {
        this.name = name;
        this.age = age;
    }
    get getName() {
        return this.name;
    }
    set setName(name) {
        this.name = name;
    }
    get getAge() {
        return this.age;
    }
    set setAge(age) {
        this.age = age;
    }
}

class Coder extends human {
    constructor(name, age, language) {
        super(name, age);
        this.language = language;
    }
}

const person = new human("", 0);
const subham = new Coder("subham", 22, "java");
person.setName = "Raj";
person.setAge = 25;


console.log( person instanceof human)
console.log( subham instanceof human)
وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

بابت سوء تفاهم پیش آمده پوزش می طلبم. حق با شماست، من باید مختصرتر می گفتم. اجازه دهید توضیح ساده‌تر و متمرکزتری درباره کپسوله‌سازی در جاوا اسکریپت ارائه کنم، به دنبال الگویی که نشان داده‌اید:

▶️ کپسولاسیون

کپسولاسیون راهی برای محدود کردن دسترسی مستقیم به برخی از اجزای یک شی است

class BankAccount {
    #balance; // Private field

    constructor(initialBalance) {
        this.#balance = initialBalance;
    }

    deposit(amount) {
        if (amount > 0) {
            this.#balance += amount;
        }
    }

    getBalance() {
        return this.#balance;
    }
}

const account = new BankAccount(1000);
account.deposit(500);
console.log(account.getBalance()); // 1500
// console.log(account.#balance); // Syntax error: private field
وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

//Encapsulation
const user = {
    firstName: "John",
    lastName: "Doe",
    age: 25,
    getAgeYear: function() {
        return new Date().getFullYear() - this.age;
    }
}
console.log(user.getAgeYear());
وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

▶️ چند شکلی

Polymorphism به معنای “شکل های متعدد” است و زمانی اتفاق می افتد که ما کلاس های زیادی داشته باشیم که از طریق ارث به یکدیگر مرتبط هستند.

// Parent class
class Animal {
  makeSound() {
    console.log("The animal makes a sound");
  }
}

// Child classes
class Dog extends Animal {
  makeSound() {
    console.log("The dog barks");
  }
}

class Cat extends Animal {
  makeSound() {
    console.log("The cat meows");
  }
}

// Function to demonstrate polymorphism
function animalSound(animal) {
  animal.makeSound();
}

// Usage
const animal = new Animal();
const dog = new Dog();
const cat = new Cat();

animalSound(animal); // Output: The animal makes a sound
animalSound(dog); // Output: The dog barks
animalSound(cat); // Output: The cat meows
وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

▶️ انتزاع

انتزاع مفهوم پنهان کردن جزئیات پیاده سازی پیچیده و نشان دادن تنها ویژگی های ضروری یک شی است.

// Abstraction: Hiding complex implementation details and showing only the necessary features of an object.

// Abstract class
class Vehicle {
    constructor(brand) {
        this.brand = brand;
    }

    // Abstract method
    start() {
        throw new Error("Method 'start()' must be implemented.");
    }

    getBrand() {
        return this.brand;
    }
}

// Concrete class
class Car extends Vehicle {
    start() {
        return `${this.brand} car is starting...`;
    }
}

// Usage
const myCar = new Car("Toyota");
console.log(myCar.getBrand()); // Output: Toyota
console.log(myCar.start());    // Output: Toyota car is starting...
وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

نوشته های مشابه

دیدگاهتان را بنویسید

نشانی ایمیل شما منتشر نخواهد شد. بخش‌های موردنیاز علامت‌گذاری شده‌اند *

دکمه بازگشت به بالا