자바스크립트 상속의 기초(프로토타입 체인, 빌린 생성자, 혼합 모드, 프로토타입 상속, 기생 상속, 기생 결합 상속)_javascript 기술
자바스크립트 상속에 대해 설명하기로 약속했는데 지금까지 미뤄지고 있습니다. 더 이상 고민하지 않고 바로 본론으로 들어가겠습니다.
상속을 이해하고 싶다면 이미 객체지향 JavaScript에 대해 어느 정도 이해하고 있다는 뜻입니다. 그래도 이해가 되지 않는다면 "객체지향 JS 기본 설명, 팩토리 모드, 생성자 모드, 프로토타입 모드, 혼합 모드, 동적 프로토타입 모드》, JavaScript 상속을 완료하기 위해 일반적으로 사용되는 방법에 대해 이야기해 보겠습니다.
프로토타입 체인
JavaScript에서 상속을 구현하는 가장 간단한 방법은 프로토타입 체인을 사용하는 것입니다. 하위 유형의 프로토타입을 상위 유형의 인스턴스, 즉 "subtype.prototype = new parent type();"으로 지정하면 됩니다. 구현 방법은 다음과 같습니다.
// 为父类型创建构造函数 function SuperType() { this.name = ['wuyuchang', 'Jack', 'Tim']; this.property = true; } // 为父类型添加方法 SuperType.prototype.getSuerperValue = function() { return this.property; } // 为子类型创建构造函数 function SubType() { this.test = ['h1', 'h2', 'h3', 'h4']; this.subproperty = false; } // 实现继承的关键步骤,子类型的原型指向父类型的实例 SubType.prototype = new SuperType(); // 在此处给子类型添加方法,一定要在实现继承之后,否则会在将指针指向父类型的实例,则方法为空 SubType.prototype.getSubValue = function() { return this.subproperty; } /* 以下为测试代码示例 */ var instance1 = new SubType(); instance1.name.push('wyc'); instance1.test.push('h5'); alert(instance1.getSuerperValue()); // true alert(instance1.getSubValue()); // false alert(instance1.name); // wuyuchang,Jack,Tim,wyc alert(instance1.test); // h1,h2,h3,h4,h5 var instance2 = new SubType(); alert(instance2.name); // wuyuchang,Jack,Tim,wyc alert(instance2.test); // h1,h2,h3,h4
위 코드는 프로토타입 체인을 통해 구현한 단순 상속임을 알 수 있지만, 테스트 코드 예시에는 여전히 몇 가지 문제가 남아 있습니다. 제 블로그 글 "객체지향 JS 기본 설명, 팩토리 모드, 생성자 모드, 프로토타입 모드, 하이브리드 모드, 동적 프로토타입 모드"를 본 아이들은 반드시 프로토타입 체인코드의 존재를 알고 있어야 한다고 믿습니다첫 번째 문제는 하위 유형의 프로토타입이 상위 유형의 인스턴스, 즉 하위 유형의 프로토타입에 포함된 상위 유형의 속성이므로 참조 유형 값의 프로토타입 속성이 모든 인스턴스에서 공유됩니다 . 위 코드의 instance1.name.push('wyc');는 이 문제의 존재를 증명할 수 있습니다. 프로토타입 체인의 두 번째 문제는 하위 유형의 인스턴스를 생성할 때 매개변수를 상위 유형의 생성자에 전달할 수 없다는 것입니다. 따라서 실제 개발에서는 프로토타입 체인만 단독으로 사용하는 경우가 거의 없습니다.
빌드 생성자
프로토타입 체인에 존재하는 두 가지 문제를 해결하기 위해 개발자들은 프로토타입 체인에 존재하는 문제를 해결하기 위해 차용 생성자라는 기술을 사용하기 시작했습니다. 이 기술의 구현 아이디어도 매우 간단합니다. 하위 유형의 생성자 내에서 상위 유형의 생성자를 호출하기만 하면 됩니다. 잊지 마세요. 함수는 특정 환경에서 코드를 실행하는 객체일 뿐이므로 apply() 또는 call() 메서드를 통해 생성자를 실행할 수 있습니다. 코드는 다음과 같습니다.
// 为父类型创建构造函数 function SuperType(name) { this.name = name; this.color = ['pink', 'yellow']; this.property = true; this.testFun = function() { alert('http://tools.jb51.net/'); } } // 为父类型添加方法 SuperType.prototype.getSuerperValue = function() { return this.property; } // 为子类型创建构造函数 function SubType(name) { SuperType.call(this, name); this.test = ['h1', 'h2', 'h3', 'h4']; this.subproperty = false; } // 在此处给子类型添加方法,一定要在实现继承之后,否则会在将指针指向父类型的实例,则方法为空 SubType.prototype.getSubValue = function() { return this.subproperty; } /* 以下为测试代码示例 */ var instance1 = new SubType(['wuyuchang', 'Jack', 'Nick']); instance1.name.push('hello'); instance1.test.push('h5'); instance1.color.push('blue'); instance1.testFun(); // http://tools.jb51.net/ alert(instance1.name); // wuyuchang,Jack,Nick,hello // alert(instance1.getSuerperValue()); // error 报错 alert(instance1.test); // h1,h2,h3,h4,h5 alert(instance1.getSubValue()); // false alert(instance1.color); // pink,yellow,blue var instance2 = new SubType('wyc'); instance2.testFun(); // http://tools.jb51.net/ alert(instance2.name); // wyc // alert(instance2.getSuerperValue()); // error 报错 alert(instance2.test); // h1,h2,h3,h4 alert(instance2.getSubValue()); // false alert(instance2.color); // pink,yellow
위 코드에서 하위 유형 SubType의 생성자는 상위 유형 "SuperType.call(this, name);"을 호출하여 속성 상속을 구현하는 것을 볼 수 있습니다. 하위 유형의 인스턴스가 전달되었지만 새로운 문제가 다시 발생합니다. 상위 유형의 생성자 testFun에 메서드를 정의하고 상위 유형의 프로토타입에 getSuperValue라는 메서드를 정의한 것을 볼 수 있습니다. 그러나 이 하위 유형을 인스턴스화한 후에도 여전히 상위 유형의 프로토타입에 정의된 getSuperValue 메소드를 호출할 수 없습니다. 이는 상위 유형의 생성자 메소드인 testFun만 호출할 수 있습니다. . 이는 객체를 생성할 때 생성자 패턴만 사용하여 함수를 재사용할 수 없게 만드는 것과 같습니다. 이러한 문제점을 고려하여 생성자를 빌리는 기법은 단독으로 사용되는 경우가 거의 없다.
결합 상속(프로토타입 체인 차용 생성자)
이름에서 알 수 있듯이 결합 상속은 프로토타입 체인을 사용하는 것과 생성자를 차용하는 것의 장점을 결합한 패턴입니다. 구현도 매우 간단하기 때문에 양쪽의 장점, 즉 프로토타입 체인 상속 방식과 생성자 상속 속성 을 확실히 결합한 것입니다. 구체적인 코드 구현은 다음과 같습니다.
// 为父类型创建构造函数 function SuperType(name) { this.name = name; this.color = ['pink', 'yellow']; this.property = true; this.testFun = function() { alert('http://tools.jb51.net/'); } } // 为父类型添加方法 SuperType.prototype.getSuerperValue = function() { return this.property; } // 为子类型创建构造函数 function SubType(name) { SuperType.call(this, name); this.test = ['h1', 'h2', 'h3', 'h4']; this.subproperty = false; } SubType.prototype = new SuperType(); // 在此处给子类型添加方法,一定要在实现继承之后,否则会在将指针指向父类型的实例,则方法为空 SubType.prototype.getSubValue = function() { return this.subproperty; } /* 以下为测试代码示例 */ var instance1 = new SubType(['wuyuchang', 'Jack', 'Nick']); instance1.name.push('hello'); instance1.test.push('h5'); instance1.color.push('blue'); instance1.testFun(); // http://tools.jb51.net/ alert(instance1.name); // wuyuchang,Jack,Nick,hello alert(instance1.getSuerperValue()); // true alert(instance1.test); // h1,h2,h3,h4,h5 alert(instance1.getSubValue()); // false alert(instance1.color); // pink,yellow,blue var instance2 = new SubType('wyc'); instance2.testFun(); // http://tools.jb51.net/ alert(instance2.name); // wyc alert(instance2.getSuerperValue()); // true alert(instance2.test); // h1,h2,h3,h4 alert(instance2.getSubValue()); // false alert(instance2.color); // pink,yellow
위 코드는 SuperType.call(this, name);을 통해 상위 유형의 속성을 상속하고 SubType.prototype = new SuperType();을 통해 상위 유형의 메서드를 상속합니다. 위의 코드는 프로토타입 체인과 빌린 생성자에서 발생하는 문제를 편리하게 해결하며 JavaScript에서 가장 일반적으로 사용되는 인스턴스 상속 방법이 되었습니다. 하지만 혼합 모드에도 단점이 있는 것은 아닙니다. 위의 코드에서 메서드를 상속할 때 상위 유형의 속성이 실제로 상속되는 것을 볼 수 있습니다. 그러나 이때 참조 유형이 공유되므로 이를 호출합니다. 하위 유형의 생성자에서 두 번 발생합니다. 부모 유형의 생성자는 부모 유형의 속성을 상속하고 프로토타입에 상속된 속성을 덮어씁니다. 분명히 생성자를 두 번 호출할 필요가 없지만 해결할 수 있는 방법이 있습니까? 이 문제를 해결할 때 다음 두 가지 패턴을 살펴보겠습니다.
프로토타입 상속
프로토타입 상속의 구현 방법은 일반 상속의 구현 방법과 다릅니다. 프로토타입 상속은 엄밀한 의미에서 생성자를 사용하지 않고, 대신 프로토타입을 사용하여 사용자 정의 유형을 생성하지 않고 기존 객체를 기반으로 새 객체를 생성합니다. . 구체적인 코드는 다음과 같습니다.
function object(o) { function F() {} F.prototype = o; return new F(); }
코드 예:
/* 原型式继承 */ function object(o) { function F() {} F.prototype = o; return new F(); } var person = { name : 'wuyuchang', friends : ['wyc', 'Nicholas', 'Tim'] } var anotherPerson = object(person); anotherPerson.name = 'Greg'; anotherPerson.friends.push('Bob'); var anotherPerson2 = object(person); anotherPerson2.name = 'Jack'; anotherPerson2.friends.push('Rose'); alert(person.friends); // wyc,Nicholas,Tim,Bob,Rose
기생 상속
/* 寄生式继承 */ function createAnother(original) { var clone = object(original); clone.sayHi = function() { alert('hi'); } return clone; }
사용 예:
/* 原型式继承 */ function object(o) { function F() {} F.prototype = o; return new F(); } /* 寄生式继承 */ function createAnother(original) { var clone = object(original); clone.sayHi = function() { alert('hi'); } return clone; } var person = { name : 'wuyuchang', friends : ['wyc', 'Nicholas', 'Rose'] } var anotherPerson = createAnother(person); anotherPerson.sayHi();
寄生组合式继承
前面说过了JavaScrip中组合模式实现继承的缺点,现在我们就来解决它的缺点,实现思路是,对于构造函数继承属性,而原型链的混成形式继承方法,即不用在继承方法的时候实例化父类型的构造函数。代码如下:
function object(o) { function F() {} F.prototype = o; return new F(); } /* 寄生组合式继承 */ function inheritPrototype(subType, superType) { var prototype = object(superType.prototype); prototype.constructor = subType; subType.prototype = prototype; }
而在使用时只需要将组合模式中的“SubType.prototype = new SuperType();”这行代码替换成inheritPrototype(subType, superType);即可。寄生组合式继承的高效率体现在它只调用了一次父类型构造函数,避免了创建不必要的或多余的属性。与此同时,原型链还能保持不变,因此,还能够正常使用instanceof和isPrototypeof()。这也是目前来说最理想的继承方式了,目前也在向这种模式转型。(YUI也使用了这种模式。)
此博文参考《JavaScript高级程序设计第3版》,代码为经过改写,更具体,并加了注释使大家更易懂。如对JS继承方面有独到见解的童鞋不别吝啬,回复您的见解供大家参考!

