在Javascript中使用寄生继承,是否可以实现内省实例方法
Using parasitic inheritance in Javascript, is it possible to implement introspective instance methods?
我正在尝试为以Crockford为模型的Javascript类开发一个简单的寄生接口,我想实现一些基本的内省方法。给定下面的类,如何编写正确标识对象类的class_name
和is_a
方法?
function Parent(name) {
var self = {};
self.name = name;
self.init = function() {
console.debug('init', self);
return self;
};
self.ama = function() {
return "AMA Parent named " + self.name;
};
// Introspective methods
self.class_name = function() {
// returns class name as a string
};
self.is_a = function(obj_class) {
// returns boolean indicating whether object is instance of obj_class
};
self = self.init();
return self;
}
function Child(name) {
var self = new Parent(name);
var base_ama = self.ama;
self.ama = function() {
var ama = base_ama();
return ama + ". NOT!";
};
self.init();
return self;
}
以下是预计通过的测试:
var alice = new Parent('Alice');
assert_equal(alice.name, 'Alice');
assert_equal(alice.class_name(), 'Parent');
assert(alice.is_a(Parent));
assert_not(alice.is_a(Child));
assert_equal(alice.ama(), 'AMA Parent named Alice');
var bob = new Child('Bob');
assert_equal(bob.class_name(), 'Child');
assert_not(bob.is_a(Parent));
assert(bob.is_a(Child));
assert_equal(bob.ama(), 'AMA Parent named Bob. NOT!');
您可以在此处找到设置测试的小提琴:
http://jsfiddle.net/LTfVa/3/
原型继承是高性能的,关于内存的经济性,相对简单,并且对Javascript的功能是习惯性的。在我看来,寄生遗传不是这些东西:
// extend:
// receiverCtor - A constructor function that we want to extend with another constructor's behavior
// supplierCtor - The supplier of the other constructor's behavior
// receiverProperties - Any instance methods/properties you want to push onto the receiver's prototype
// receiverStatics - Any methods/properties you want to attach to the constructor function itself
//
function extend(receiverCtor, supplierCtor, receiverProperties, receiverStatics) {
receiverProperties = receiverProperties || {};
receiverStatics = receiverStatics || {};
var supplierProto = supplierCtor.prototype,
receiverProto = Object.create(supplierProto),
prop;
receiverCtor.prototype = receiverProto;
receiverProto.constructor = receiverCtor;
receiverCtor.parent = supplierProto;
if(supplierCtor !== Object && supplierProto.constructo === Object.prototype.constructor) {
supplierProto.constructor = supplierCtor;
}
for(prop in receiverProperties) {
if(receiverProperties.hasOwnProperty(prop)) {
receiverProto[prop] = receiverProperties[prop];
}
}
for(prop in receiverStatics) {
if(receiverStatics.hasOwnProperty(prop)) {
receiverCtor[prop] = receiverStatics[prop];
}
}
}
function Parent(name) {
this.name = name;
}
function Child(name) {
Child.parent.constructor.apply(this, arguments);
}
extend(Child, Parent);
var alice = new Parent('alice');
var bob = new Child('bob');
console.log(alice instanceof Parent);
console.log(!(alice instanceof Child));
console.log(alice.name == 'alice');
console.log(bob instanceof Parent); // inherits from parent
console.log(bob.constructor !== Parent); // but it isn't a parent
console.log(bob instanceof Child);
console.log(bob.constructor === Child);
console.log(bob.name === 'bob');
这是一个要验证的 jsbin。
编辑:extend
函数是以下非常简单的关系之上的语法糖的集合:
function Parent(name) {
this.name = name;
}
function Child(name) {
Parent.apply(this, arguments);
}
Child.prototype = Object.create(Parent.prototype);
Child.prototype.constructor = Child;
以上十行将通过第一个示例的所有测试。
相关文章:
- 是否有WebKit的实现可以方便地访问本地文件系统
- 确定当前的Javascript实现是否为Rhino
- 是否可以为聚合物组件实现Webpack HMR
- emberfire 1.3.2是否实现findQuery方法
- Angular框架是否为立即返回的promise实现常量
- 是否可以将扫描作为转换器来实现
- 使用
时,是否有任何方法可以实现页面过渡 - 是否可以在 JavaScript 中实现没有舍入问题的任意精度算术
- 是否可以在javascript中实现sleep()
- 测试对象是否是 Google 闭包类框架中接口的实现
- HTMLUnit是否包括一个功能性的[HTML5]画布2D实现,能够将图像数据渲染回Java代码
- 浏览器实现同源策略的方式是否存在实质性差异
- 是否可以在IE中实现WebKit滚动条效果
- 承诺.resolve 是否等待传递的承诺实现
- URI模板:javascript中是否有rfc-6570实现
- javascript是否实现词法作用域
- javascript检查对象是否实现HTMLAnchorElement接口
- 在Javascript中的NodeJS/上是否实现了任何规则引擎
- 如何检查JS对象是否实现了一些DOM IDL接口
- Javascript是否实现了类似SQL的数据访问