기사 디렉토리
6 개의 상속 방법이 있습니다 : 생성자 상속, 프로토 타입 체인 상속, 결합 상속, 프로토 타입 상속, 기생 상속, 기생 결합 상속
하나, 생성자 상속
함수를 사용하여 상속 구현
//父类构造函数
function Father(){
this.name = "Father";
this.say = function(){
console.log(this.name);
}
}
//子类构造函数
function Son(){
Father.call(this); // 重点
}
중요 : call을 사용하여 상위 클래스 생성자를 하위 클래스 함수에 도입합니다 (부모 클래스는 하위 클래스 함수에 복사 됨).
테스트:
let son1 = new Son();
son1.say(); // Father
son1은 부모 클래스의 name 속성과 say 메서드를 성공적으로 상속했습니다.
그러나 이것은 전통적인 의미에서 상속이 아닙니다. 부모 클래스를 호출하는 각 Son 하위 클래스에 의해 생성 된 객체가 서로 독립적이기 때문입니다. 즉, 부모 클래스가 모든 하위 클래스 인스턴스가 공유하는 공통 속성을 갖기를 원하면 달성 할 수 없습니다.
이점:
- 여러 생성자 상속 가능 (다중 호출 가능)
- 모든 기본 속성은 독립적이며 다른 인스턴스의 영향을받지 않습니다.
단점 :
- 부모 클래스 생성자 (.prototype)의 속성과 메서드를 상속 할 수 없습니다.
- 각각의 새 인스턴스는 부모 생성자를 복사합니다. 부모 클래스가 매우 크면 메모리를 차지합니다.
- 공용 메소드의 재사용 (함수 재사용)은 구현되지 않으며 공유 대신 매번 새로운 함수가 생성됩니다.
2. 프로토 타입 체인 상속
프로토 타입 속성 상속을 통한 가장 원시적 인 방법
//父级 构造函数
function Father() {
this.arr = [1,2,3];
}
//父级 原型属性
Father.prototype.name = "tingting"
//子级 构造函数
function Son() {
}
//子级 原型属性: 继承父级
Son.prototype = new Father() // 重点
//创建子级的实例对象
let son = new Son();
console.log(son.name); // tingting
중요 : 하위 클래스의 프로토 타입은 상위 클래스의 인스턴스와 동일합니다. Son.prototype = new Father()
아들 인스턴스가 이름 속성을 찾는 방법을 설명합니다.
객체의 특정 속성을 찾을 수없는 경우 프로토 타입을 따라 조회하고 프로토 타입 체인이 끝날 때까지 검색을 중지합니다.
- 발견되지 않은 경우 아들 객체 자체에서 먼저 검색
- Son.prototype에서 (Father ())를 찾을 수없는 경우 찾습니다.
- 상위 수준
Son.prototype.__proto__
(Father.prototype) - 필요한 속성 또는 메서드를 찾거나 프로토 타입 체인 Object.prototype의 맨 위에 도달 할 때까지
그러나 자식 인스턴스의 모든 속성과 메서드는 부모 클래스의 동일한 인스턴스에 있으므로 자식 인스턴스가 메서드를 수정하면 다른 모든 자식 인스턴스가 영향을받습니다.
다음 코드를보십시오 .
function Father() {
this.arr = [1,2,3];
}
function Son() {
}
Son.prototype = new Father()
let son1 = new Son();
let son2 = new Son();
son1.arr.push(4);
console.log(son1.arr); // 1,2,3,4
console.log(son2.arr);// 1,2,3,4
자식 인스턴스 son1이 arr을 수정하면 son2 인스턴스의 arr도 수정됩니다.
이점:
- 단순한
단점 :
- 매개 변수를 상위 클래스 생성자에 전달할 수 없습니다.
- 모든 인스턴스는 상위 인스턴스의 속성을 공유합니다 (인스턴스가 수정되면 모든 속성이 변경됨).
셋, 컴포지션 상속 (프로토 타입 체인 + 생성자)
프로토 타입 체인 상속과 차용 생성자 상속을 결합하여 일반적으로 사용되는 둘의 장점을 통합합니다.
function Father(color) {
this.color = color;
}
Father.prototype.print = function() {
console.log(this.color);
}
function Son(color) {
Father.call(this, color); // 借用构造函数继承
}
Son.prototype = new Father(); // 原型链继承
let son1 = new Son('red');
son1.print(); // red
let son2 = new Son('blue');
son2.print(); // blue
Son 하위 클래스에서는 Father.call을 사용하여 부모 클래스 생성자를 호출하고 Son.prototype을 부모 클래스 인스턴스에 할당합니다
. Father.call을 사용하여 부모 클래스 생성자를 호출 한 후 모든 후속 new Son()
인스턴스는 Copy a copy를 통해 생성됩니다. 부모 클래스 생성자에 정의 된 속성 및 메서드,
다음 서브 클래스의 프로토 타입 프로토 타입 부모 클래스의 인스턴스를 할당 속성 및 부모 클래스 프로토 타입의 메소드를 공유 할 수있는 모든 서브 클래스의 인스턴스는,
그러므로, 부모 클래스 정의 작성을 , 개인 넣어 생성자에 속성과 메서드를 추가하고 프로토 타입에 공유 속성과 메서드를 넣습니다.
이점:
- 매개 변수를 전달할 수 있습니다.
- 일반적인 기능을 재사용 할 수 있습니다.
단점 : - 부모 클래스 생성자를 두 번 호출하여 메모리를 차지합니다.
넷, 프로토 타입 상속
프로토 타입 상속의 본질은 실제로 새 객체를 복사하기위한 템플릿으로 객체를 사용하는 얕은 사본입니다 .
// 封装一个函数容器,用来承载继承的原型
function object(obj){
function F(){
}
F.prototype = obj;
return new F();
}
let father = {
name: "father",
arr: [1,2,3]
}
let son1 = object(father);
개체 함수에서 생성자를 정의하고 obj를 템플릿으로 사용하고 생성자의 프로토 타입 개체가 obj를 가리 키도록 한 다음 생성자의 인스턴스를 반환하면 개체 obj의 모든 속성과 메서드에 액세스 할 수 있습니다.
Object.creat ()
새로운 함수 Object.create ()가 es5에 추가되어 프로토 타입 상속을 직접 구현합니다.
위 코드는 다음과 같이 다시 작성할 수 있습니다.
let father = {
name: "father",
arr: [1,2,3]
}
let son1 = Object.create(obj);
본질은 여전히 프로토 타입 체인 상속이며 부모 클래스의 속성도 공유합니다.
다섯, 기생 상속
기생 상속은 프로토 타입 상속을 다시 캡슐화 한 다음 객체에 대한 새 메서드를 확장 한 다음 새 객체를 반환하는 것입니다.
프로토 타입 상속을 기반으로 일부 기능이나 속성을 추가하는 것으로 이해할 수 있습니다 .
function object(obj){
function F(){
}
F.prototype = obj;
return new F();
}
// 上面是原型式继承
function create(obj){
let clone = object(obj) // 或 Object.create(obj)
clone.say = function(){
console.log('123');
}
return clone;
}
// 用create函数封装了一遍,又增添了say方法
let father = {
name: "father",
arr: [1,2,3]
}
let son = create(father);
son.say(); // 123
Clone은 객체에 새 메서드를 추가하고 마지막으로 clone으로 돌아가서 객체가 반환 한 객체를 상속합니다.
이점:
- 사용자 지정 유형을 만들 필요가 없습니다.
단점 :
- 프로토 타입은 사용되지 않으며 재사용 할 수 없습니다.
6. 기생 결합 상속 (일반적으로 사용됨)
마지막 상속 방법은 가장 완벽한 솔루션입니다
.ES6 클래스 문법의 실현 원리입니다. 주된 목적은 결합 상속에서 매번 new Father가 필요하다는 단점을 해결하여 부모 클래스 생성자의 실행으로 이어집니다. .
function Father(color) {
this.color = color;
}
Father.prototype.print = function() {
console.log(this.color);
}
function Son(color) {
Father.call(this, color);
}
Son.prototype = Object.create(Father.prototype); // 划重点
let son1 = new Son('red');
son1.print(); // red
let son2 = new Son('blue');
son2.print(); // blue
상속 및 단 하나의 조합이 다르다 원래 인 Son.prototype = new Father();
개정Son.prototype = Object.create(Father.prototype);
Object.create
프로토 타입 에서 언급 한 방법은 들어오는 객체를 프로토 타입으로 사용하여 새 객체를 만드는 것입니다. 새 객체가 생성 된 후에 할당 Son.prototype
되므로 Son의 프로토 타입은 궁극적으로 new Father
동일한 부모 클래스의 프로토 타입 객체를 가리 킵니다. 메모리를 차지하기 위해 중복 인스턴스를 생성하지 않고 그 효과는 물론 다중 상속을 달성 할 수도 있습니다.