핫 AI 도구

Undresser.AI Undress
사실적인 누드 사진을 만들기 위한 AI 기반 앱

AI Clothes Remover
사진에서 옷을 제거하는 온라인 AI 도구입니다.

Undress AI Tool
무료로 이미지를 벗다

Clothoff.io
AI 옷 제거제

AI Hentai Generator
AI Hentai를 무료로 생성하십시오.

인기 기사

뜨거운 도구

메모장++7.3.1
사용하기 쉬운 무료 코드 편집기

SublimeText3 중국어 버전
중국어 버전, 사용하기 매우 쉽습니다.

스튜디오 13.0.1 보내기
강력한 PHP 통합 개발 환경

드림위버 CS6
시각적 웹 개발 도구

SublimeText3 Mac 버전
신 수준의 코드 편집 소프트웨어(SublimeText3)

뜨거운 주제









함수 상속에서는 "기본 클래스 포인터" 및 "파생 클래스 포인터"를 사용하여 상속 메커니즘을 이해합니다. 기본 클래스 포인터가 파생 클래스 개체를 가리키는 경우 상향 변환이 수행되고 기본 클래스 멤버에만 액세스됩니다. 파생 클래스 포인터가 기본 클래스 개체를 가리키는 경우 하향 캐스팅이 수행되므로(안전하지 않음) 주의해서 사용해야 합니다.

