본 글은 이전 글 자바스크립트 객체지향 프로그래밍(1)기본>의 후속글입니다.
이전 글에서 언급했듯이 자바스크립트에는 클래스라는 개념이 없으며 클래스 정의를 구현하려면 함수를 사용해야 합니다. 먼저 예를 들어 설명하겠습니다.
function myClass ()
{
var id = 1;
var name = "johnson";
//properties
this.ID =
this.Name = 이름; >//method
this.showMessage = function()
{
alert("ID: " this.ID ", 이름: " this.Name)
}
}
var obj1 = new myClass();
var obj2 = new myClass();
함수의 정의는 실제로 클래스의 생성자와 동일하며 마지막 두 문장은 다음과 같습니다. 이 클래스의 인스턴스를 만듭니다. 먼저 첫 번째 문장을 분석해 보겠습니다. var obj1 = new myClass(); 클래스의 인스턴스를 생성하기 위해 new를 사용할 때 인터프리터는 먼저 빈 객체를 생성합니다. 그런 다음 이 myClass 함수를 실행하고 이 포인터가 이 클래스의 인스턴스를 가리키도록 합니다. this.ID = id; 및 this.Name = name; 및 this.showMessage = function(){...}이 발생하면 이 두 속성과 이 메서드가 생성되고 변수 id와 name이 정의됩니다. 값 수준 함수는 이 두 속성과 이 함수 개체(shwoMessage)에 할당됩니다. 이 프로세스는 C#의 생성자와 유사하게 개체를 초기화하는 것과 동일합니다. 마지막으로 new는 이 객체를 반환합니다. 두 번째 문장을 보십시오. var obj2 = new myClass(); 실행 프로세스는 이전 문장과 동일합니다. 즉, 빈 객체를 만든 다음 myClass 함수를 실행하고 두 개의 속성과 메서드를 정의합니다.
위 분석에서 알 수 있듯이 위의 클래스 구현 방법은 함수 정의에서 클래스의 속성 메서드를 정의하는 것입니다. 단점이 있습니다. 위에 표시된 것처럼 이 클래스의 인스턴스를 두 개 이상 생성해야 하는 경우 이러한 속성은 여러 번 생성됩니다.
그럼 이런 상황을 피하는 방법은 무엇일까요? 프로토타입의 활용은 이전 글에서도 언급되었습니다. 프로토타입은 이름과 같은 프로토타입입니다. 각 함수에는 실제로 이 함수 개체의 멤버 컬렉션을 나타내는 하위 개체 프로토타입이 있습니다. 여기서는 클래스를 구현하기 위해 함수를 사용하므로 프로토타입은 실제로 클래스라고 말할 수 있습니다. 회원의. 프로토타입에 의해 정의된 속성과 메서드는 함수 생성자가 실행되기 전에 실행됩니다. 따라서 객체가 새로 생성되기 전에 프로토타입의 멤버가 실제로 실행되었습니다. 먼저 예를 살펴보겠습니다.
함수 myClass()
{
//Constructor
}
myClass.prototype =
{
ID: 1,
이름: "johnson",
showMessage: 함수 ()
{
alert("ID: " this.ID ", 이름: " this.Name)
}
}
var obj1 = new myClass(); var obj2 = new myClass ();
클래스의 구조는 이전 예제와 동일하지만 여기서는 프로토타입을 사용하여 구현됩니다. 먼저 마지막 두 문장을 살펴보겠습니다. 앞서 언급했듯이 프로토타입은 함수 생성자 이전에 실행됩니다. 즉, var obj1 = new myClass();가 실행되기 전에 이 클래스에는 이미 ID, Name 속성 및 showMessage 메서드가 있습니다. 실행자가 문장을 작성할 때 실행 프로세스는 다음과 같습니다. 이전 예제와의 비교에 유의하세요. 먼저 빈 개체를 만들고 이 개체를 가리키는 this 포인터입니다. 그런 다음 함수 프로토타입 객체의 모든 멤버를 이 객체에 할당합니다(이러한 멤버는 다시 생성되지 않습니다). 그런 다음 함수 본문을 실행합니다. 마지막으로 new는 이 객체를 반환합니다. 다음 문장을 실행하는 경우: 이 프로세스도 실행되며 이러한 멤버는 반복적으로 생성되지 않습니다.
위 코드는 단지 예시일 뿐이며, 실제 프로젝트에서는 클래스에 많은 구성원이 있을 수 있으며, 많은 수의 인스턴스를 생성해야 할 수도 있습니다. 이 프로토타입은 그 우수성을 보여줄 것입니다. 또한 위 코드는 중괄호 구문을 사용하여 프로토타입의 멤버를 정의하므로 코드가 더 명확해 보입니다. 이는 권장되는 클래스 디자인 패턴입니다. 물론 많은 프로젝트에서 더 나은 모델을 찾을 수도 있습니다. 또한 더 최적화된 JavaScript 프로그래밍 모델을 통해 새로운 모델을 지속적으로 도입할 수 있기를 바랍니다. 또한 시간이 지남에 따라 모든 주류 브라우저도 JavaScript 구문 분석을 표준화할 수 있기를 바랍니다. .
위에서 언급했듯이 프로토타입에서 정의한 멤버는 생성자보다 먼저 발생합니다. 위의 예에서는 생성자가 비어 있음을 증명할 수 있습니다. var obj1 = new myClass();, 올바른 속성 값을 표시하는 팝업 대화 상자가 표시됩니다.
이 글을 쓰고 나서 많은 형제님들께 댓글도 많이 받았고, 얻은 것도 많았습니다. 위의 예에 대한 추가 설명은 다음 코드입니다.
코드 복사 코드는 다음과 같습니다.
function subClass(){ }
subClass.prototype =
{
이름: "sub"
}
function myClass()
{
/ /Constructor
}
myClass.prototype =
{
ID: 1,
이름: "johnson",
SubObj: new subClass(),
showMessage: 함수( )
{
alert("ID: " this.ID ", 이름: " this.Name "SubObj.Name: " this.SubObj.Name)
}
}
var obj1 = new myClass();
obj1.SubObj.Name = "XXX";
obj1.showMessage()
var obj2 = new myClass()
여기서 참조 유형은 myClass에 정의되어 있으며 해당 유형은 우리가 사용자 정의한 하위 클래스이고 이 하위 클래스에는 Name 속성이 있습니다. 위의 분석에 따르면 프로토타입 객체가 공유되므로 var obj1 = new myClass();를 실행할 때 myClass 프로토타입의 멤버가 이 obj1 인스턴스에 복사됩니다. 그러나 여기서 SubObj는 참조 유형입니다. var obj2 = new myClass();가 실행되면 프로토타입의 ID 및 Name 멤버는 obj2에 복사되지만 SubObj 속성은 복사되지 않지만 프로토타입에서 참조됩니다. . SubObj. 이전 문장에서 obj1.Subobj.Name의 값을 수정했기 때문에 new를 사용하여 obj2 인스턴스를 생성할 때 수정된 값이 참조됩니다.
따라서 프로토타입을 사용하여 클래스를 정의하는 경우 생성자에서 속성을 정의하고 생성자의 프로토타입에서 메서드를 정의해야 합니다.
function myClass(id, name )
{
this.ID = id;
this.Name = 이름;
}
myClass.prototype =
{
showMessage: function()
{
alert("ID: " this.ID ", 이름: " this.Name);
},
showMessage2: function()
{
alert("Method2"); 🎜>}
}
var obj1 = new myClass(1, "johnson")
obj1.showMessage()
obj1.Name="John"
obj1.showMessage( );
var obj2 = new myClass(2, "Amanda");
obj2.showMessage();
프라이빗 멤버, 공유 멤버, 정적 멤버 정보 클래스, 가상 메소드, 클래스 리플렉션 및 기타 구현 메소드는 앞으로도 계속해서 기록될 것입니다. 하지만 제가 작성하려는 내용은 JavaScript의 기본적인 객체지향 구현이라는 점을 말씀드리고 싶습니다. 심층적인 학습이 필요한 경우 Li Zhan 형제의 "만나 모델"을 참조하시기 바랍니다.