>  기사  >  웹 프론트엔드  >  JavaScript_javascript 기술에서 클래스를 정의하는 여러 방법 요약

JavaScript_javascript 기술에서 클래스를 정의하는 여러 방법 요약

WBOY
WBOY원래의
2016-05-16 17:05:24939검색

객체지향이라고 하면 클래스, 객체, 캡슐화, 상속, 다형성을 떠올릴 수 있습니다. 책 "javaScript Advanced 프로그래밍"(인민우편통신 출판사, Cao Li 및 Zhang Xin 번역. 영문 이름은 Professional JavaScript for Web Developers)에 설명된 내용이 비교적 자세합니다. JavaScript에서 클래스를 정의하는 다양한 방법을 살펴보겠습니다.

1. 팩토리 메소드

JavaScript에서 자체 클래스와 객체 생성을 마스터해야 합니다. 우리 모두는 다음 코드와 같이 객체가 생성된 후 JavaScript에서 객체의 속성을 동적으로 정의할 수 있다는 것을 알고 있습니다.

코드 복사 코드는 다음과 같습니다.


oCar 객체를 사용하는 것은 쉽지만 우리는 여러 개의 자동차 예제를 만들고 싶습니다. 이를 달성하기 위해 위 코드를 캡슐화하는 함수를 사용할 수 있습니다.


코드 복사 코드는 다음과 같습니다.


그런데 JavaScript 객체의 기본 멤버 속성은 모두 공개입니다. 이 접근 방식을 팩토리 접근 방식이라고 하며, 특정 유형의 개체를 생성하고 반환하는 팩토리를 만듭니다.
좀 흥미롭지만 객체 지향에서 객체를 생성하는 데 자주 사용하는 방법은 다음과 같습니다.
자동차 car=새 차();

new 키워드를 사용하는 것은 사람들의 마음 속에 깊이 뿌리내려 있기 때문에 위의 방법을 사용하여 정의할 때 항상 어색함을 느끼고 호출할 때마다 새로운 속성과 기능이 생성되므로 기능적으로 실용적이지 않습니다. 생성자 클래스의 형식적 정의를 살펴보겠습니다.

2. 생성자

이 방법은 약간 팩토리 함수와 비슷해 보입니다. 구체적인 성능은 다음과 같습니다.


코드 복사 코드는 다음과 같습니다.< script type="text/ javascript">
//정의
function Car(color,doors) {
this.color = color;
this.doors =doors;
this. showColor = function() {
            Alert(this.color); 
        } "blue", 4);
car1.showColor();
car2.showColor();
< ;/스크립트>


효과는 분명한 것 같지만, 차이가 있습니다. 조금 흥미로운 느낌이 듭니다. 생성자 내부에서 객체를 생성하는 것은 this 키워드를 사용하고, new 연산자를 사용하여 객체를 생성하는 것은 매우 친숙한 느낌입니다. 하지만 문제도 있습니다. 새로운 객체가 생성될 때마다 함수 생성을 포함한 모든 속성이 생성됩니다. 즉, 여러 객체가 완전히 독립적이라는 의미입니다. 클래스를 정의하는 목적은 메서드와 데이터를 공유하는 것이지만, car1 객체와 car2 객체는 모두 독립적인 속성과 기능을 위해 최소한 메소드를 공유해야 합니다. 이것이 프로토타입 접근 방식의 장점이다.

3. 프로토타입 제작 방법

객체의 프로토타입 속성을 사용하면 새로운 객체 생성이 의존하는 프로토타입을 볼 수 있습니다. 방법은 다음과 같습니다.

코드 복사 코드는 다음과 같습니다.

< script type="text/javascript ">
//정의
function Car() {
};
Car.prototype.color = "red";
Car.prototype.doors = 4;
Car .prototype.drivers = new Array("Tom", "Jerry");
Car.prototype.showColor = function() {
Alert(this.color);
}
//호출 :
var car1 = new Car();
var car2 = new Car();
car1.showColor();
car2.showColor();
경보(car1.drivers) ;
car1.drivers.push("stephen");
경보(car1.drivers); //결과: Tom, Jerry, stephen
경보(car2.drivers) ; //결과: Tom, Jerry,Stephen

//json을 사용하여 프로토타입 정의를 단순화할 수 있습니다.