상속과 다형성은 클래스 결합에 영향을 줍니다. 상속은 파생 클래스가 기본 클래스에 종속되기 때문에 결합을 증가시킵니다. 다형성은 객체가 가상 함수와 기본 클래스 포인터를 통해 일관된 방식으로 메시지에 응답할 수 있기 때문에 결합을 줄입니다. 모범 사례에는 상속을 적게 사용하고, 공용 인터페이스를 정의하고, 기본 클래스에 데이터 멤버를 추가하지 않고, 종속성 주입을 통해 클래스를 분리하는 것이 포함됩니다. 다형성과 종속성 주입을 사용하여 은행 계좌 애플리케이션에서 결합을 줄이는 방법을 보여주는 실제 예입니다.

PHP 오류 해결: 상위 클래스 상속 시 발생하는 문제 PHP에서 상속은 객체 지향 프로그래밍의 중요한 기능입니다. 상속을 통해 기존 코드를 재사용하고 원본 코드를 수정하지 않고도 확장하고 개선할 수 있습니다. 상속은 개발에 널리 사용되지만 부모 클래스에서 상속할 때 가끔 오류 문제가 발생할 수 있습니다. 이 문서에서는 부모 클래스에서 상속할 때 발생하는 일반적인 문제를 해결하는 데 중점을 두고 해당 코드 예제를 제공합니다. 질문 1: 시스템이 상위 클래스를 상속하는 과정에서 상위 클래스를 찾을 수 없습니다.

