说实话关于原型链和面向对象我已经看过很多次了,对看过很多次了,但是依旧不能清晰的表达出他们直接的关系【理解不深】。类似于网上大家说的关于看过一本书,让你说出这本书说了什么了,你吞吞吐吐的回答道:嗯………就是那个那个……嗯…………。好,结束,对说不出来。今天我就自己来分析分析,下次你来问我,我讲给你听啊~~~^_^
- 创建对象的几种方式
针对上面贴出来的代码我们说几个概念
构造函数,原型,实例,原型对象,原型链
1.构造函数:new 后面的函数fn就是构造函数
2.实例:o1,o2,o3 对象都是实例。
3.函数的原型prototype:函数一创建就有prototype,prototype是一个对象,指向了当前构造函数的引用地址。
4.函数的原型对象__proto__:所有对象都有__proto__属性, 当用构造函数实例化(new)一个对象时,会将新对象的__proto__属性指向 构造函数的prototype。
下面我们用一张图来说明他们之间的联系:
实例对象o2通过构造函数fn 用new方法来创建,构造函数fn通过prototype属性访问它的原型对象,原型对象的constructor属性指向构造函数。
实例对象o2通过__proto__属性访问fn的原型对象,fn的原型对象又通过__proto__ 查找它上一级的原型对象,这样一级一级往上查找,直至Object的原型。整个过程我们称之为原型链。
- 原型链之instanceof
判断实例对象的__proto__属性是否跟构造函数的prototype以及它的上级原型对象相关联【详细可看其他文章】
- 面向对象的继承
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
/**
* [构造函数实现继承]
* @return {[type]} [description]
* 缺点:只能继承父类构造函数里的属性方法,原型链上的属性和方法访问不到
*/
function c1 (){
p1.call(this)
}
p1.prototype.say = function(){
console.log("say")
}
var t1 = new c1()
/**
* [c2 原型链实现继承]
* @return {[type]} [description]
* 缺点: 子类如果创建多个对象,某一个对象将父类的属性改变,则其他对象也相应的会改变,
*/
function p2 (){
this.name = "parent2";
this.type = [1,2,3]
}
function c2 (){
this.age = 3
}
c2.prototype = new p2()
c2.prototype.say = function (){
console.log(1)
}
var t2 = new c2()
var t2_1 = new c2()
t2.type.push(4)
console.log(t2_1.type) // [1,2,3,4]
/**
* [构造函数+原型链实现]
*
*缺点: 父类函数执行了两次
* @return {[type]} [description]
*/
function p3 (){
this.name = "parent3";
this.type = [1,2,3]
}
function c3 (){
p3.call(this)
this.age = 3
}
c3.prototype = new p3()
c3.prototype.say = function (){
console.log(1)
}
var t3 = new c3()
var t3_1 = new c3()
t3.type.push(4)
console.log(t3_1.type) // [1,2,3]
/**
* [构造函数+原型链实现 优化]
* 缺点:无法判断当前对象是由子类创建的还是父类创建的
* @return {[type]} [description]
*/
function p4 (){
this.name = "parent3";
this.type = [1,2,3]
}
function c4 (){
p4.call(this)
this.age = 3
}
c4.prototype = p4.prototype
c4.prototype.say = function (){
console.log(1)
}
var t4 = new c4()
var t4_1 = new c4()
t4.type.push(4)
console.log(t4_1.type) // [1,2,3]
console.log(t4.constructor ) // p4
/**
* [构造函数+原型链实现 优化2]
* 完美
* @return {[type]} [description]
*/
function p5 (){
this.name = "parent5";
this.type = [1,2,3]
}
function c5 (){
p5.call(this)
this.age = 3
}
c5.prototype = Object.create(p5.prototype)
p5.prototype.constructor = c5
var t5 = new c5()
var t5_1 = new c5()