작가가 자신의 학습과 활용을 위해 번역에 자신의 이해를 더할 예정이므로, 영어에 능숙한 학생들은 다음 내용을 읽어도 됩니다. 기사에 번역 오류가 있으면 소통하고 수정해 주세요. (:
====== ===============에네인 번역====================== ====
John Resig는 base2 및 PrototypeJS에서 영감을 받아 다른 언어와 유사한 JavaScript의 "상속"에 관한 기사를 작성했습니다. 그는 기사의 이름을 "Simple JavaScript Inheritance"로 지정했습니다.
당신 자세한 설명은 원문을 참조하세요. 책에서는 전역 변수를 생성하는 대신 하위 클래스를 추가하는 방법도 있습니다. .
원본 스크립트 - John Resig Simple JavaScript Inheritance
아래는 용서 코드입니다. 더 명확하게 보이도록 일부 주석을 제거했습니다.
단순 상속 스크립트 분석
어떻게 구현되고 어떤 기술이 사용되는지 분석해 보겠습니다.
먼저 자체 실행 익명 함수를 만들어 코드 범위를 만듭니다.
이 초기화 변수의 의미는 매우 간단합니다. 클래스 함수(나중에 설명)가 호출될 때 확인하는 부울입니다. 인스턴스를 생성할 때 초기화를 true/false로 설정하거나 현재 프로토타입을 가리키는 객체를 반환하기만 하면 됩니다. " 상속의 목적을 달성하기 위한 체인입니다.
인스턴스를 생성하면(초기화 == false) Class에는 init 메소드가 있으므로 init가 자동으로 실행됩니다. 또는 프로토타입에 할당하면(초기화 == true) 아무 일도 일어나지 않고 init 메서드가 실행되지 않습니다. 이는 생성자가 호출될 때마다 init 메소드를 실행하지 않아도 되도록 수행됩니다(var 프로토타입 = new this());.
이 fnTest의 목적은 클래스 메소드에서 "_super()" 호출이 사용되는지 확인하는 것입니다. 이 기술을 "함수 디컴파일(function decompilation)", "함수 직렬화(function serialization)"라고도 하며, 함수 직렬화 함수가 문자열로 변환될 때 발생합니다. 이제 많은 브라우저가 toString 메서드를 지원합니다.
함수 직렬화를 테스트하기 위해 fnTest는 익명 함수 funciton(){xyz;}를 사용하여 내용을 "xyz"로 설정하고, 이를 문자열로 변환한 후 정규식을 사용하여 "xyz"를 검색합니다. true(브라우저가 함수 직렬화를 지원하는 경우) 함수가 이를 문자열로 변환하기 때문에 "xyz"도 문자열의 일부입니다. 이 경우 fnTest는 "/b_superb/"를 반환하고 다른 경우에는 "/.*/를 반환합니다. " 브라우저가 기능 직렬화를 지원하지 않는 경우 항상 true를 반환합니다. (원래 코드의 fnTest.test를 참조합니다.) fnTest 정규화 및 함수 직렬화 기술을 사용하면 "_super"가 메서드에 사용되는지 여부를 쉽게 확인할 수 있습니다. 이 특별한 방법은 부모 클래스와 자식 클래스에 동시에 나타나는 동일한 메서드를 방지하는 것입니다.
브라우저가 함수 직렬화를 지원하지 않으면 항상 true를 반환하므로 항상 _super에서 추가 작업이 수행되므로 이러한 새로운 메서드는 _super에서 사용되지 않습니다. 그러나 이는 약간의 성능 소모를 가져옵니다. 보장 모든 브라우저에서 정상적으로 실행됩니다.
빈 생성자를 만들어 전역 변수에 넣습니다. 이는 정의된 내용이 없거나 아래의 확장 메서드를 제외하고는 창 개체를 참조합니다. 클래스 변수는 전역 객체입니다.
확장 메소드와 간단한 prop(객체) 매개변수를 추가하면 새 생성자의 프로토타입과 상위 객체의 프로토타입이 반환됩니다.
prop의 각 객체를 반복할 때 (typeof prop[name] == "function") (typeof _super[name] == "function") (fnTest.test(prop[name]) = = true)
부모 클래스에 바인딩된 새 메서드와 원래 메서드를 처리하기 위해 새 메서드를 추가합니다.
위의 코드를 좀 더 명확하게 살펴보겠습니다.
super에서 prop[name]이라는 이름을 처리할 때 사용되는 또 다른 자체 실행 익명 함수입니다. 이 함수를 반환할 때 이 변수에 대한 참조가 잘못됩니다. 루프 a)
전체를 반복하면 새 함수가 반환됩니다. 이 함수는 기본 메서드(수퍼를 통해)와 새 메서드를 처리합니다.
super의 특수 처리를 위해 먼저 기존 _super 속성과 클래스의 일부 매개변수를 임시 tmp에 저장해야 합니다. 이는 _super의 기존 메소드를 덮어쓰는 것을 방지하기 위한 것입니다.
그 후에 할당합니다. tmp를 this._super에 할당하여 정상적으로 작동하도록 합니다.
다음으로 현재 개체의 this._super에 _super[name] 메서드를 할당하여 Apply를 통해 fn이 실행될 때 this ._Super()가 이
이 상위 메소드는 현재 객체에 액세스할 수도 있습니다.
마지막으로 반환 값을 RET 객체에 저장합니다.
아래에 간단한 예가 있습니다. 간단한 Foo를 생성하고 상속된 객체 Bar를 생성합니다.
Foo.extends가 실행될 때 qux 메서드에 this._super가 존재하기 때문에 Bar 프로토타입의 qux는 실제로 다음과 같아야 합니다.
스크립트에서 이 단계를 완료하면 생성자가 호출됩니다.
이 코드는 Class를 호출하여 이전에 생성된 this.Class와 다른 새로운 생성자를 로컬 Class.extend로 생성합니다. 이 생성자는 Class.extend(예: 이전 Foo.extends)에 대한 호출을 반환합니다. new 이 생성자는 Foo()가 인스턴스화된 후에 실행됩니다.
생성자는 init() 메서드(존재하는 경우)를 자동으로 실행합니다. 위에서 언급한 대로 이 초기화 변수는 init 실행 여부를 제어합니다.
마지막 프로토타입은 상위 클래스의 생성자 메서드에서 상위 클래스의 혼합 프로토타입 객체를 반환합니다(예: var 프로토타입 = new this()). 이 결과는 확장 함수의 for 루프를 통해 전달됩니다. >
Class.constructor = Class;
전체 프로토타입 객체를 다시 작성했기 때문에 이 네이티브 생성자를 이 유형에 저장하여 인스턴스 생성자에서 기본 모양을 유지할 수 있습니다.