상속 오류 디버깅 팁: 올바른 상속 관계를 확인하세요. 디버거를 사용하여 코드를 단계별로 실행하고 변수 값을 검사합니다. 가상 수정자를 올바르게 사용했는지 확인하세요. 숨겨진 상속으로 인해 발생하는 상속 다이아몬드 문제를 살펴봅니다. 추상 클래스에서 구현되지 않은 순수 가상 함수를 확인하세요.

상속은 한 클래스의 속성과 동작을 다른 클래스에서 액세스할 수 있게 해주는 개념입니다. 메서드와 멤버 변수를 상속하는 클래스를 슈퍼클래스 또는 부모 클래스라고 하며, 이러한 메서드와 멤버 변수를 상속하는 클래스를 하위 클래스 또는 하위 클래스라고 합니다. Java에서는 클래스를 상속하기 위해 "extends" 키워드를 사용합니다. 이 기사에서는 상속을 사용하여 정기 예금과 정기 예금에 대한 이자를 계산하는 Java 프로그램에 대해 설명합니다. 먼저 로컬 시스템 IDE에서 네 개의 Java 파일(Acnt.java)을 생성합니다. 이 파일에는 이자율 및 금액과 같은 계정 세부 정보를 저장하는 데 사용되는 추상 클래스 'Acnt'가 포함됩니다. 또한 계산을 위한 매개변수 'amnt'가 있는 추상 메소드 'calcIntrst'도 있습니다.

