JavaScript의 프로토타입 개념은 이 단어의 의미를 적절하게 반영합니다. C의 프로토타입처럼 미리 선언된 개념으로는 이해할 수 없습니다.
JavaScript의 모든 함수 유형 객체에는 프로토타입 속성이 있습니다. 프로토타입 속성 자체는 객체 유형 객체이므로 이 프로토타입 객체에 임의의 속성과 메서드를 추가할 수도 있습니다. 프로토타입은 객체의 "프로토타입"이므로 이 함수로 생성된 객체는 이 "프로토타입"의 특성을 가져야 합니다. 실제로 생성자의 프로토타입에 정의된 모든 속성과 메서드는 생성된 개체를 통해 직접 액세스하고 호출할 수 있습니다. 또한 프로토타입은 유사한 객체 그룹이 속성과 메서드를 공유할 수 있는 메커니즘을 제공한다고 말할 수도 있습니다.
먼저 다음 코드를 살펴보겠습니다.
function Person(name)
{
this.name = name; //객체 속성을 설정합니다. 각 객체에는 고유한 속성 데이터가 있습니다.
};
Person.prototype.SayHello = function() //Person 함수의 프로토타입에 SayHello 메서드를 추가합니다.
{
alert("안녕하세요, 저는 " this.name);
}
var BillGates = new Person("Bill Gates") //BillGates 객체 생성
var SteveJobs = new Person("Steve Jobs"); //SteveJobs 객체 생성
BillGates.SayHello(); //BillGates 객체를 통해 SayHello 메서드를 직접 호출
SteveJobs.SayHello(); SteveJobs 객체 SayHello 메소드로 이동
alert(BillGates.SayHello == SteveJobs.SayHello); //두 객체가 SayHello의 프로토타입을 공유하므로 다음과 같이 표시됩니다.
프로그램 실행 결과는 생성자는 프로토타입에 정의되어 있습니다. 메소드는 실제로 객체를 통해 직접 호출될 수 있으며 코드는 공유됩니다. 물론 메소드를 프로토타입으로 설정하는 방식이 훨씬 더 우아합니다. 호출 형식은 변경되지 않았지만 메소드와 클래스 간의 관계를 논리적으로 반영하므로 이전 작성 방식에 비해 이해하기 쉽고 정리하기 쉽습니다. 코드.
그렇다면 다중 레벨 유형의 생성자는 어떻습니까?
다음 코드를 다시 살펴보겠습니다.
1 function Person(name) //기본 클래스 생성자
2 {
3 this.name = name
4 };
6 Person.prototype.SayHello = function() //기본 클래스 생성자의 프로토타입에 메서드 추가
7 {
8 Alert("안녕하세요, 저는 " this.name); 🎜> 9 };
10
11 function Employee(이름, 급여) //하위 클래스 생성자
12 {
13 Person.call(this, name) 호출
14 this.salary = 급여;
15 };
16
17 Employee.prototype = new Person(); //하위 클래스 프로토타입의 프로토타입으로 기본 클래스 객체를 생성합니다. .
18
19 Employee.prototype.ShowMeTheMoney = function() //서브클래스 생성자의 프로토타입에 메서드 추가
20 {
21 Alert(this.name " $" this.salary ) ;
22 };
23
24 var BillGates = new Person("Bill Gates"); //기본 클래스 Person의 BillGates 객체 생성
25 var SteveJobs = new Employee("Steve Jobs" , 1234); //Employee 하위 클래스의 SteveJobs 객체 생성
26
27 BillGates.SayHello(); //객체를 통해 프로토타입 메서드 직접 호출
28 SteveJobs.SayHello(); //Pass 하위 클래스 객체는 기본 클래스 프로토타입의 메서드를 직접 호출합니다. 주의하세요!
29 SteveJobs.ShowMeTheMoney(); // 하위 클래스 객체를 통해 하위 클래스 프로토타입의 메서드를 직접 호출합니다.
30
31 Alert(BillGates.SayHello == SteveJobs.SayHello); 프로토타입 메서드가 공유됨을 나타냅니다.
이 코드의 17번째 줄은 기본 클래스 객체를 생성하고 이를 하위 클래스 생성자의 프로토타입으로 설정하는데, 이는 매우 흥미롭습니다. 28행에 대한 목적입니다. 기본 클래스 프로토타입의 메서드는 하위 클래스 개체를 통해 직접 호출할 수도 있습니다. 이것이 가능한 이유는 무엇입니까?
JavaScript에서 프로토타입은 객체가 자신의 부를 공유할 수 있도록 할 뿐만 아니라 뿌리와 조상을 추적하는 특성도 갖고 있어 조상의 유산이 대대로 이어질 수 있다는 것이 밝혀졌습니다. 객체에서 속성을 읽거나 메소드를 호출할 때 객체 자체에 그러한 속성이나 메소드가 없으면 프로토타입에 해당 속성이나 메소드가 없으면 해당 객체와 연관된 프로토타입 객체로 이동합니다. 프로토타입 자체와 연관된 프로토타입을 찾거나 추적 프로세스가 완료될 때까지 검색합니다.
JavaScript 내부에서는 객체의 속성 및 메서드 추적 메커니즘이 소위 프로토타입 체인을 통해 구현됩니다. new 연산자를 사용하여 객체를 생성하면 생성자의 프로토타입 객체도 새로 생성된 객체에 할당되어 해당 객체의 내장 프로토타입 객체가 됩니다. 객체의 내장 프로토타입 객체는 외부 세계에 보이지 않아야 합니다. 일부 브라우저(예: Firefox)에서는 이 내장 프로토타입 객체에 액세스할 수 있지만 이는 권장되지 않습니다. 내장된 프로토타입 객체 자체도 객체이며 자신과 연관된 프로토타입 객체를 가지므로 소위 프로토타입 체인을 형성합니다.
프로토타입 체인의 끝에는 Object 생성자의 프로토타입 속성이 가리키는 프로토타입 객체가 있습니다. 이 프로토타입 객체는 모든 객체 중 가장 오래된 조상입니다. 이 조상은 모든 객체가 본질적으로 가지고 있어야 하는 toString과 같은 메서드를 구현합니다. Function, Boolean, String, Date 및 RegExp와 같은 다른 내장 생성자의 프로토타입은 모두 이 조상으로부터 상속되지만 각각 고유한 속성과 메서드를 정의하므로 자손이 해당 클랜의 특성을 표시합니다. 그 특성.
이거 그냥 '상속'아닌가요? 예, 이것은 JavaScript 고유의 "프로토타입 상속"인 "상속"입니다.
"프로토타입 상속"은 친절하면서도 가혹합니다. 프로토타입 객체는 자신의 속성과 메서드를 아이들에게 사심 없이 제공하고 아이들이 따르도록 강요하지 않으므로 일부 장난꾸러기 아이들이 자신의 관심과 취미에 따라 독립적으로 행동할 수 있습니다. 그런 점에서 원형적 주체는 사랑하는 어머니이다. 그러나 어떤 어린이라도 자신의 길을 갈 수는 있지만 프로토타입 개체의 기존 속성을 건드릴 수는 없습니다. 왜냐하면 다른 어린이의 이익에 영향을 미칠 수 있기 때문입니다. 이런 관점에서 프로토타입 객체는 엄격한 아버지와 같습니다. 이것이 무엇을 의미하는지 이해하기 위해 다음 코드를 살펴보겠습니다.
function Person(name)
{
this.name = name
}
Person.prototype.company = " Microsoft"; //프로토타입 속성
Person.prototype.SayHello = function() //프로토타입 메서드
{
alert("안녕하세요. 저는 " this.company 의 " this.name "입니다.);
};
var BillGates = new Person("Bill Gates");
BillGates.SayHello(); //프로토타입 상속으로 인해 출력이 정상입니다. 안녕하세요, 저는 Bill Gates입니다. 🎜>var SteveJobs = new Person("Steve Jobs");
SteveJobs.company = "Apple"; //프로토타입의 회사 속성을 덮어 자신만의 회사 속성을 설정합니다.
SteveJobs.SayHello = function () / /프로토타입의 SayHello 메서드를 은폐하여 나만의 SayHello 메서드를 구현했습니다.
{
alert("Hi, " this.name " like " this.company ", 하하하 ")
SteveJobs.SayHello(); //그들은 모두 자체적으로 적용되는 속성과 메서드입니다. 출력: 안녕하세요, Apple과 같은 Steve Jobs입니다. 하하하
BillGates.SayHello() //SteveJobs를 덮어쓰는 것은 효과가 없습니다. 프로토타입 객체인 경우에도 BillGates는 이전과 동일하게 출력합니다.
객체는 프로토타입 객체의 속성과 메서드를 마스킹할 수 있습니다. 생성자 프로토타입 객체는 상위 계층 생성자 프로토타입 객체의 기존 속성과 메서드도 마스킹할 수 있습니다. 이 마스킹은 실제로 객체 자체에 새로운 속성과 메서드를 생성하지만 이러한 속성과 메서드는 프로토타입 객체의 이름과 동일합니다. JavaScript는 이 간단한 마스킹 메커니즘을 사용하여 객체의 "다형성"을 달성합니다. 이는 가상 함수의 개념과 일치하며 정적 객체 언어의 재정의입니다.
그러나 정적 객체 언어보다 더 놀라운 점은 언제든지 프로토타입 객체에 새로운 속성과 메서드를 동적으로 추가하여 기본 클래스의 기능을 동적으로 확장할 수 있다는 것입니다. 이는 정적 객체 언어에서는 상상하기 어렵습니다. 다음 코드를 살펴보겠습니다.
function Person(name)
{
this.name = name
}
Person.prototype.SayHello = function() //생성하기 전 객체 정의 메소드
{
alert("안녕하세요, 저는 " this.name);
}
var BillGates = new Person("Bill Gates"); >BillGates.SayHello();
Person.prototype.Retire = function() //객체 생성 후 프로토타입을 동적으로 확장하는 방법
{
alert("Poor " this.name ", 안녕 ! ");
};
BillGates.Retire(); //동적으로 확장된 메서드는 이전에 생성된 객체에 의해 즉시 호출될 수 있습니다.
아미타바, 프로토타입 상속은 실제로 이러한 마법을 발휘할 수 있습니다!
프로토타입 확장
매우 높은 수준의 이해가 있어야 합니다. 다음과 같이 생각할 수도 있습니다. Object 및 Function과 같은 JavaScript 내장 함수의 프로토타입에 몇 가지 새로운 메서드와 속성을 추가하면 확장할 수 있습니까? JavaScript는 어떻습니까?
그래서 축하합니다!
오늘날 AJAX 기술의 급속한 발전으로 인해 많은 성공적인 AJAX 프로젝트의 JavaScript 런타임 라이브러리는 내장 기능의 프로토타입 기능을 크게 확장했습니다. 예를 들어, Microsoft의 ASP.NET AJAX는 이러한 내장 함수와 해당 프로토타입에 수많은 새로운 기능을 추가하여 JavaScript의 기능을 향상시킵니다.
MicrosoftAjax.debug.js에서 발췌한 코드를 살펴보겠습니다.
String.prototype.trim = function String$trim() {
if (arguments.length !== 0) throw Error. 매개변수카운트();
return this.replace(/^s |s $/g, '');
}
이 코드는 내장 문자열 함수의 프로토타입으로 트림 메소드를 확장합니다. 이제 모든 String 클래스 객체에 Trim 메소드가 있습니다. 이 확장을 사용하면 나중에 문자열의 두 섹션 사이의 공백을 제거하려는 경우 더 이상 별도로 처리할 필요가 없습니다. 모든 문자열에 이 확장 함수가 있고 호출하기만 하면 되기 때문입니다. 편리한.
물론, Object의 프로토타입에 메소드를 추가하는 사람은 거의 없습니다. 왜냐하면 이 메소드가 실제로 아키텍처의 모든 객체에 필요한 경우를 제외하고는 모든 객체에 영향을 미치기 때문입니다.
2년 전, AJAX 클래스 라이브러리 설계 초기에 마이크로소프트는 '클래스'를 시뮬레이션하기 위해 '클로저'라는 기술을 사용했습니다.대략적인 모델은 다음과 같습니다.
function Person(firstName, lastName, age)
{
//개인 변수:
var _firstName = firstName;
var _lastName = lastName; // 공개 변수:
this.age = age;
//메서드:
this.getName = function()
{
return(firstName " " lastName); ;
this.SayHello = function()
{
alert("안녕하세요. 저는 "firstName" "lastName입니다)
}
var BillGates = new Person( "Bill", "Gates", 53);
var SteveJobs = new Person("Steve", "Jobs", 53)
BillGates.SayHello()
SteveJobs.SayHello() ;
alert(BillGates.getName() " " BillGates.age);
alert(BillGates.firstName); //여기에서는 개인 변수에 액세스할 수 없습니다.
분명히 이 모델의 클래스 설명은 다음과 같습니다. C# 언어 설명 형식은 생성자에서 전용 멤버, 공용 속성 및 사용 가능한 메서드를 정의하는데 이는 매우 우아합니다. 특히, "폐쇄" 메커니즘은 개인 구성원의 보호 메커니즘을 시뮬레이션할 수 있는데 이는 매우 아름답습니다.
소위 "클로저"는 생성자 본문에 다른 함수를 대상 개체의 메서드 함수로 정의하고, 이 개체의 메서드 함수는 차례로 외부 외부 함수 본문에 있는 임시 변수를 참조하는 것입니다. 이를 통해 대상 개체가 수명 동안 항상 해당 메서드를 유지할 수 있는 한 원래 생성자 본문에서 사용된 임시 변수 값을 간접적으로 유지할 수 있습니다. 초기 생성자 호출이 종료되고 임시변수의 이름은 사라졌지만, 변수의 값은 항상 대상 객체의 메소드에서 참조할 수 있으며, 이 메소드를 통해서만 값에 접근할 수 있다. 동일한 생성자를 다시 호출하더라도 새 객체와 메서드만 생성됩니다. 새 임시 변수는 새 값에만 해당하며 마지막 호출과 독립적입니다. 정말 영리해요!
하지만 앞서 말했듯이 객체별로 메서드를 설정하는 것은 큰 낭비입니다. 또한 변수 값을 간접적으로 유지하는 메커니즘인 "클로저"는 JavaScript의 가비지 수집기에 문제를 일으키는 경우가 많습니다. 특히 객체 간에 복잡한 순환 참조가 발생할 경우 가비지 수집의 판단 논리가 매우 복잡해집니다. 우연히도 IE의 초기 버전에는 JavaScript 가비지 수집에서 메모리 누수가 발생했습니다. 성능 테스트에서 "폐쇄" 모델의 열악한 성능과 함께 Microsoft는 마침내 "폐쇄" 모델을 포기하고 "프로토타입" 모델로 전환했습니다. "얻은 것은 반드시 손실이 따른다"는 말이 있습니다.
프로토타입 모델에는 객체의 멤버를 정의하기 위한 생성자가 필요하며 생성자의 프로토타입에 메소드가 첨부됩니다. 대략적인 내용은 다음과 같습니다.
//생성자 정의
function Person(name)
{
this.name = name; //생성자에 멤버 정의
}; >/ /메서드는 생성자의 프로토타입에 정의됩니다.
Person.prototype.SayHello = function()
{
alert("안녕하세요, 저는 " this.name); ;
//하위 클래스 생성자
function Employee(이름, 급여)
{
Person.call(this, 이름) //상위 생성자 호출
this.salary = 급여; //확장 멤버
};
//상속 개념을 실현하려면 먼저 상위 클래스 생성자를 사용하여 프로토타입 객체를 생성해야 합니다.
Employee.prototype = new Person() // 프로토타입 메소드만 필요하며 이 객체의 멤버는 의미가 없습니다!
//하위 클래스 메서드도 생성자 위에 정의됩니다.
Employee.prototype.ShowMeTheMoney = function()
{
alert(this.name " $" this.salary)
};
var BillGates = new Person("Bill Gates");
BillGates.SayHello();
var SteveJobs = new Employee("Steve Jobs", 1234)
SteveJobs.SayHello( );
SteveJobs.ShowMeTheMoney();
프로토타입 클래스 모델은 실제 개인 변수를 시뮬레이션할 수 없지만 클래스를 정의하기 위해 두 부분으로 나누어야 하는데 이는 그다지 "우아하지" 않습니다.그러나 메소드는 객체 간에 공유되고 가비지 수집 문제가 발생하지 않으며 "클로저" 모델보다 더 나은 성능을 발휘합니다. "잃어버린 모든 것에는 반드시 이득이 있다"는 말이 있습니다.
프로토타입 모델에서 클래스 상속을 구현하려면 먼저 하위 클래스 생성자의 프로토타입을 상위 클래스의 객체 인스턴스로 설정해야 합니다. 이 부모 클래스 객체 인스턴스를 생성하는 목적은 상위 프로토타입 메소드를 공유하기 위한 프로토타입 체인을 형성하는 것입니다. 그러나 이 인스턴스 개체가 생성되면 상위 수준 생성자도 개체 멤버를 설정합니다. 이러한 개체 멤버는 상속에 의미가 없습니다. 생성자에 매개변수를 전달하지 않았음에도 불구하고 쓸모없는 멤버를 여러 개 생성했는데, 그 값이 정의되지 않았음에도 불구하고 이는 낭비이기도 합니다.
아아! 세상에 완벽한 것은 없습니다!
원형의 진실
우리가 감동에 휩싸이던 그 순간, 하늘에서 붉은 빛이 번쩍였고, 상서로운 구름 속에서 관음보살이 나타났다. 나는 그녀가 옥 정화병을 들고, 녹색 버드나무 가지를 휘두르고, 꿀 몇 방울을 뿌리는 것을 보았고, 이는 즉시 JavaScript에 새로운 기운을 불어넣었습니다.
관음이 뿌린 과즙은 자바스크립트 세계에서 블록으로 응축되어 '문법 과즙'이라는 것이 되었습니다. 이 구문적 꿀은 우리가 작성하는 코드를 객체 언어처럼 보이게 만들 수 있습니다.
이 "문법적 꿀"이 무엇인지 알고 싶다면 잘 들어보세요.
이러한 문법적 꿀팁을 이해하기 전에 JavaScript에서 객체를 구성하는 과정을 검토해야 합니다.
우리는 var anObject = new aFunction() 형식으로 객체를 생성하는 과정이 실제로 세 단계로 나눌 수 있다는 것을 이미 알고 있습니다. 첫 번째 단계는 새 객체를 생성하는 것이고, 두 번째 단계는 빌드된 객체를 설정하는 것입니다. - 객체의 프로토타입 객체를 생성자에 함수 프로토타입이 참조하는 프로토타입 객체의 세 번째 단계는 멤버 설정과 같은 초기화 작업을 완료하기 위해 객체를 이 매개변수로 사용하여 생성자를 호출하는 것입니다. 객체가 생성된 후 객체에 대한 모든 액세스 및 작업은 객체 자체 및 프로토타입 체인의 객체 문자열에만 관련되며 생성자와는 아무 관련이 없습니다. 즉, 생성자는 객체 생성 시 프로토타입 객체를 도입하고 객체를 초기화하는 역할만 합니다.
그럼 우리가 직접 객체를 프로토타입으로 정의하고, 이 프로토타입에 클래스를 기술한 후, 새로 생성된 객체에 이 프로토타입을 설정하고 객체의 클래스로 처리할 수 있을까요? 새로 생성된 객체를 초기화하기 위해 이 프로토타입의 메서드를 생성자로 사용할 수 있습니까? 예를 들어, 다음과 같은 프로토타입 객체를 정의합니다.
var Person = //객체를 프로토타입 클래스로 정의
{
Create: function(name, age) //생성자로 사용됩니다. function
{
this.name = name;
this.age = age
},
SayHello: function() //메소드 정의
{
alert("안녕하세요, 저는 " this.name);
},
HowOld: function() //메서드 정의
{
alert(this.name "은 " this.age "세입니다.") ;
}
};
이 JSON이 작성된 방식은 C# 클래스와 같습니다! 생성자와 다양한 메서드가 모두 있습니다. 어떤 형태로든 객체를 생성하고 그 객체의 내장 프로토타입을 위의 "클래스" 객체로 설정할 수 있다면, 그 클래스의 객체를 생성하는 것과 같지 않을까요?
하지만 안타깝게도 객체의 내장 프로토타입 속성에 거의 액세스할 수 없습니다! 일부 브라우저는 객체의 내장 프로토타입에 액세스할 수 있지만 그렇게 하면 사용자가 사용해야 하는 브라우저만 제한됩니다. 이것도 거의 불가능합니다.
그럼 함수 객체를 매개로 함수 객체의 프로토타입 속성을 사용해 프로토타입을 전달하고, new 연산자를 사용해 새로 생성된 객체에 전달할 수 있을까요?
실제로 다음과 같은 코드로 이 목표를 달성할 수 있습니다.
function anyfunc(){}; //함수 셸 정의
anyfunc.prototype = Person; //프로토타입 객체를 전송 스테이션 프로토타입에 넣습니다.
var BillGates = new anyfunc(); //새 객체의 내장 프로토타입은 우리가 기대하는 프로토타입 객체가 됩니다.
그러나 이 anyfunc 함수는 단지 쉘일 뿐이며 이 쉘을 사용한 후에는 중복됩니다. 뭔가 있고, 생성자를 직접 사용하여 객체를 생성하는 것과 다르지 않은데, 이는 다소 불쾌합니다.
그런데 이 코드를 일반 함수로 작성하고, 함수 본문이 함수 내의 함수가 된다면, 외부 함수가 범위를 벗어난 후에 이 내부 함수가 자동으로 죽지 않을까요? 게다가, 프로토타입 객체를 일반 함수의 매개변수로 사용할 수 있고, 일반 함수가 생성된 객체를 반환하도록 할 수도 있습니다.필요한 형식은 다음과 같습니다.
function New(aClass, aParams) //일반적으로 생성된 함수
{
function new_() //임시 전송 함수 쉘 정의
{
aClass .Create.apply(this, aParams); //프로토타입에 정의된 생성자를 호출하고 생성 로직과 생성 매개변수를 전송합니다
new_.prototype = aClass; 🎜> return new new_(); //최종 생성된 객체를 반환합니다
};
var Person = //정의된 클래스
{
생성: 함수(이름, 나이)
{
this.name = 이름;
this.age = age
},
SayHello: function()
{
alert("안녕하세요, 저는 " this.name입니다. ) ;
},
HowOld: function()
{
alert(this.name "은 " this.age " 세입니다.")
}
}; 🎜 >var BillGates = New(Person, ["Bill Gates", 53]); //일반 함수를 호출하여 객체를 생성하고 구성 매개변수를 배열 형식으로 전달합니다.
BillGates.SayHello(); 🎜>BillGates.HowOld() ;
alert(BillGates.constructor == Object); //출력: true
여기서 일반 함수 New()는 "문법적 꿀"입니다! 이 구문 넥타는 프로토타입 객체를 전송할 뿐만 아니라 생성자 논리 및 생성 매개변수도 전송합니다.
흥미로운 점은 객체가 생성되고 New 함수 범위를 종료할 때마다 임시 new_function 객체가 자동으로 해제된다는 것입니다. new_의 프로토타입 속성이 새 프로토타입 객체로 설정되었으므로 원래 프로토타입 객체와 new_ 사이의 참조 체인이 풀리고 임시 함수와 원래 프로토타입 객체가 올바르게 재활용됩니다. 위 코드의 마지막 문장은 새로 생성된 객체의 constructor 속성이 Object 함수를 반환한다는 것을 증명합니다. 실제로 새로 생성된 객체 자체와 해당 프로토타입에는 생성자 속성이 없으므로 반환되는 것은 최상위 프로토타입 객체인 Object의 생성자뿐입니다.
New의 구문 꿀을 사용하면 클래스 정의가 C#의 정적 개체 언어 형식과 매우 유사합니다. 이러한 코드는 얼마나 조용하고 우아해 보입니까?
물론 이 코드는 "문법적 꿀"의 개념만을 보여줍니다. 또한 간결하고 우아한 코드로 클래스 계층 구조와 상속 관계를 작성하려면 더 많은 구문이 필요합니다. 자, 더 풍부한 예를 살펴보겠습니다.
//Syntax nectar:
var object = //가장 기본적인 메소드 등을 구현하는 데 사용되는 소문자 객체 기본 클래스를 정의합니다.
{
isA: function(aType) //클래스와 객체 및 클래스 간의 관계를 판단하는 기본 방법
{
var self = this
while(self)
{
if( self == aType)
return true;
self.Type;
return false
}
function Class( aBaseClass, aClassDefine) //클래스 생성 함수, 클래스 선언과 상속관계 선언에 사용
{
function class_() //클래스의 임시 함수 쉘 생성
{
this.Type = aBaseClass; //각 클래스의 Type 속성에 동의하고 상속된 클래스를 참조합니다.
for(var member in aClassDefine)
this[member] = aClassDefine[member] //클래스의 모든 정의를 현재 생성 Class
};
class_.prototype = aBaseClass;
return new class_();
function New(aClass, aParams) //객체를 생성하는 함수 모든 클래스 객체 생성에 대해
{
function new_() //객체의 임시 함수 셸을 생성합니다
{
this.Type = aClass //각각의 Type 속성에도 동의합니다. object에 따르면 해당 객체가 속한 클래스에 액세스할 수 있습니다.
if (aClass.Create)
aClass.Create.apply(this, aParams) //모든 클래스의 생성자를 Create라고 하는 데 동의합니다. , 이는 DELPHI와 유사합니다
};
return new new_()
}//신택스 적용 효과:
var Person = Class(object, // 객체 기본 클래스에서 파생됨
{
Create: function(name, age)
{
this.name = name;
this.age = age;
},
SayHello: function()
{
alert("안녕하세요, 저는 " this.name ", " this.age " 살입니다."); >}
});
var Employee = Class(Person, // Person 클래스에서 파생, 일반 객체 언어와 매우 유사합니까?
{
생성: 함수(이름, 나이, 급여)
{
Person.Create.call(this, 이름, 나이) //기본 클래스의 생성자 호출
this; . 급여 = 급여;
},
ShowMeTheMoney: function()
{
alert(this.name " $" this.salary)
}
var BillGates = New(Person, ["Bill Gates", 53]);
var SteveJobs = New(직원, ["Steve Jobs", 53, 1234])
BillGates.SayHello(); 🎜 >SteveJobs.SayHello();
SteveJobs.ShowMeTheMoney();
var LittleBill = New(BillGates.Type, ["Little Bill", 6]); //BillGate 유형에 따라 LittleBill 생성
LittleBill .SayHello();
alert(BillGates.isA(Person)); //true
alert(BillGates.isA(Employee)) //false
alert(SteveJobs.isA(Person) )); //true
alert(Person.isA(Employee)); //false
alert(Employee.isA(Person)) //true
너무 많은 문법이 필요하지 않습니다. nectar"를 조금만 사용하면 전체 코드의 가독성과 유창성을 향상시켜 코드를 더욱 우아하게 만들 수 있습니다. 이러한 구문을 통해 JavaScript는 일반 객체 언어와 매우 유사해지며 코드를 작성하는 것이 훨씬 더 좋습니다!
좋은 소식은 이러한 꿀로 자양분을 얻은 JavaScript 프로그램이 더 효율적이라는 것입니다.프로토타입 객체에는 쓸모없는 객체 수준 멤버가 없고 생성자 속성 본문이 없기 때문에 생성자에 대한 개입은 적지만 메서드 공유는 계속 유지됩니다. 이렇게 하면 프로토타입 체인을 추적하고 속성과 메서드를 검색할 때 JavaScript에서 많은 시간을 절약할 수 있습니다.
이 형태를 '만나모델'이라고 부르자! 사실, 이 "만나 모델"의 프로토타입 사용법은 프로토타입 개념의 원래 의미와 일치하며 JavaScript 프로토타입의 진정한 의미입니다!
마이크로소프트에서 AJAX 아키텍처를 설계한 엔지니어들이 이 넥타 모델을 보고 좀 더 일찍 AJAX 부서를 미국에서 중국 관음사로 옮기지 않은 것을 후회하고 관음보살의 깨달음을 놓쳤던 것 같아요. 물론 우리는 코드 예제에서 빌 게이츠를 대상으로만 플레이할 수 있습니다. 그가 신을 포기하고 나의 부처로 개종하는 것은 확실히 쉽지 않을 것입니다. 언젠가 Microsoft의 새로운 AJAX 클래스 라이브러리에서 이런 종류의 넥타 모델을 보게 된다면, 그것은 진정한 운명입니다!
프로그래밍의 즐거움
오늘날 소프트웨어 산업의 급속한 발전과 함께 다양한 프로그래밍 언어가 끊임없이 등장하고 있으며, 새로운 언어의 탄생과 옛 언어의 진화가 우리를 현혹시켰던 것 같습니다. . 객체지향 프로그래밍 추세에 적응하기 위해 JavaScript 언어도 완전히 객체지향적인 방향으로 발전하고 있습니다. 새로운 JavaScript 표준은 의미상 많은 새로운 객체지향 요소를 확장했습니다. 반대로 많은 정적 객체 언어 역시 자바스크립트의 단순성과 우아함을 지향하는 방향으로 발전하고 있습니다. 예를 들어 C# 언어의 새 버전에는 JSON과 같은 간결한 표현은 물론 다른 형태의 JavaScript 기능도 포함되어 있습니다.
RIA(Strong Internet Application)의 개발과 대중화로 인해 AJAX 기술은 점차 세상에서 사라지고, JavaScript는 결국 사라지거나 다른 형태의 언어로 진화하게 될 것이라고 보아야 합니다. 그러나 프로그래밍 언어가 어떻게 발전하고 진화하든 프로그래밍 세계는 언제나 '데이터'와 '코드'의 뗄 수 없는 얽힘 속에서 무한한 생명력을 유지하게 될 것입니다. 이를 통해 우리는 소프트웨어 세계의 다양한 새로운 것들을 쉽게 배우고 이해할 수 있습니다. 친숙한 절차적 프로그래밍이든, 개발 중인 함수형 프로그래밍이든, 미래의 양자 얽힘 상태에 대한 대규모 병렬 프로그래밍이든, 우리는 모든 복잡한 문제를 해결할 수 있는 충분한 마법의 힘을 가지고 있습니다.