本篇主要是简单回顾面向对象的编程。
# 封装
使用工厂模式进行封装
function createCat() {
var obj = {};
obj.name = name;
obj.eat = function() {
console.log(name + "eat something");
};
return obj;
}
var catA = createCat("xiaoA");
var catB = createCat("xiaoB");
var catC = createCat("xiaoC");
1
2
3
4
5
6
7
8
9
10
11
2
3
4
5
6
7
8
9
10
11
# 1. this 指向问题
# 2. new 干了什么
// 区分构造函数和一般函数的区别,一般构造函数首字母大写
function CreateCat(name){
this.name=name
this.eat=fucntion(){
console.log('abc')
}
}
// 在生命函数的时候,会自动创建一个prototype属性,这个叫原型,一般用来存放实例公用方法
CreateCat.prototype.eat=fucntion(something){
console.log(this.name+'eat'+something)
}
var catA=new CreateCat=('xiaoA')
catA.eat('finish')
// 在js里规定,访问对象属性的时候,如果对象下面没有这个属性,则去它下面的__proto__去寻找,如果害没有就一直向下寻找知道没有__proto__为止
console.log(catA)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
以上执行结果:

# 继承
# 1.类式继承
问题:
- 这种方法不支持父构造函数带参数
- 父构造函数里的方法和属性都会编程共有属性
fucntion A(name){
this.name=name
this.list=[1,2,3,4]
}
A.prototype.getName=fucntion(){
console.log(this.name)
}
function SubA(name){
this.subName='sub'+this.name
}
SubA.prototype=new A()
// var sa1=new SubA('sa1')
// console.log(sa1.list,sal.name) // [1,2,3] undefined
/*
执行 var sa1=new SubA('sa1'),做了什么?
SubA.prototype=new A()->{
name:undefined
list:[1,2,3], 这里属性共享了
__proto__:{
getName:fn
constructor...
}
}
*/
var sal=new SubA('sa1')
var sa2=new SubA('sa2')
A.prototype.getName=fucntion(){
console.log('fixed getName')
}
A.prototype.newFn=fucntion(){
console.log('fixed getName')
}
sa1.getName()
sa2.newFn()
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
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
# 2.构造函数继承
问题:不能继承父构造函数的原型方法
fucntion A(name){
this.name=name
this.list=[1,2,3,4]
}
A.prototype.getName=fucntion(){
console.log(this.name)// 这里漏掉了
}
fucntion SubA(name){
A.call(this,name)
this.subName='sub'+this.name
}
var sa1=new SubA('xiaoA')
console.log(sa1.list,sal.name)
sa1.getName()//报错,因为不能继承父构造函数的原型方法
/*
分析:漏掉了父构造函数的原型方法
sa1= new SubA('xiaoA')->{
__proto__:{constructor...},
name:'xiaoA',
list:[1,2,3],
subName:'sub XiaoA'
}
*/
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
# 3.组合式继承
小问题:
- _proto里面的属性没有用
- 执行两次父构造函数
function A(name) {
this.name = name;
this.list = [1, 2, 3];
}
A.prototype.getName=function(){
console.log(this.name)
}
fucntion SubA(name){
A.call(this,name)
this.subName='sub'+this.name
}
SubA.prototype=new A()
var sa1=new SubA('xiaoA')
console.log(sa1.name,sa1.subName)//xiaoA sub xiaoA
sa1.getName()//xiaoA
/*
SubA.prototype=new A()->{
name:undefined
list:[1,2,3],
__proto__:{
getName:fn
}
}
var sa1= new SubA('xiaoA')->{
name:'xiaoA',
list:[1,2,3],
subName:'sub XiaoA',
__proto__:{
name:'xiaoA',
list:[1,2,3],
__proto__:{
getName:fn
}
},
}
*/
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
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
# 4.寄生组合式继承
function A(name) {
this.name = name;
this.list = [1, 2, 3];
}
A.prototype.getName=function(){
console.log(this.name)
}
fucntion SubA(name){
A.call(this,name)
this.subName='sub'+this.name
}
//问题出现在这: SubA.prototype=new A()
// 所以,改个写法
function inheritPrototype(subClass,superClass){
function F(){}
F.prototypr=superClass.prototype
subClass.prototype=new F()//这里导致constructor没有了,可以写回去
// subClass.prototype.constructor=subClass
}
inheritPrototype(subA,A)
var sa1=new SubA('xiaoA')
console.log(sa1.name,su1.subName)
sa1.getName()
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
# 多态
- 定义:表示不同对象调用相同方法会产生不同结果 SubaA,SubB 都是继承 Base,但是调用同样 initial 方法会产生不同结果
fucntion Base(){}
Base.prototype.initial=fucntion(){
this.init()
}
fucntion SubA(){
this.init=fucntion(){
console.log('subA init')
}
}
fucntion SubB(){
this.init=fucntion(){
console.log('subB init')
}
}
SubA.prototype=new Base()
SubB.prototype=new Base()
var subA=new SubA()
var subB=new SubB()
// SubaA,SubB 都是继承 Base,但是调用同样 initial 方法会产生不同结果
subA.initial() // subA init
subB.initial() // subB init
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21