viviier

Javascript 原型继承和面向委托的设计模式

原型继承

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
function Foo(name) {
this.name = name;
}
Foo.prototype.sayName = function() {
console.log(this.name);
}
/* 构建原型 Foo */
function Bar(name, label) {
Foo.call(this, name); // this指向new Bar后的新实例对象 然后传入参数name
this.label = label;
}
Bar.prototype = Object.create(Foo.prototype);
/* 将Bar.prototype对象关联到Foo.prototype 实现继承 */
// 现在没有Bar.prototype.constructor,如果需要手动修复
Bar.prototype.myLabel = function() {
console.log(this.label);
}
var a = new Bar('nico', 'obj a');
/* 构造newBar的实例对象
=> Foo.call(this, name) === Foo.call(a, 'nico')
*
*/
a.sayName(); // 'nico'
a.myLabel(); // 'obj a'

调用Object.create会凭空创建一个新对象并把新对象内部的[[Prototype]]关联到你指定的对象。

在本例中 => ‘创建一个新的Bar.prototype对象关联到Foo.prototype’

注*     关于constructor

1
2
3
4
5
6
7
8
function Foo() {
// ...
}
console.log(Foo.prototype.constructor); // Foo()
var a = new Foo();
console.log(a.constructor); // Foo()
  1. 这里constructor并不是通过new自带的属性,而是a通过引用的Foo得到的
1
2
3
4
5
6
7
8
function Foo() {
// ...
}
Foo.prototype = { /* ... */ }; // 修改了prototype
var a = new Foo();
console.log(a.constructor); // Object

当我们修改了Foo的prototype之后,constructor没有被设置,通过new得到的实例也就找不到原型链上的Foo._proto_constructor那么他就会继续向上寻找 –> Object.prototype 在这里找到了constructor然后返回

_proto_ 和 prototype

_proto_ 是隐式原型,作用时构成原型链,同样用于实现基于原型的继承。指向创建这个对象的显式原型。

prototype 是显式原型,指向当前对象的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
/*
* 定义父类,
* 包含的控件行为: 宽, 高, 加入
*
*/
var Widget = {
/* 初始化 */
init: function(width, height) {
this.width = width;
this.height = height;
this.$elm = null; // 初始化子类元素
},
/* 添加行为 */
insert: function($where) {
if(this.$elm) {
this.$elm.css({
width: this.width + 'px',
height: this.height + 'px'
}).appendTo($where);
}
}
};
/* 定义子类 ,宽, 高, 颜色, 加入 */
// 关联父类
var Box = Object.create(Widget);
/* 初始化Box 宽, 高, 颜色, 并且定义元素*/
Box.setup = function(width, height, color) {
// 委托调用
this.init(width, height);
this.color = color;
this.$elm = $('<div>');
this.$elm.css({
backgroundColor: this.color
});
};
/* 添加Box行为 */
Box.build = function($where) {
// 委托父类
this.insert($where);
// 添加行为
this.$elm.click(this.onClick.bind(this));
};
Box.onClick = function() {
console.log('Hello '+this.color);
};
$(document).ready(function() {
$body = $(document.body);
var box1 = Object.create(Box);
box1.setup(150, 150, '#f00');
box1.build($body);
});
------本文结束感谢阅读------