다형성과 상속을 사용하여 PHP에서 데이터 유형을 처리하는 방법 소개: PHP에서 다형성과 상속은 두 가지 중요한 객체 지향 프로그래밍(OOP) 개념입니다. 다형성과 상속을 사용하면 다양한 데이터 유형을 보다 유연하게 처리할 수 있습니다. 이 기사에서는 다형성과 상속을 사용하여 PHP에서 데이터 유형을 처리하는 방법을 소개하고 코드 예제를 통해 실제 적용 방법을 보여줍니다. 1. 상속의 기본 개념 상속은 객체지향 프로그래밍에서 중요한 개념으로, 부모 클래스의 속성과 메서드를 상속받을 수 있는 클래스를 생성할 수 있게 해줍니다.

PHP의 캡슐화 기술과 애플리케이션 캡슐화는 객체 지향 프로그래밍에서 중요한 개념입니다. 이는 외부 프로그램에 대한 통합 액세스 인터페이스를 제공하기 위해 데이터와 데이터에 대한 작업을 함께 캡슐화하는 것을 의미합니다. PHP에서는 액세스 제어 수정자와 클래스 정의를 통해 캡슐화를 달성할 수 있습니다. 이 기사에서는 PHP의 캡슐화 기술과 해당 애플리케이션 시나리오를 소개하고 몇 가지 구체적인 코드 예제를 제공합니다. 1. 캡슐화된 액세스 제어 수정자 PHP에서 캡슐화는 주로 액세스 제어 수정자를 통해 이루어집니다. PHP는 세 가지 액세스 제어 수정자를 제공합니다.

C++ 함수 상속에 대한 자세한 설명: "is-a"와 "has-a" 사이의 관계를 마스터하세요. 함수 상속이란 무엇인가요? 함수 상속은 파생 클래스에 정의된 메서드를 기본 클래스에 정의된 메서드와 연결하는 C++의 기술입니다. 파생 클래스가 기본 클래스의 메서드에 액세스하고 재정의할 수 있도록 하여 기본 클래스의 기능을 확장합니다. "is-a" 및 "has-a" 관계 함수 상속에서 "is-a" 관계는 파생 클래스가 기본 클래스의 하위 유형, 즉 파생 클래스가 기본 클래스의 특성과 동작을 "상속"함을 의미합니다. 기본 클래스. "has-a" 관계는 파생 클래스에 기본 클래스 개체에 대한 참조 또는 포인터가 포함되어 있음을 의미합니다. 즉, 파생 클래스가 기본 클래스 개체를 "소유"합니다. 구문다음은 함수 상속을 구현하는 방법에 대한 구문입니다. classDerivedClass:pu
