>  기사  >  웹 프론트엔드  >  JavaScript 객체 지향 프로그래밍 기본: 상속_js 객체 지향

JavaScript 객체 지향 프로그래밍 기본: 상속_js 객체 지향

WBOY
WBOY원래의
2016-05-16 18:47:48970검색

여기에서 상속의 개념이 얼마나 간단한지 알 수 있습니다. "한 클래스의 프로토타입을 다른 클래스에 복사"입니다. 좋습니다. 코드는 저렴합니다. 코드를 살펴보세요.

function class1() { }
function class2() { }
class2.prototype = class1.prototype;
class2.moreProperty1 = " 클래스 2 추가 문자열 " ;
class2.moreMethod1 = function () { 경고( " 클래스 2 추가 메서드 " ) ; }
/*
이렇게 하면 우선 class2는 생성자에 관계없이 두 클래스가 동일합니다.
이후 프로토타입을 통해 class2에 두 가지 메소드를 추가로 부여했습니다. 그래서 class2는 클래스 상속을 구현하는 class1
을 기반으로 속성과 메서드를 추가합니다.
*/

function test() {
var obj = new class2()
// JavaScript는 객체가 특정 클래스의 인스턴스인지 여부를 확인하는 instanceof 연산자를 제공합니다
alert(obj instanceof class2); // true
alert(obj instanceof class1); // ?
}

코드를 실행해 보세요. 예상한 결과가 나오나요? 표면적으로 위의 구현은 완전히 가능하며 js도 이 상속 관계를 올바르게 이해하고 구현할 수 있습니다. obj는 class1과 class2의 인스턴스이지만 실제로는 그렇지 않습니다(우리 연구의 목적은 클래스 2에 대해 더 자세히 알아보는 것입니다). 다) 그 이유). js에 대한 이러한 이해는 실제로 매우 간단한 전략을 기반으로 합니다. 먼저 프로토타입을 사용하여 class2가 class1에서 상속되도록 한 다음 class2에서 메서드 메서드를 반복적으로 정의합니다.

// Define class1
function class1() {
//Constructor
}
// class1의 멤버 정의
class1.prototype = {
m1: function () { // 메서드 1
Alert( " class1 method1 " );
}
}
// 클래스2 정의
function class2() {
// 생성자
}
// 클래스2 상속 위치 class1
class2.prototype = class1.prototype;

// class2에 대한 메소드 메소드를 반복적으로 정의
class2.prototype.method = function () {
alert( " 누구의 메소드2? class1 또는 class2 " );
}
// 두 클래스의 인스턴스 생성
var obj1 = new class1();
var obj2 = new class2();

function test() {
// 두 객체의 메소드 메소드를 각각 호출
obj2.method()
}

코드 실행 결과로 판단 , class1과 class2에서 실행된 메서드의 결과는 동일합니다.

class2의 프로토타입이 변경되면 class1의 프로토타입도 이에 따라 변경되는 것을 볼 수 있습니다. class2의 프로토타입에 일부 멤버가 추가되거나 제거되더라도 그에 따라 class1의 멤버도 변경되는 것을 알 수 있습니다. . 따라서 class1과 class2는 생성자가 서로 다른 두 클래스일 뿐이지만 동일한 멤버 정의를 유지합니다. 이 시점에서 나는 독자들이 비밀을 발견했다고 믿습니다: class1과 class2의 프로토타입은 정확히 동일하며 동일한 객체를 참조합니다. 실제로 다음 할당문에서 알 수 있습니다.
//Let class2는 class1에서 상속됩니다.
class2.prototype=class1.prototype;
js에서는 기본 데이터 유형(숫자, 문자열, 부울 유형 등), 모든 할당 및 함수 매개변수는 값이 아닌 참조로 전달됩니다. 따라서 위의 명령문은 class2의 프로토타입 객체가 class1의 프로토타입을 참조하도록 허용하므로 클래스 멤버 정의가 항상 일관되는 ​​효과가 있습니다. 여기서는 객체가 프로토타입의 인스턴스인지 여부를 결정하는 objectof 연산자의 실행 메커니즘도 볼 수 있습니다. 여기서 obj1과 obj2는 동일한 프로토타입에 해당하므로 해당 인스턴스of의 결과는 동일합니다. 프로토타입 참조 사본을 사용하여 상속을 구현하는 것은 올바른 방법이 아님을 알 수 있습니다. 그러나 요구 사항이 엄격하지 않은 경우에는 합리적인 방법이기도 합니다. 유일한 제약은 클래스 멤버 정의를 재정의하는 것이 허용되지 않는다는 것입니다. 이는 실제로 js의 유연성을 반영합니다. 실제로 리플렉션 메커니즘과 프로토타입을 완전히 사용하여 js에서 올바른 클래스 상속을 얻을 수 있습니다.

