Javascript Good Part读书笔记-JavaScript继承
文章目录
继承(Inheritance)
伪类(Pseudoclassical)
当一个函数对象被创建时,这个函数的构造器会产生一个函数对象运行类似下面的代码:
1
|
this.prototype = {constructor: this}; |
例子,定义一个构造器,并在prototype上添加方法
1 2 3 4 5 6 7 8 9 |
var Mammal = function (name) {
this.name = name;
};
Mammal.prototype.get_name = function () {
return this.name;
};
Mammal.prototype.says = function () {
return this.saying || '';
}; |
创建实例
1 2 |
var myMammal = new Mammal('Herb the Mammal');
var name = myMammal.get_name(); // 'Herb the Mammal' |
创建另一个伪类继承Mammal,通过定义该伪类的constructor函数并且替换它的prototype属性为Mammal的实例。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
var Cat = function (name) {
this.name = name;
this.saying = 'meow';
};
// Replace Cat.prototype with a new instance of Mammal
Cat.prototype = new Mammal();
// Augment the new prototype with purr and get_name methods.
Cat.prototype.purr = function (n) {
var i, s = '';
for (i = 0; i < n; i += 1) {
if (s) {
s += '-';
}
s += 'r';
}
return s;
};
Cat.prototype.get_name = function () {
return this.says() + ' ' + this.name + ' ' + this.says();
}; |
1 2 3 4 |
var myCat = new Cat('Henrietta');
var says = myCat.says(); // 'meow'
var purr = myCat.purr(5); // 'r-r-r-r-r'
var name = myCat.get_name(); // 'meow Henrietta meow' |
使用前面定义的method方法定义一个inherits方法:
1 2 3 4 |
Function.method('inherits', function (Parent) {
this.prototype = new Parent();
return this;
}); |
因为inherits和method方法都返回this,我们可以通过及联调用的方式实现Cat
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
var Cat = function (name) {
this.name = name;
this.saying = 'meow';
}.inherits(Mammal)
.method('purr', function (n) {
var i, s = '';
for (i = 0; i < n; i += 1) {
if (s) {
s += '-';
}
s += 'r';
}
return s;
})
.method('get_name', function () {
return this.says() + ' ' + this.name + ' ' + this.says();
}); |
伪类继承存在的问题
- 没有私有属性/方法(JavaScript所有属性都是公有的)。
- 不能访问父类的方法。
- 如果调用的时候忘记了
new(没有以构造函数的方式调用),则this不能被绑定到新创建的对象实例(this将会被绑定到全局对象)。
对象说明符(Object Specifiers)
当一个构造器有非常多的参数时,参数的顺序会变的非常难记,这时候可以通过对象描述符代替。
例如:
1
|
var myObject = maker(f, l, m, c, s); |
可以写为:
1 2 3 4 5 6 7 |
var myObject = maker({
first: f,
last: l,
middle: m,
state: s,
city: c
}); |
原型(Prototypal)
基于原型的继承方式比经典的继承在概念上更为简单,并且更容易理解。
示例
1 2 3 4 5 6 7 8 9 |
var myMammal = {
name : 'Herb the Mammal',
get_name : function () {
return this.name;
},
says : function () {
return this.saying || '';
}
}; |
创建对象实例
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
var myCat = Object.create(myMammal);
myCat.name = 'Henrietta';
myCat.saying = 'meow';
myCat.purr = function (n) {
var i, s = '';
for (i = 0; i < n; i += 1) {
if (s) {
s += '-';
}
s += 'r';
}
return s;
};
myCat.get_name = function () {
return this.says() + ' ' + this.name + ' ' + this.says();
}; |
函数化(Functional)
通过模块化的方式实现封装,可通过如下4步实现
创建一个对象,创建对象的方式:
- 字面符
- 通过
new调用构造器 - 从一个已经存在的对象使用
Object.create方法新建一个实例 - 调用一个函数返回一个对象
定义私有的实例变量和方法(可选)
为创建的对象增加方法(这鞋方法有权限去访问底2步中定义的变量/方法)
返回新建的对象。
伪代码如下:
1 2 3 4 5 6 7 8 |
var constructor = function (spec, my) {
var that, other private instance variables;
my = my || {};
Add shared variables and functions to my
that = a new object;
Add privileged methods to that
return that;
}; |
示例
1 2 3 4 5 6 7 8 9 10 11 |
var mammal = function (spec) {
var that = {};
that.get_name = function () {
return spec.name;
};
that.says = function () {
return spec.saying || '';
};
return that;
};
var myMammal = mammal({name: 'Herb'}); |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
var cat = function (spec) {
spec.saying = spec.saying || 'meow';
var that = mammal(spec);
that.purr = function (n)
var i, s = '';
for (i = 0; i < n; i
if (s) {
s += '-';
}
s += 'r';
}
return s;
};
that.get_name = function(){
return that.says() + ' ' + spec.name + ' ' + that.says();
};
return that;
};
var myCat = cat({name: 'Henrietta'}); |
访问父类方法
1 2 3 4 5 6 7 |
Object.method('superior', function (name) {
var that = this,
method = that[name];
return function () {
return method.apply(that, arguments);
};
}); |
示例
1 2 3 4 5 6 7 8 9 10 |
var coolcat = function (spec) {
var that = cat(spec),
super_get_name = that.superior('get_name');
that.get_name = function (n) {
return 'like ' + super_get_name() + ' baby'; };
return that;
};
var myCoolCat = coolcat({name: 'Bix'});
var name = myCoolCat.get_name();
// 'like meow Bix meow baby' |
文章作者 binbin wen
上次更新 2019-11-14