출처: http://www.ajaxwing.com/index.php?id=2
1. 배경
프로그래밍 언어의 발전을 되돌아보면 어렵지 않다. 지속적인 캡슐화 과정: 초기 어셈블리 언어, 프로세스 지향 언어, 객체 지향 언어, 객체 지향 특성을 지닌 스크립팅 언어로 계층별로 캡슐화하는 단계 , 프로그래머의 부담을 줄이고 점차적으로 프로그램 작성 효율성을 향상시킵니다. 이번 글은 자바스크립트에 관한 글이므로 먼저 자바스크립트가 어떤 언어인지 알아보겠습니다. 현재 JavaScript는 객체 지향 기능을 완전히 지원하지 않는 스크립팅 언어입니다. 제가 이렇게 말하는 이유는 JavaScript가 객체 개념을 지원하기 때문입니다. 우리는 프로그램에서 객체를 볼 수 있지만 Javascipt는 클래스 캡슐화와 상속을 지원하지 않습니다. C, Java, PHP 또는 Python 프로그래밍 경험이 있는 독자라면 이러한 언어를 사용하면 클래스를 사용하여 객체를 디자인할 수 있으며 이러한 클래스는 상속 가능하다는 것을 알 수 있습니다. JavaScript는 사용자 정의 객체와 상속을 지원하지만 또 다른 방법인 프로토타입(중국어 번역: 프로토타입)을 사용합니다. 자바스크립트를 사용해 본 독자나 "디자인 패턴"을 읽어본 독자라면 이 기술을 다음과 같이 설명하고 있을 것입니다.
각 개체에는 프로토타입 개체가 포함되어 있으며 개체에 속성을 쿼리하거나 메서드를 요청할 때 실행 환경이 실행됩니다. 먼저 현재 객체를 검색하고, 검색에 실패하면 해당 프로토타입 객체를 검색합니다. 프로토타입도 객체이므로 이 검색 프로세스는 현재 객체의 프로토타입이 비어 있을 때까지 객체의 프로토타입 객체에도 적용됩니다.
JavaScript에서 객체의 프로토타입은 런타임에 보이지 않으며 객체를 생성하기 전에 객체의 생성자를 정의할 때만 설정할 수 있습니다. 다음 사용법은 모두 잘못되었습니다.
o2.prototype = o1;
/*
이때 o2의 "prototype"이라는 속성만 정의되며,
은 o1이 아닙니다. o2의 프로토타입으로 설정됩니다.
*/
// ---------------
f2 = function(){}
o2 = new f2;
f2.prototype = o1;
/*
이때 o1은 o2의 프로토타입이 되지 않았습니다.
f2가 프로토타입을 설정하기 전에 o2가 생성되었기 때문입니다.
*/
// ---------------
f1 = 함수(){}
f2 = 함수() {};
o1 = new f1;
f2.prototype = o1;
o2 = new f2;
/*
마찬가지로 현재 o1은 o2의 프로토타입이 아닙니다. 🎜> JavaScript는 생성자의 프로토타입 객체가 다른 변수에 의해 직접 참조되는 것을 허용하지 않기 때문입니다.
*/
올바른 사용법은 다음과 같습니다:
f1 = function(){};
f2 = function(){};
f2.prototype = new f1;
o2 = new f2;
위의 예에서 볼 수 있듯이 생성자 F2가 다른 생성자 F1에서 정의한 속성과 메서드를 상속하도록 하려면 먼저 An을 만들어야 합니다. F1의 인스턴스 객체를 만들고 즉시 F2의 프로토타입으로 설정합니다. 따라서 프로토타입 상속 방법을 사용하면 실제로 상속 사용이 권장되지 않는다는 것을 알게 될 것입니다. 한편으로는 JavaScript가 내장된 스크립팅 언어로 설계되었기 때문에 예를 들어 브라우저에 내장되어 있으며 이를 사용하여 작성된 애플리케이션은 일반적으로 그다지 좋지 않습니다. 매우 복잡하고 상속이 필요하지 않습니다. 반면에 상속이 더 깊으면 프로토타입 체인이 길어지고 객체 속성 및 메서드를 검색하는 데 소요되는 시간이 길어져 전반적인 운영 효율성이 떨어집니다. 프로그램.
두 번째, 문제
요즘에는 JavaScript가 점점 더 많은 상황에서 사용됩니다. web2.0에서 매우 중요한 측면은 사용자 경험입니다. 좋은 사용자 경험을 위해서는 좋은 아트뿐만 아니라 응답 속도와 역동적인 효과도 필요합니다. 잘 알려진 많은 web2.0 애플리케이션은 Flickr, Gmail 등과 같은 많은 JavaScript 코드를 사용합니다. 어떤 사람들은 Javasript를 사용하여 Backbase, Qooxdoo 등과 같은 브라우저 기반 GUI를 작성하기도 합니다. 따라서 JavaScript 코드의 개발 및 유지 관리는 매우 중요한 문제가 되었습니다. 많은 사람들은 JavaScript가 개발 속도와 효율성을 향상시키기 위해 다른 프로그래밍 언어처럼 성숙하고 안정적인 JavaScript 라이브러리를 가질 수 있기를 바랍니다. 더 많은 사람들이 바라는 것은 자신이 작성한 JavaScript 코드가 다른 객체 지향 언어로 작성된 코드처럼 모듈성이 좋고 재사용성이 좋아 유지 관리가 더 편리하다는 것입니다. 그러나 현재 JavaScript는 이러한 요구 사항을 잘 지원하지 않습니다. 대부분의 개발은 처음부터 시작해야 하며 유지 관리가 매우 불편합니다.
세 가지, 기존 솔루션
요구가 있으면 자연스럽게 솔루션이 나올 것입니다. 두 가지 더 성숙한 솔루션이 있습니다.
1. MVC 웹 프레임워크인 Ruby on Rails에서 개발되었으며 JavaScript 기본 라이브러리를 사용하는 프로토타입.js라는 JavaScript 라이브러리입니다. 이 라이브러리는 잘 설계되었으며 재사용성과 브라우저 간 기능이 뛰어납니다. 프로토타입을 사용하면 클라이언트 코드 개발이 크게 단순화됩니다. 프로토타입.js로 작성된 클래스는 클래스 인스턴스를 생성할 때 초기화 함수를 정의할 수 있습니다. 이름에서 알 수 있듯이, 프로토타입.js의 핵심은 여전히 프로토타입입니다. 재사용 가능한 코드를 많이 제공하지만 JavaScript의 개발 및 유지 관리 문제를 근본적으로 해결하지는 않습니다.
2. asp.net을 사용하는 사람들은 일반적으로 Microsoft의 AJAX 도구인 Atlas라는 프레임워크를 들어본 적이 있거나 사용해 본 적이 있을 것입니다. Atlas를 사용하면 클래스 메소드를 사용하여 클라이언트 코드를 작성할 수 있으며, 개인 속성 및 클래스의 개인 메소드 정의, 상속 지원, Java와 같은 인터페이스 작성 등과 같은 프로토타입.js보다 더 나은 객체 지향 기능을 가지고 있습니다. Atlas는 클라이언트-서버 솔루션이지만 asp.net에서만 사용할 수 있으며 저작권 및 기타 문제로 인해 사용 범위가 제한됩니다.
이 문제에 대한 근본적인 해결책은 단 하나, JavaScript2.0(또는 ECMAScript4.0) 표준의 도입을 기다리는 것입니다. JavaScript의 다음 버전에는 이미 언어에 객체 지향 기능이 있습니다. 또한 이러한 기능은 이미 Microsoft의 JScript.NET에서 사용할 수 있습니다. 물론 기다리는 것은 현명한 접근 방식이 아닙니다.
4. Modello Framework
위의 표현이 조금 어지러운 경우, Modello Framework를 먼저 이해하는 것이 가장 좋습니다.
JavaScript 생성자: JavaScript에서 사용자 정의 개체는 생성자를 통해 설계됩니다. new 연산자와 생성자를 더하면 JavaScript에서 인스턴스 객체
프로토타입이 생성됩니다. 객체 P가 생성자 F의 프로토타입으로 설정된 경우 F를 사용하여 생성된 인스턴스 객체는 P 메소드
의 속성과 속성을 상속합니다. 클래스: 객체 지향 언어는 클래스를 사용하여 객체를 캡슐화하고 디자인합니다. 유형에 따라 클래스 멤버는 속성과 메서드로 구분됩니다. 접근 권한에 따라 클래스 멤버는 정적 멤버, 프라이빗 멤버, 보호 멤버, 퍼블릭 멤버로 구분됩니다.
클래스 상속: 객체지향 언어에서는 한 클래스가 다른 클래스의 속성과 메서드를 상속받을 수 있습니다. 클래스를 하위 클래스라고 합니다. 상속된 클래스를 부모 클래스라고 합니다. 일부 언어에서는 하위 클래스가 하나의 상위 클래스만 상속(단일 상속)하도록 허용하고 일부 언어에서는 다중 상속(다중 상속)을 허용합니다.
JavaScript의 클로저 기능: 함수의 범위는 클로저입니다. JavaScript에서는 내부 함수 I를 함수 O에 정의할 수 있습니다. 내부 함수 I는 항상 외부 함수 O에 정의된 변수에 액세스할 수 있습니다. 외부 함수 O가 반환된 후에도 내부 함수 I를 호출하면 외부 함수 O에 정의된 변수에 계속 액세스할 수 있습니다. 즉, 생성자 C에서 var를 사용하여 변수 V를 정의하고 이를 사용하여 함수 F를 정의하면, C가 생성한 인스턴스 객체 O가 O.F를 호출할 때 F는 항상 V에 접근할 수 있지만, 이렇게 O.V를 사용하여 접근하는 것입니다. V는 이것에 의해 정의되지 않기 때문에 작동하지 않습니다. 즉, V는 O의 비공개 멤버가 됩니다. 이 기능은 매우 중요합니다. 아직 완전히 이해하지 못했다면 "JavaScript의 Private Members" 기사를 참조하세요.
위의 개념을 이해하려면 다음 내용을 이해하는 것이 어렵지 않습니다. 시작했어요!
제목에서 알 수 있듯이 Modello는 JavaScript로 클래스를 작성하도록 허용하고 장려하는 프레임워크입니다. 전통적인 JavaScript는 생성자를 사용하여 객체와 프로토타입을 사용자 정의하여 상속을 구현합니다. Modello에서는 다른 객체 지향 언어와 마찬가지로 클래스를 사용하여 객체를 디자인하고 클래스를 사용하여 상속을 구현하기 때문에 모호한 프로토타입을 잊어버릴 수 있으며 사용이 더 간단합니다. 믿을 수 없나요? 계속 읽어주세요.
Modelello를 사용하여 작성된 클래스에는 다음과 같은 기능이 있습니다.
개인 멤버, 공용 멤버 및 정적 멤버
클래스 상속, 다중 상속
네임스페이스
유형 식별
Modello
더 적은 개념, 더 편리한 사용
약 200줄의 코드로 작고 컴팩트
상속을 사용하여 디자인과 런타임의 완전한 분리 필요 없음 프로토타입을 사용하거나 상위 클래스의 인스턴스를 먼저 생성
prototype.js와 호환되는 클래스, JavaScript 생성자와 호환
크로스 브라우저, 크로스 브라우저 버전
오픈 소스 코드, BSD 라이센스, 사용 허용 개인 또는 상업 프로젝트에서 무료로
Modello를 사용하는 방법은 다음과 같습니다.
1. 클래스 정의
Point = Class.create(); 수업. 프로토타입.js를 사용해본 사람이라면 익숙할 것입니다.)
*/
2. 클래스 등록
Point.register("Modello.Point")/ *
여기서 "Modello"는 네임스페이스이고 "Point"는 "."으로 구분된 클래스 이름입니다.
등록에 성공하면
Point.namespace는 "Modello", Point.classname과 같습니다. "포인트"와 같습니다.
실패하면 Modello는 실패 이유를 나타내는 예외를 발생시킵니다.
*/
Point.register("Point"); // 여기서는 기본 네임스페이스 "std"가 사용됩니다.
Class.register(Point, "Point") // Class
3의 등록 메소드를 사용하여 등록된 클래스를 가져옵니다.
P = Class.get("Modello.Point")
P = Class.get("Point") ; // 여기서는 기본 네임스페이스 "std"가 사용됩니다.
4, 상속이 사용됩니다.
ZPoint = Class.create(Point) // ZPoint는 Point를 상속합니다.
ZPoint = Class.create("Modello.Point"); // 등록된 클래스 상속
ZPoint = Class.create(Point1, Point2[, ...])
/*
더 많은 상속.매개변수의 클래스는 등록된 클래스 이름으로 대체될 수도 있습니다.
*/
/*
상속 관계:
Point.subclasses 내용은 [ZPoint]
ZPoint입니다. 슈퍼클래스 콘텐츠는 [ Point ]
*/
5이며, 클래스의 정적 멤버를 정의합니다.
Point.count = 0
Point.add = function(x, y; ) {
return x y;
}
6, 클래스의 생성자 정의
Point.construct = function($self, $class) {
// "var"를 사용하여 비공개 멤버 정의
var _name = "";
var _getName = function () {
return _name> }
// " this" 공개 멤버 정의
this.x = 0;
this.y = 0;
this.initialize = function (x, y) { // 초기화 함수
this.x = x;
This.y = y;
$class.count = 1; // 정적 멤버에 액세스
// 퍼블릭 메소드는 프라이빗 속성에 액세스
this.setName = function (name) 🎜 > _name = 이름;
}
this.getName = function () {
return _getName() 🎜> return "Point(" . add = function () {
/ / 정적 메소드를 호출하고 $ class
return $ class.add (this.x, this.y)
>}
ZPoint를 사용합니다. constructor = function($self, $class) {
this.z = 0; // this.x, this.y는 Point
// Point 초기화 함수 오버로드
this.initialize = function (x, y, z) {
this.z = z;
// 첫 번째 상위 클래스의 초기화 함수를 호출합니다.
// 두 번째 상위 클래스는 $입니다. self.super1 등.
$self 변수를 사용할 수 있지만 상위 클래스의 공개 메소드로 제한됩니다.
}
// Point
this.toString = function () {
return "Point( " This. ().register("Modello.Point").construct = function($self, $class) {
// ...
}
7, 클래스의 인스턴스 생성
// 두 가지 메서드: new 및 create
point = new Point(1, 2)
point = Point.create(1) , 2);
point = Class.get("Modello .Point").create(1, 2);
zpoint = new ZPoint(1, 2, 3); 유형 식별
ZPoint.subclassOf(Point); // true를 반환합니다.
point.instanceOf(Point); // true를 반환합니다.
point.isA(Point); // true를 반환합니다. zpoint.isA(Point); // true를 반환합니다.
zpoint .instanceOf(Point); // false를 반환합니다.
// 위 클래스는 등록된 클래스 이름으로 대체 가능합니다.
위 내용은 모두 모델로에서 제공하는 기능입니다. 다음은 Modello 사용에 대한 몇 가지 참고 사항 및 제안 사항입니다.
상속을 사용할 때 전달되는 상위 클래스는 프로토타입.js를 사용하여 정의된 클래스이거나 JavaScript를 사용하여 정의된 생성자일 수 있습니다.
클래스는 실제로도 일반적인 프로토타입 상속 방법은 Modello로 정의된 클래스에도 적용 가능합니다.
이런 종류의 클래스는 익명 클래스라고 하며 Class.get 메서드를 통해 얻을 수 없습니다. 🎜>클래스 생성자를 정의하면 위의 예와 같이 $self와 $class라는 두 개의 매개변수가 제공됩니다. Modello는 인스턴스 생성 시 인스턴스 자체를 $self에 전달하고 클래스 자체를 $class에 전달합니다. $self는 일반적으로 상위 클래스 멤버에 액세스할 때 사용되며 $class는 일반적으로 정적 멤버에 액세스할 때 사용됩니다. $self와 $class는 매우 강력하지만 Modello의 소스 코드를 읽은 적이 없고 실제로 특별한 요구 사항이 있는 경우를 제외하고는 다른 상황에서 사용하지 않는 것이 좋습니다. 이 대신 $self를 사용하려고 시도하지 마세요.
하위 클래스는 상위 클래스의 전용 멤버에 액세스할 수 없으며 정적 메서드에서는 전용 멤버에 액세스할 수 없습니다.
특별한 사항은 없습니다. Modello에서는 private 멤버 이름에 대한 제한이 있지만 "_"로 시작하는 것이 좋습니다.
Modello는 protected 멤버를 하위 클래스에서 액세스할 수 있도록 하려면 다음을 정의해야 합니다. 상위 클래스 멤버를 공개로 사용합니다. 보호된 멤버를 나타내기 위해 "this._property"와 같은 명명 방법을 참조할 수도 있습니다.
계산 복잡성이 높은 일부 보조 메서드를 정적 멤버로 정의하여 운영 효율성을 향상시킬 수 있습니다.
Modello 상속 및 유형 식별을 사용합니다. 기본 인터페이스 기능을 구현할 수 있다는 사실은 이미 발견했습니다.)
다중 상속을 사용할 때 왼쪽의 상위 클래스가 오른쪽의 상위 클래스보다 우선순위가 높습니다. 즉, 여러 상위 클래스가 동일한 메서드를 정의하면 가장 왼쪽 상위 클래스에서 정의한 메서드가 결국 상속됩니다.
Modello를 사용하여 작성된 클래스의 기능은 Atlas를 사용하여 작성된 클래스의 기능과 비슷하며 사용이 더 간단합니다. . 프로토타입.js의 단순한 클래스 프레임워크 대신 Modello 프레임워크를 사용하려면 먼저 modello.js를 포함시킨 다음 프로토타입.js에서 클래스를 정의하는 몇 줄의 코드를 제거하면 모든 것이 정상적으로 실행됩니다.
Modello에서 버그를 발견하면 이메일로 연락해 주세요. Modello에 더 많은 기능이 있어야 한다고 생각한다면 소스 코드를 읽어보면 Modello가 필요한 기능을 쉽게 확장할 수 있다는 것을 알게 될 것입니다.
Modello의 원래 의미는 "대형 예술 작품의 모델"입니다. Modello가 고품질 JavaScript 코드를 작성하는 데 도움이 되기를 바랍니다.
5, 다운로드
Modello의 전체 참조 지침 및 다운로드 주소: http://modello.sourceforge.net