function class1() {
// Constructor
}
class1.prototype = {
method: function () {
alert( " method1 " );
},
method2: function () {
alert( " method2 " );
function class2() {
// 생성자
}

// class2가 class1에서 상속받도록 합니다
for ( var p in class1.prototype) {
class2.prototype [p] = class1.prototype[p]; //상속을 구현하기 위해 리플렉션 메커니즘과 프로토타입을 사용합니다
}

// class1에 정의된 메서드 메서드를 재정의합니다
class2.prototype.method = function ( ) {
alert( " class2 new method1 " );


// 두 클래스의 인스턴스 생성
var obj1 = new class1()
var obj2 = new class2();

function test() {
// 두 개체의 메서드 메서드를 각각 호출합니다.
obj1.method()
obj2.method();
// 두 객체의 method2 메소드를 각각 호출
obj1.method2();
obj2.method2()
}

실행 결과에서 확인할 수 있습니다. obj2 메서드의 반복된 정의가 상속된 메서드 메서드를 재정의했지만 method2 메서드는 영향을 받지 않습니다. 그리고 obj1의 메소드 메소드는 여전히 원래 정의를 유지합니다. 이러한 방식으로 클래스 상속의 올바른 의미가 달성됩니다.개발을 용이하게 하기 위해 각 클래스에 공통 메소드를 추가하여 클래스 상속을 구현할 수 있습니다.

// 특정 클래스
Function.prototype으로부터의 상속을 나타내기 위해 클래스에 정적 메소드 상속을 추가합니다. 상속 = 함수 (baseClass) {
for ( var p in baseClass.prototype) {
this .prototype[p] = baseClass.prototype[p]
}
}

function class1() {
//Constructor
}
class1.prototype = {
method: function () {
alert( " method1 " ),
method2: function () {
alert( " method2 " );
}
}
function class2() {
// 생성자
}

/ / class2가 class1에서 상속받도록 합니다.
// for (var p in class1.prototype) {
// class2.prototype[p] = class1.prototype[p] // 상속을 달성하기 위해 리플렉션 메커니즘과 프로토타입을 사용합니다.
// }

class2.inherit(class1); // 위에서 주석 처리한 for 루프와 동일합니다.

// class1
class2 .prototype에 정의된 메서드를 재정의합니다. method = function () {
alert( " class2 new method1 " );


// 두 클래스의 인스턴스 생성
var obj1 = new class1 (); 🎜>var obj2 = new class2();

function test() {
// 두 개체의 메서드를 각각 호출합니다.
obj1.method()
obj2.method ();
// 두 개체의 method2 메서드를 각각 호출합니다.
obj2.method2()
}

위 코드는 논리를 더 명확하게 만듭니다. 그리고 이해하기 더 쉽습니다. 이 방법을 통해 구현된 상속의 한 가지 단점은 class2에 클래스 멤버 정의를 추가할 때 프로토타입에 직접 값을 할당할 수 없고 해당 속성에만 값을 할당할 수 있다는 것입니다. class2.prototype={
//멤버 정의
}
다음만 가능합니다:
class2.prototype.propertyName=someValue;
class2.prototype.methodName=function(){
//Statement
}

이러한 방식으로 상속을 구현하면 여전히 코드 가독성이 어느 정도 저하되는 것을 볼 수 있습니다. "기본 클래스에서 객체를 속성에 직접 할당할 수 있을 뿐만 아니라 파생 클래스에서도 구현할 수 있어 코드 논리가 더 명확해지고 객체지향 언어의 특성을 더 잘 반영할 수 있는" js 상속 방법이 있나요? 따옴표 안의 말은 너무 유혹적입니다. 계속 공부하세요.

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