<commit_before>---
layout: post
title: JS继承
category: JS
tags: JS继承
description: 
---

## 6种继承方式
## 1.原型链继承
```js
//1.原型链继承
function Super(){
	this.val = 1;
	this.arr = [1];
}
function Sub(){

}
Sub.prototype = new Super();  //核心

var sub1 = new Sub();
var sub2 = new Sub();

sub1.val = 2;
sub1.arr.push(2);

console.log(sub1.val);  //2
console.log(sub2.val);  //1
console.log(sub1.arr);  //1,2
console.log(sub2.arr);  //1,2
```

### 核心
拿父类实例来充当子类的原型对象

### 优缺点
优点：简单，易于实现

缺点：

1.修改sub1.arr后sub2.arr也变了，因为来自原型对象的引用属性是所有实例共享的。

执行sub1.arr.push(2);先对sub1进行属性查找，找遍了实例属性也没找到，就开始顺着原型链找，找到了sub1的原型对象，所以是改变了原型的引用属性。

2.创建子类实例时，无法向父类构造函数传参。

## 借用构造函数
```js
//2.构造函数继承
function Super(val){
	this.val = val;
	this.arr = [1];

	this.fun = function(){

	}
}

function Sub(val){
	Super.call(this,val);  //核心
}

var sub1 = new Sub(1);
var sub2 = new Sub(2);

sub1.arr.push(2);

console.log(sub1.val);  //1
console.log(sub2.val);  //2
console.log(sub1.arr);  //1,2
console.log(sub2.arr);  //1
console.log(sub1.fun === sub2.fun);  //false

```
### 核心
借父类的构造函数来增强子类实例，等于是把父类的实例属性复制了一份给子类实例装上了。（没用到原型）

### 优缺点
优点：

1.解决了子类实例共享父类引用属性的问题

2.创建子类实例时，可以向父类构造函数传参

缺点：无法实现函数复用，每个子类实例都有一个新的fun函数，太多了就会影响性能，内存爆炸。

## 组合继承（最常用）
```js
//3.组合继承
function Super(){
	this.val = 1;
	this.arr = [1];
}
Super.prototype.fun1 = function(){};
Super.prototype.fun2 = function(){};

function Sub(){
	Super.call(this);  //核心
}
Sub.prototype = new Super();  //核心

var sub1 = new Sub();
var sub2 = new Sub();<commit_msg>Update 2018-06-20-JS继承.md<commit_after>---
layout: post
title: JS继承
category: JS
tags: JS继承
description: 
---

## 6种继承方式
## 1.原型链继承
```js
//1.原型链继承
function Super(){
	this.val = 1;
	this.arr = [1];
}
function Sub(){

}
Sub.prototype = new Super();  //核心

var sub1 = new Sub();
var sub2 = new Sub();

sub1.val = 2;
sub1.arr.push(2);

console.log(sub1.val);  //2
console.log(sub2.val);  //1
console.log(sub1.arr);  //1,2
console.log(sub2.arr);  //1,2
```

### 核心
拿父类实例来充当子类的原型对象

### 优缺点
优点：

1.简单，易于实现

2.实例是父类的实例，也是子类的实例

3.父类新增原型方法或属性，子类都能访问到

缺点：

1.修改sub1.arr后sub2.arr也变了，因为来自原型对象的引用属性是所有实例共享的。

执行sub1.arr.push(2);先对sub1进行属性查找，找遍了实例属性也没找到，就开始顺着原型链找，找到了sub1的原型对象，所以是改变了原型的引用属性。

2.创建子类实例时，无法向父类构造函数传参。

## 借用构造函数
```js
//2.构造函数继承
function Super(val){
	this.val = val;
	this.arr = [1];

	this.fun = function(){

	}
}

function Sub(val){
	Super.call(this,val);  //核心
}

var sub1 = new Sub(1);
var sub2 = new Sub(2);

sub1.arr.push(2);

console.log(sub1.val);  //1
console.log(sub2.val);  //2
console.log(sub1.arr);  //1,2
console.log(sub2.arr);  //1
console.log(sub1.fun === sub2.fun);  //false

```
### 核心
借父类的构造函数来增强子类实例，等于是把父类的实例属性复制了一份给子类实例装上了。（没用到原型）

### 优缺点
优点：

1.解决了子类实例共享父类引用属性的问题

2.创建子类实例时，可以向父类构造函数传参

3.可以实现多类继承（call多个父类对象）

缺点：

1.无法实现函数复用，每个子类实例都有一个新的fun函数，太多了就会影响性能，内存爆炸。

2.实例不是父类的实例，只是子类的实例

3.只能继承父类的实例属性和方法，无法继承原型属性或方法

## 组合继承（最常用）
```js
//3.组合继承
function Super(){
	this.val = 1;
	this.arr = [1];
}
Super.prototype.fun1 = function(){};
Super.prototype.fun2 = function(){};

function Sub(){
	Super.call(this);  //核心
}
Sub.prototype = new Super();  //核心

var sub1 = new Sub();
var sub2 = new Sub();
{'fraction_non_alphanumeric': 0.19838709677419356, 'fraction_numerical': 0.04161290322580645, 'mean_word_length': 3.9616, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1663397', 'n_tokens_mistral': 1857, 'n_tokens_neox': 2042, 'n_words': 255}