Car.prototype =
{
색상: "red",
문: 4,
운전자: ["Tom", "Jerry",'safdad'],
showColor : function() {
                       Alert(this.color); 다음으로 객체의 프로토타입 속성을 통해 Car 객체의 속성을 정의하는 속성을 추가합니다. 이 방법은 좋지만 문제는 Car 객체가 Array 포인터를 가리킨다는 것입니다. 두 Car 객체 모두 동일한 Array 배열을 가리키고 있습니다. 한 객체 car1이 속성 객체(배열 Array)의 참조를 변경하면 다른 객체 car2도 마찬가지입니다. 속성 객체(배열)의 참조를 변경합니다. 동시 변경은 허용되지 않습니다.

동시에 이 문제는 프로토타입이 초기화 매개변수를 사용할 수 없어 생성자가 정상적으로 초기화되지 않는다는 사실에서도 나타납니다. 이를 해결하려면 하이브리드 생성자/프로토타입 패턴이라는 또 다른 방법이 필요합니다.

4. 혼합 생성자/프로토타입 패턴

생성자와 프로토타입을 함께 사용하면 클래스를 정의하는 것이 매우 편리합니다.

코드 복사


코드는 다음과 같습니다.


프로토타입을 이용하여 내부의 속성과 외부의 메소드를 정의하는 방법입니다. 세 번째 방법으로 문제를 해결했습니다.

이 방법은 실제로 매우 친숙해야 하지만 Java의 구문에 비해 약간 부조화적이고 지저분해야 합니다. C의 경우 그다지 번거롭다고 느끼지 않지만 C를 개발할 때 R&D 인력은 일반적으로 JavaScript를 사용하는 경우가 거의 없습니다. J2EE R&D 인력 여러분, 이 접근 방식은 항상 좀 어색합니다. 항상 친근한 패키지가 아닌 것 같은 느낌이 듭니다. 사실, 시각적 캡슐화 효과를 얻고 싶다면 이 방법의 효과를 얻으려면 개인적으로 생각합니다. 그것은 더 문제입니다. 이것이 바로 다이나믹 프로토타이핑 방법이다.

5. 동적 프로토타입

다른 언어 사용에 익숙한 개발자의 경우 혼합 생성자/프로토타입 접근 방식을 사용하는 것이 덜 조화롭게 느껴질 수 있습니다. 결국 대부분의 객체지향 언어는 클래스를 정의할 때 속성과 메서드를 시각적으로 캡슐화합니다. 다음 C# 클래스를 고려하세요.

코드 복사 코드는 다음과 같습니다.

class Car //class
{
공개 문자열 색상 = "red";
공개 int 문 = 4;
공개 int mpg = 23;

public Car(string color, intdoors, int mpg) //constructor
{
this.color = color;
this.doors =doors;
this.mpg = mpg;
}
public void showColor() //method
{
Console.WriteLine(this.color);
}
}


C#은 매우 good Car 클래스의 모든 속성과 메서드를 패키징하므로 ​​이 코드를 보면 어떤 기능을 달성하려는지 알 수 있습니다. 이는 객체의 정보를 정의합니다. 혼합 생성자/프로토타입 접근 방식을 비판하는 사람들은 생성자의 메모리에서 속성을 찾고 그 외부에서 메서드를 찾는 것이 비논리적이라고 주장합니다. 따라서 그들은 보다 친숙한 코딩 스타일을 제공하기 위해 동적 프로토타입 접근 방식을 설계했습니다.

동적 프로토타입 방법의 기본 아이디어는 하이브리드 생성자/프로토타입 접근 방식과 동일합니다. 즉, 비기능적 속성은 생성자 내에서 정의되고, 기능적 속성은 프로토타입 속성을 사용하여 정의됩니다. 유일한 차이점은 객체 메서드가 할당되는 위치입니다. 다음은 동적 프로토타입 메소드로 재작성된 Car 클래스입니다.

코드 복사 코드는 다음과 같습니다.




이 생성자는 Car._initialized 유형이 "정의되지 않음"인지 확인할 때까지 변경되지 않습니다. 이 코드 줄은 동적 프로토타입 방법에서 가장 중요한 부분입니다. 이 값이 정의되지 않은 경우 생성자는 프로토타입을 사용하여 객체의 메서드를 계속 정의한 다음 Car._initialized를 true로 설정합니다. 이 값이 정의되면(해당 값이 true인 경우 typeof 값은 부울임) 메서드가 생성되지 않습니다. 간단히 말해서 이 메서드는 플래그(_initialized)를 사용하여 프로토타입에 할당된 메서드가 있는지 확인합니다. 이 메서드는 한 번만 생성되고 할당됩니다. 기존 OOP 개발자를 만족시키기 위해 이 코드는 다른 언어의 클래스 정의와 더 비슷해 보입니다.

6 혼합공장 방식

이 방법은 일반적으로 이전 방법을 적용할 수 없는 경우 해결 방법입니다. 그 목적은 다른 종류의 객체의 새 인스턴스를 반환하는 가짜 생성자를 만드는 것입니다. 이 코드는 팩토리 함수와 매우 유사해 보입니다.

코드 복사 코드는 다음과 같습니다.

function Car() {
var oTempCar = new Object();
oTempCar.color="red";
oTempCar.doors=4;
oTempCar.mpg=23;
oTempCar.showColor = function() {
                                                                                        ~                                                        , 실제 생성자처럼 보이도록 합니다.
var oCar = new Car();

new 연산자는 Car() 생성자 내부에서 호출되므로 두 번째 new 연산자(생성자 외부에 있음)는 무시됩니다. 생성자 내부에서 생성된 객체는 var 변수로 다시 전달됩니다. 이 접근 방식은 객체 메서드의 내부 관리에 관한 고전적인 접근 방식과 동일한 문제를 가지고 있습니다. 강력한 권장 사항: 꼭 필요한 경우가 아니면 이 방법을 사용하지 마십시오(15장 참조).
요약: (어떤 방법을 사용할 것인가)
현재 가장 널리 사용되는 방법은 생성자/프로토타입 혼합 방법이다. 또한 동적 프로토타입 접근 방식도 널리 사용되며 기능적으로 생성자/프로토타입 접근 방식과 동일합니다. 다음 방법 중 하나를 사용할 수 있습니다. 하지만 고전적인 생성자나 프로토타입 접근 방식만 사용하면 코드에 문제가 발생할 수 있으므로 사용하지 마세요.

코드 복사

코드는 다음과 같습니다.//ps//static class (1 :function) var CarCollection = new function() { var _carCollection = new Array(); //global,private
this.Add = function(objCar) {
Alert( '추가' );
}
this.Get = function(carid) {
Alert('Get');
}
}

//정적 클래스(2:json)


var Car = {
color: 'red', door: 4,

showColor: function() { Alert(this.color) }

}

Car.showColor();


성명:
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.