JS에서 클래스를 정의하는 방법에는 여러 가지가 있습니다.
1. 팩토리 방식
함수 Car(){
var ocar = 새 개체
ocar.color = "파란색"
ocar.doors = 4
ocar.showColor = function(){
Document.write(this.color)
};
오카 복귀
}
var car1 = 자동차()
var car2 = 자동차()
이 함수가 호출되면 새 개체가 생성되고 모든 속성과 메서드가 해당 개체에 할당됩니다. 이 기능을 사용하여 정확히 동일한 속성을 가진 2개의 개체를 만듭니다. 물론 내 여동생이 매개변수를 전달하여 이 메서드를 수정할 수 있습니다.
기능 자동차(색상,문){
var ocar = 새 개체
ocar.color = 색상
ocar.doors = 문
ocar.showColor = function(){
Document.write(this.color)
};
오카 복귀
}
var car1 = 자동차("빨간색",4)
var car2 = 자동차("파란색",4)
car1.showColor() //출력:"red"
car2.showColor() //출력:"파란색"
이제 함수에 다양한 매개변수를 전달하여 다양한 값을 가진 객체를 얻을 수 있습니다.
이전 예제에서 showcolor()는 Car() 함수가 호출될 때마다 생성됩니다. 즉, 각 객체에는 고유한 showcolor() 메서드가 있습니다.
하지만 사실 각 개체는 동일한 기능을 공유합니다.
함수 외부에서 메서드를 정의한 다음 함수의 속성을 메서드에 지정하는 것도 가능합니다.
함수 showColor(){
경고(this.color)
}
함수 Car(){
var ocar = 새로운 객체()
ocar.color = 색상
ocar.doors = 문
ocar.showColor = 쇼컬러
오카 복귀
}
하지만 이건 함수 메소드처럼 보이지 않습니다.
2. 생성자 방식
생성자 메서드는 아래와 같이 팩토리 메서드만큼 간단합니다.
기능 자동차(색상,도어)
생성자 메소드는 함수 내부에 객체를 생성하지 않고 this 키워드를 사용하는 것을 볼 수 있습니다. 왜냐하면 생성자가 호출될 때 객체가 생성되었고, 이것만 함수 내부의 객체 속성에 접근하는 데 사용될 수 있기 때문입니다.
이제 new를 사용하여 객체를 생성하면 다음과 같습니다! 그러나 이는 공장 접근 방식과 동일합니다. 각 호출은 객체에 대한 자체 메서드를 생성합니다.
3. 프로토타입 제작 방법
이 방법은 객체의 프로토타입 속성을 사용합니다. 먼저 빈 함수를 사용하여 클래스 이름을 만든 다음 모든 속성과 메서드에 프로토타입 속성이 할당됩니다.
함수 Car()
이 코드에서는 먼저 빈 함수를 정의한 후 프로토타입 속성을 통해 객체의 속성을 정의합니다. 이 함수가 호출되면 프로토타입의 모든 속성이 생성될 객체에 즉시 할당됩니다. 이 함수의 모든 객체는 showColor()에 대한 포인터를 저장하며 구문상 모두 동일한 객체에 속하는 것으로 나타납니다.
하지만 이 함수에는 매개변수가 없으며, 매개변수를 전달하여 속성을 초기화할 수 없습니다. 속성의 기본값은 객체 생성 후 변경되어야 합니다.
프로토타입 메서드의 심각한 문제는 속성이 배열과 같은 객체를 가리키는 경우입니다.
코드 복사 코드는 다음과 같습니다.
함수 Car(){
}
Car.prototype.color = "빨간색"
Car.prototype.doors = 4
Car.prototype.arr = new Array("a","b")
Car.prototype.showColor = function(){
경고(this.color)
}
var car1 = 새 자동차()
var car2 = 새 자동차()
car1.arr.push("cc")
경고(car1.arr); //출력:aa,bb,cc
경고(car2.arr); //출력:aa,bb,cc
배열의 참조 값으로 인해 Car의 두 객체가 동일한 배열을 가리키므로 car1에 값을 추가하면 car2에서도 볼 수 있습니다.
Union은 다른 프로그래밍 언어와 마찬가지로 생성자/프로토타입 메소드를 사용하여 객체를 생성하는 메소드이며, 객체의 비함수적 속성을 정의하기 위해 생성자를 사용하고, 객체를 정의하기 위해 프로토타입 메소드를 사용합니다.
기능 자동차(색상,문){
This.color = 색상
This.doors = 문
This.arr = new Array("aa","bb")
}
Car.prototype.showColor(){
경고(this.color)
}
var car1 = 새 자동차("빨간색",4)
var car2 = 새 자동차("파란색",4)
car1.arr.push("cc")
경고(car1.arr); //출력:aa,bb,cc
경고(car2.arr); //출력:aa,bb
4. 동적 프로토타입 방식
동적 프로토타입 방식의 원리는 생성자/프로토타입 혼합 방식의 원리와 유사합니다. 유일한 차이점은 객체 메서드가 할당되는 위치입니다.
기능 자동차(색상,문){
This.color = 색상
This.doors = 문
This.arr = new Array("aa","bb")
If(자동차 유형_초기화 == "정의되지 않음"){
Car.prototype.showColor = function(){
경고(this.color)
};
Car._initialized = true
}
}
동적 프로토타입 메서드는 플래그를 사용하여 메서드가 프로토타입에 할당되었는지 여부를 확인합니다. 이렇게 하면 메소드가 한 번만 생성됩니다.
6. 믹싱팩토리 방식
그 목적은 다른 개체의 새 인스턴스를 반환하는 가짜 생성자를 만드는 것입니다.
함수 Car(){
var ocar = 새로운 객체()
ocar.color = "빨간색"
ocar.doors = 4
ocar.showColor = function(){
경고(this.color)
};
오카 복귀
}
팩토리 메소드와의 차이점은 new 연산자를 사용한다는 점입니다.
PS(개인적 이해):
1) 프로토타입을 통해 클래스에서 정의한 멤버(메서드 또는 속성)는 모든 클래스 객체에 공통되며 일반적으로 하나의 객체가 속성 값을 수정하면 모든 객체가 수정됩니다. >
2) 클래스에는 프로토타입 속성이 있지만 클래스 객체에는 없습니다.
3) 새로운 클래스 객체나 클래스가 직접 호출될 때마다(아래 팩토리 메소드 형식), 클래스(함수)를 정의하는 명령문이 한 번 실행됩니다(싱글톤 모드에서는 이러한 상황을 피할 수 있습니다).
4) 클래스는 함수 유형이고, 클래스 객체는 객체 유형이며, 함수 유형에만 프로토타입 속성이 있습니다.
5) 프로토타입에서 정의한 메소드는 클래스의 프라이빗 변수(클래스에서 정의한 지역 변수)에는 접근할 수 없으나, 이를 통해 클래스의 멤버 속성과 멤버 메소드(이에서 정의한 변수 및 메소드)에는 접근할 수 있다.
6) 클래스 정의 방법:
가. 팩토리 메소드(객체)
b. 상속 방법(프로토타입)
c. 생성자 메서드(this)
d. 혼합방법
7) [질문] 프로토타입을 통해 정의된 속성이 왜 어떤 객체에 의해 변경될 수 있나요? 그리고 생성자 메소드에 정의된 속성은 해당 객체에만 속하고 다른 객체의 속성값에는 영향을 주지 않는다는 건가요?
위의 내용은 모두 객체를 생성하는 방법입니다. 현재 가장 널리 사용되는 방법은 생성자/프로토타입 혼합 방법이며, 동적 프로토타입 방법도 매우 널리 사용됩니다. 기능적으로 생성자/프로토타입 접근 방식과 동일합니다.