javascript - 一个关于实现接口及其继承的javascript构造函数问题
问题描述
使用 javascript 实现接口及其继承时遇到问题。
内容和思路来自《Learning JavaScript Design Pattern》一书。我尝试使用它的接口代码,并希望我使用的方式可以使它像 C# 一样。我使用的代码如下:
var Interface = function(name, methods) {
if (arguments.length != 2) {
throw new Error("Interface constructor called with " + arguments.length +
"arguments, but expected exactly 2.");
}
this.name = name;
this.methods = [];
for (var i = 0, len = methods.length; i < len; i++) {
if (typeof methods[i] !== 'string') {
throw new Error("Interface constructor expects method names to be " +
"passed in as a string.");
}
this.methods.push(methods[i]);
}
};
function extend(subClass, superClass) {
var F = function() {};
F.prototype = superClass.prototype;
subClass.prototype = new F();
console.log(subClass.name);
console.info(subClass);
subClass.prototype.constructor = subClass;
subClass.superclass = superClass.prototype;
if (superClass.prototype.constructor == Object.prototype.constructor) {
superClass.prototype.constructor = superClass;
}
}
var Composite = new Interface('Composite', ['add', 'remove', 'getChild']);
console.log(Composite.name);
console.info(Composite);
console.log(Composite.__proto__.constructor.name);
var testinterface = function(name ,methods) {
Composite.call(this, name, methods);
};
extend(testinterface, Composite);
但是在执行代码时,错误消息显示:无法读取未定义的属性“构造函数”。
当我声明函数testinterface时确实有问题,但我不知道为什么,因为在extend的函数体中,console.log输出说明testinterface仍然是一个函数声明,没有任何原型,甚至是构造函数。
有什么办法可以纠正这个问题,为什么代码不起作用。任何指示都非常感谢,非常感谢。
解决方案
I see a post about polymorphism, https://medium.com/yld-blog/program-like-proteus-a-beginners-guide-to-polymorphism-in-javascript-867bea7c8be2 . I modify some codes from this web page, the codes can run, and its code snippet is as following:
function identical(a, b) {
return a === b;
}
class Protocol {
// accept a list of method-names
constructor(...methods) {
this.implementations = {};
// and create a method for each
methods.forEach(method => {
// that will dispatch to an implementation stored on the type of the first argument
this[method] = (type, ...args) => {
// with the convention that an object's type is given by its constructor
return this.implementations[type.constructor][method](type, ...args);
}
});
}
// register implementations for a type
extendTo(typeConstructor, implementation) {
const typed = this.implementations[typeConstructor] = {};
Object.keys(implementation)
.forEach(method => {
typed[method] = implementation[method];
});
}
}
const Ramda = new Protocol('equals', 'map', 'add'); /* and the rest! */
Ramda.extendTo(String, {
equals: (a, b) => a === b,
map: (a, f) => a.split('').map(f),
add: (a, b) => a + b
})
Ramda.extendTo(Date, {
equals: (a, b) => identical(a.valueOf(), b.valueOf()),
add: (a, b) => new Date(Number(a) + Number(b))
// map not implemented
})
console.log(Ramda.equals('hello', 'world')); // false
console.log(Ramda.equals(new Date(1), new Date(1))); // true
I think, if I can combine these concepts, the javescript interface may be implemented.
推荐阅读
- r - 匹配一个序列。获取遵循模式的元素的索引
- spring - Spring Batch 3 分类器没有被调用
- python - 如何从 gpu 内存地址创建 PyCUDA GPUArray?
- if-statement - 具有计算字段的 Sharepoint 2016 交通灯
- django - Django - 将上下文注入 base.html
- c# - 如何在gridview的Edittemplate中从数据库中填充选定的值
- qt - Qt 应用程序启动时 QIcon::addFile 执行太慢
- spring - Log4jdbc 级别配置不起作用
- ios - iOS Google Maps 搜索半径内的标记列表
- c# - Debian 上的 Exchange Web Services 401 错误,但不是 Windows