-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathjs继承的几种方式.js
171 lines (152 loc) · 6.07 KB
/
js继承的几种方式.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
/**
* 构造函数式定义
* @param {*} name
* @param {*} voice
*/
function Animate (name, voice) {
this.name = name
this.voice = voice
this.feature = ['life', 'need oxygen', 'need nutrition'] //生命、需要氧气、需要营养
}
Animate.description = 'Created by Animate'
Animate.prototype.say = function () {
console.log(`I'm ${this.name}, ${this.voice}~~${this.voice}~~`)
return 1;
}
/**
* es6语法糖 class类定义
*/
class Animate2 {
constructor(name, voice) {
this.name = name
this.voice = voice
this.feature = ['life', 'need oxygen', 'need nutrition'] //生命、需要氧气、需要营养
}
say() {
console.log(`I'm ${this.name}, ${voice}~~${voice}~~`)
}
}
/*************************************以下为几种继承方式********************************************/
/**
* 原型
* 可以共享,但是一个实例修改原型属性,其他继承的实例也会受影响
* @param {*} name
* @param {*} voice
*/
function Fish() {
this.fishFeature = ['swimming', 'Spit bubbles', 'Live in water'] //游动,吐泡泡,生活在水中
}
Fish.prototype.name = '小金鱼'
Fish.prototype.voice = 'bubble bubble'
Fish.prototype.constructor = Fish
const fish = new Fish()
console.log(fish.name)//小金鱼
const fish2 = new Fish()
fish2.__proto__.name = '小龙虾'
console.log(fish.fishFeature)//['swimming', 'Spit bubbles', 'Live in water']
console.log(fish.name, fish2.name) //小龙虾,小龙虾
/**
* 构造函数继承
* 缺点:1、无法继承父类的原型链;2、父类方法在构造函数中定义,函数未复用。
*/
function Dog (name, voice, walk) {
Animate.call(this, name, voice)
this.walk = walk
this.dogFeature = this.feature.concat(['Four legs', 'cute', 'loyalty', 'Like the bones']) //四条腿、可爱、忠诚
}
Dog.prototype.go = function() {
console.log(`${this.walk}~~${this.walk}~~`)
}
let dog = new Dog('旺财', 'woff', 'dong')
console.log(dog.dogFeature) //[ 'life', 'need oxygen', 'need nutrition', 'Four legs', 'cute', 'loyalty', 'Like the bones']
console.log(dog.go())//dong~~dong~~
// console.log(dog.say()) //TypeError: dog.say is not a function
/**
* 组合继承:将原型继承和构造函数继承相结合
* 优点:完整的继承,继承父类的属性和方法+原型链的属性和方法
* 缺点:重复调用了父类的构造函数,根据原型链搜索原则,实例上的属性会屏蔽原型链上的属性
* @param {*} name
* @param {*} voice
* @param {*} walk
*/
function Cat(name, voice, walk) {
Animate.call(this, name, voice) //继承Animate的属性
this.walk = walk
this.catFeature = this.feature.concat(['Four legs', 'cute', 'loyalty', 'fuzzy', 'High cold or sticky']) //四条腿、可爱、毛茸茸、高冷或粘人
}
Cat.prototype = new Animate() //继承Animate原型链上的属性和方法,此处会覆盖Cat.prototype的constructor属性
Cat.prototype.constructor = Cat
Cat.prototype.go = function() {
console.log(`${this.walk}~~${this.walk}~~`)
}
const cat = new Cat('Orange', 'miao', 'tata')
console.log(cat.catFeature) //[ 'life', 'need oxygen', 'need nutrition', 'Four legs', 'cute', 'loyalty', 'fuzzy', 'High cold or sticky' ]
console.log(cat.go()) //tata~~tata~~
console.log(cat.say()) //I'm Orange, miao~~miao~~
/**
* 优化版的组合继承
* @param {*} name
* @param {*} voice
* @param {*} walk
*/
function Cat2(name, voice, walk) {
Animate.call(this, name, voice) //继承Animate的属性
this.walk = walk
this.catFeature = this.feature.concat(['Four legs', 'cute', 'loyalty', 'fuzzy', 'High cold or sticky']) //四条腿、可爱、毛茸茸、高冷或粘人
}
// function F() {}
// F.prototype = Animate.prototype
// Cat2.prototype = new F() //继承Animate原型链上的属性和方法,此处会覆盖Cat.prototype的constructor属性
// Cat2.prototype.constructor = Cat2
//或者使用Object.create(),与上面运行原理相同
Cat2.prototype = Object.create(Animate.prototype, {constructor: {value: Cat2}})
Cat2.prototype.go = function() {
console.log(`${this.walk}~~${this.walk}~~`)
}
const cat2 = new Cat2('Orange', 'miao', 'tata')
console.log(cat2.catFeature) //[ 'life', 'need oxygen', 'need nutrition', 'Four legs', 'cute', 'loyalty', 'fuzzy', 'High cold or sticky' ]
console.log(cat2.go()) //tata~~tata~~
console.log(cat2.say()) //I'm Orange, miao~~miao~~
/**
* 更简单的继承
* __proto__严格模式下不可用
* setPrototypeOf是es6版本对象新增的方法
*/
function Sheep(name, voice, walk) {
Animate.call(this, name, voice) //继承Animate的属性
this.walk = walk
this.sheepFeature = this.feature.concat(['Four legs', 'cute', 'loyalty', 'fuzzy', 'claw', 'delicious']) //四条腿、可爱、毛茸茸、羊角、美味
}
// 严格模式不可用
// Sheep.prototype.__proto__ = Animate.prototype
//与上面实现一样,将Sheep.prototype的__proto__指向Animate.prototype
Object.setPrototypeOf(Sheep.prototype, Animate.prototype)
//实现类的静态方法继承
Object.setPrototypeOf(Sheep, Animate)
Sheep.prototype.go = function() {
console.log(`${this.walk}~~${this.walk}~~`)
}
const sheep = new Sheep('暖暖', 'mie', 'tita')
console.log(sheep.sheepFeature) //[ 'life', 'need oxygen', 'need nutrition', 'Four legs', 'cute', 'loyalty', 'fuzzy', 'claw', 'delicious' ]
console.log(sheep.go()) //tita~~tita~~
console.log(sheep.say()) //I'm 暖暖, mie~~mie~~
console.log(Sheep.description) //Created by Animate
/**
* es6 class继承
*/
class Bird extends Animate {
constructor(name, voice, walk) {
super(name, voice, walk) // 始终指向父类,调用它就是调用了父类的构造函数
this.walk = walk
this.birdFeature = [...this.feature, 'Two legs', 'cute', 'Eat insects', 'Sharp mouth'] //两条腿、可爱、吃虫子、嘴巴尖尖
}
go() {
super.say()
console.log(`${this.walk}~~${this.walk}~~`)
}
static description = super.description
}
const bird = new Bird('骊歌', 'jiujiu', 'tita')
console.log(bird.birdFeature)
console.log('11', bird.go(), '111')
console.log('22', bird.say(), '222')