我正在学习如何用JavaScript制作面向对象编程。是否有接口概念(如Java的接口)?
这样我就可以创建一个监听器。
我正在学习如何用JavaScript制作面向对象编程。是否有接口概念(如Java的接口)?
这样我就可以创建一个监听器。
当前回答
Js没有接口,但typescript有!
其他回答
JavaScript (ECMAScript edition 3)有一个保留字以备将来使用。我认为这正是为了这个目的而设计的,然而,在匆忙发布规范的过程中,他们没有时间定义如何使用它,所以,目前,浏览器除了让它呆在那里,偶尔会抱怨你试图用它来做什么之外,什么也不做。
创建自己的object. implementation (Interface)方法是可能的,而且非常简单,只要在给定的对象中没有实现特定的属性/函数集,该方法的逻辑就会中断。
我写了一篇关于面向对象的文章,其中使用了我自己的符号如下:
// Create a 'Dog' class that inherits from 'Animal'
// and implements the 'Mammal' interface
var Dog = Object.extend(Animal, {
constructor: function(name) {
Dog.superClass.call(this, name);
},
bark: function() {
alert('woof');
}
}).implement(Mammal);
有很多方法来处理这个特殊的问题,但这是我在自己的接口实现中使用的逻辑。我发现我更喜欢这种方法,而且它易于阅读和使用(如上所述)。这意味着在Function中添加一个“实现”方法。原型,有些人可能有一个问题,但我发现它工作得很漂亮。
Function.prototype.implement = function() {
// Loop through each interface passed in and then check
// that its members are implemented in the context object (this).
for(var i = 0; i < arguments.length; i++) {
// .. Check member's logic ..
}
// Remember to return the class being tested
return this;
}
Javascript没有接口。但它可以是鸭子类型的,一个例子可以在这里找到:
http://reinsbrain.blogspot.com/2008/10/interface-in-javascript.html
像这样的抽象接口
const MyInterface = {
serialize: () => {throw "must implement serialize for MyInterface types"},
print: () => console.log(this.serialize())
}
创建一个实例:
function MyType() {
this.serialize = () => "serialized "
}
MyType.prototype = MyInterface
并使用它
let x = new MyType()
x.print()
希望任何还在寻找答案的人都能从中找到帮助。
你可以尝试使用代理(这是自ECMAScript 2015以来的标准):https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Proxy
latLngLiteral = new Proxy({},{
set: function(obj, prop, val) {
//only these two properties can be set
if(['lng','lat'].indexOf(prop) == -1) {
throw new ReferenceError('Key must be "lat" or "lng"!');
}
//the dec format only accepts numbers
if(typeof val !== 'number') {
throw new TypeError('Value must be numeric');
}
//latitude is in range between 0 and 90
if(prop == 'lat' && !(0 < val && val < 90)) {
throw new RangeError('Position is out of range!');
}
//longitude is in range between 0 and 180
else if(prop == 'lng' && !(0 < val && val < 180)) {
throw new RangeError('Position is out of range!');
}
obj[prop] = val;
return true;
}
});
然后你就可以轻松地说:
myMap = {}
myMap.position = latLngLiteral;
如果你想通过instanceof (@Kamaffeather问)检查,你可以像这样把它包装在一个对象中:
class LatLngLiteral {
constructor(props)
{
this.proxy = new Proxy(this, {
set: function(obj, prop, val) {
//only these two properties can be set
if(['lng','lat'].indexOf(prop) == -1) {
throw new ReferenceError('Key must be "lat" or "lng"!');
}
//the dec format only accepts numbers
if(typeof val !== 'number') {
throw new TypeError('Value must be numeric');
}
//latitude is in range between 0 and 90
if(prop == 'lat' && !(0 < val && val < 90)) {
throw new RangeError('Position is out of range!');
}
//longitude is in range between 0 and 180
else if(prop == 'lng' && !(0 < val && val < 180)) {
throw new RangeError('Position is out of range!');
}
obj[prop] = val;
return true;
}
})
return this.proxy
}
}
这可以在不使用Proxy的情况下完成,而是使用类getter和setter:
class LatLngLiteral {
#latitude;
#longitude;
get lat()
{
return this.#latitude;
}
get lng()
{
return this.#longitude;
}
set lat(val)
{
//the dec format only accepts numbers
if(typeof val !== 'number') {
throw new TypeError('Value must be numeric');
}
//latitude is in range between 0 and 90
if(!(0 < val && val < 90)) {
throw new RangeError('Position is out of range!');
}
this.#latitude = val
}
set lng(val)
{
//the dec format only accepts numbers
if(typeof val !== 'number') {
throw new TypeError('Value must be numeric');
}
//longitude is in range between 0 and 180
if(!(0 < val && val < 180)) {
throw new RangeError('Position is out of range!');
}
this.#longitude = val
}
}
Js没有接口,但typescript有!