我按照Crockford的例子在Javascript(在Chrome中)中使用经典继承。我喜欢寄生接口,但我正在寻找一种更简洁的方法来封装继承。
我想要满足一些额外的要求:
这是我的父类Parasite
,其extend
方法尝试封装继承并利用Object.defineProperty
:
function Parasite(host) {
var self = {};
self.host = host;
self.swollen = false;
self.init = function() {
console.debug('Parasite.init');
return self;
};
self.suck = function() {
console.log("I'm a parasite who sucks on " + self.host);
self.swollen = true;
return self;
};
self.extend = function(child) {
for(var prop in self) {
if (prop == 'extend') { // skip extend
console.debug('skip extend');
continue;
}
var is_extended = child.hasOwnProperty(prop);
var is_accessor = typeof self[prop] != "function";
// inherit prop
if (! is_extended) {
child[prop] = self[prop];
console.debug('prop', prop, 'inherited by child');
}
// default: override
else {
console.debug('prop', prop, 'overridden by child');
}
// For accessors, parent should reference child. This tries to
// synchronize them on the child's accesor.
if (is_accessor) {
var accessor = prop.toString();
console.warn('define accessor for', accessor, ':', child[accessor]);
Object.defineProperty(self, accessor, {
get: function() {
var val = child[accessor];
console.debug('getting', accessor, val, 'from', child, 'for', self);
return val;
},
set: function(val) {
console.debug('setting', accessor, val, 'from', child, 'for', self);
child[accessor] = val;
},
enumerable: true,
configurable: true
});
};
}
child.parent = self;
return child;
};
self = self.init();
return self;
}
这是我的孩子班,Tick
:
function Tick(host) {
var self = {};
self.suck = function() {
self.parent.suck.call();
self.engorge();
};
self.engorge = function() {
console.log("And now I'm engorged with blood.");
};
self.init = function() {
var parent = new Parasite(host);
self = parent.extend(self);
return self;
};
self = self.init();
return self;
}
你可以在这里找到我最新的小提琴(警告:在Firefox中无限递送,但在Chrome中无法提升):
控制台输出说明了访问者发生问题的位置。
答案 0 :(得分:1)
这不是我的问题的答案本身,但这是一个更简单的实现,似乎符合我的要求。它遵循this Stack Overflow answer中提出的模式。
function Parasite(host) {
var self = {};
self.host = host;
self.hungry = true;
self.init = function() {
console.debug('Parasite.init');
return self;
};
self.suck = function() {
console.log("I'm a parasite who sucks on " + self.host);
self.hungry = false;
return self;
};
self.init();
return self;
}
function Tick(host) {
var self = new Parasite(host);
self.engorged = false;
var base_suck = self.suck;
self.suck = function() {
base_suck();
self.engorge();
};
self.engorge = function() {
console.log("And now I'm engorged with blood.");
self.engorged = true;
};
self.init = function() {};
self.init();
return self;
}
可以在此处找到小提琴测试:http://jsfiddle.net/AvdK2/3/