[英]Call base method in Javascript using Douglas Crockford's functional inheritance
[英]Using super methods in Javascript based on Crockford's functional inheritance
我一直在阅读Crockford的“ The Good Parts”中有关函数继承的章节。 在哺乳动物的示例中,对于他为什么使用superior
方法修改get_name
函数,他有些困惑。 这是有问题的示例:
Function.prototype.method = function (name, func) {
this.prototype[name] = func;
return this;
};
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'
});
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 += 1) {
if (s) {
s += '-';
}
s += 'r';
}
return s;
};
that.get_name = function () {
return that.says() + ' ' + spec.name + ' ' + that.says();
};
return that;
};
Object.method('superior', function (name) {
var that = this,
method = that[name];
return function () {
return method.apply(that, arguments);
};
});
var coolcat = function (spec) {
var that = cat(spec);
var 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'
我对此感到困惑,因为我可以通过删除superior
方法并只需更改coolcat
来复制相同的coolcat
,如下所示:
var coolcat = function(spec) {
var that = cat(spec);
var super_get_name = that.get_name();
that.get_name = function(n) {
return 'like ' + super_get_name + ' baby';
};
return that;
};
因此,我不明白为什么Crockford选择使用superior
方法。 有人可以解释吗?
这里的想法是这样的:
var super_get_name = that.superior('get_name');
使super_get_name
成为一个函数-每次调用时-都会调用that
方法的原始 get_name
方法。 这允许新的 get_name
调用旧的 (超类) get_name
。
现在,如果原始的get_name
方法除了返回一个永远不变的值之外,将永远不会有任何其他效果,那么,是的,这毫无意义; 您可以只保存该单值永不更改,然后在新的get_name
使用它。 但是,如果原始的get_name
实际上可以执行操作(例如,运行AJAX请求或更改HTML元素的样式),或者其返回值可以更改(例如,是否有一些对应的set_name
方法),那么您的代码做什么(保存原始返回值并使用它)和Crockford的代码做什么(保存原始方法并调用它)之间将存在重要的区别。
Crockford在本书的这一章中引起了困惑,因为Crockford所描述的是“他的”在JavaScript中实现继承的首选模式,这取决于他用Function.prototype.method
(第1.3章)扩展的Function
对象,向Function对象添加方法。
coolcat
示例中解决的问题是需要访问父类型的方法。 在像Java这样的“经典” OO语言中,这很自然,因为类本身就存在。 在JavaScript继承是典型的情况下,您将创建一个mammal
类型的对象,然后修改该对象以创建类型cat
或coolcat
。
根据您的设计,您可以添加属性和功能或覆盖“继承的”功能。 当您覆盖“继承的”函数时,就会出现问题,在JavaScript中,您基本上用新函数替换了旧函数,从而失去了旧函数。
克罗克福德现在需要做两件事:
get_name
方法; 和 在此代码中:
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;
};
他通过调用高级方法来获得一个函数,该函数获得了猫的get_name
函数。 然后他通过将其保存到coolcat函数(/ object)中的super_get_name
变量中来进行操作,从而允许在猫被其猫的get_name
函数覆盖(更正确地覆盖)之前访问该猫的get_name
函数。
我认为之所以会引起混淆,是因为:
superior
方法的名称很奇怪:“ superior”方法只是按名称查找函数 ,可以更好地命名,例如,将其命名为getFunctionByName
(您可以通过将字符串get_name
替换为purr
来尝试,coolcat的get_name现在会调用purr,只需记住将其称为super_get_name(10)
否则将返回一个空字符串)。 我认为有一种更简单的方法可以实现此目的,我认为因为它是完全本地化的,因此更易于理解等,如下面的代码所示:
var coolcat = function(spec) {
var that = cat(spec);
that.parent_get_name = that.get_name;
that.get_name = function() {
return 'like ' + this.parent_get_name() + ' baby';
};
return that;
};
还有其他一些奇怪的地方,例如coolcat get_name
函数的定义中的参数n
,我只能假定它来自复制purr函数,这可能表明是幽灵作家!
最后,我建议在读本书之前,应该先听一下关于“ JavaScript的好部分”的演讲。 演讲绝对精彩,比这本书好得多。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.