在其他语言中比如
C#
、
Java
,接口方法在定义的时候都是未实现的,而我这里模拟的
JS
接口则是可以在定义的时候实现的。
定义接口:
var
IC
lass
Manager = {
hasClass:function(className){},
addClass:function(className){}
}
;
定义菜单类:
var
Men
u
= function(options){
this._element = null;
this.setXY =
function(x,y){
if (x)
this._element.style.left = x + 'px';
if (y)
this._element.style.top = y + 'px';
}
};
定义菜单项类:
var
Men
uItem = function(){
this.setText =
function(){
};
}
其实菜单类和菜单项类都是基于
HTMLElement
的抽象,因此如果要让他们可以灵活的定义
HTMLElement
样式,那么都需要一组管理
className
的方法。因此
Menu
和
MenuItem
都需要实现
IClassManager
。辅助实现接口的方法:
var extend = function(dest,
source){
//
实现接口
dest = self || {};
for (property in source)
{
if
(!
dest[property]
)
//
如果
dest
也就是类没有同名的方法,则用接口默认实现方法。
dest[property] =
dest[property];
}
return dest;
}
extend(Menu.prototype,
I
Class
Manager);
extend(MenuItem.prototype,
I
Class
Manager);
这样
Menu
和
MenuItem
都具有了
Class
的管理能力。
通过
extend
,
Menu
和
MenuItem
可以实现任意的接口,并且同时实现多个接口。
在实现接口之前
Menu
和
MenuItem
还可以有一次继承的机会:
Menu.prototype = new BaseClass();
//
最简单的继承方式
然后再实现接口:extend(Menu.prototype,
I
Class
Manager);
这样就类似单根继承
+
多接口实现,很像
C#
或者
Java
吧
下面是完整的代码:
(function(){
var Event =
joyeach.util.Event;
var extend =
function(dest, source){
//
实现接口
dest = self || {};
for (property in source)
{
if
(!
dest[property]
)
dest[property] =
dest[property];
}
return dest;
}
//C
lass
Manager Interface
var
I
Class
Manager= {
hasClass:function(className){
var reg = new
RegExp('(?:^|\\s+)' + className + '(?:\\s+|$)')
;
return
reg.test(this._element['className']);
},
addClass:function(className){
if (this.hasClass(el,
className))
return;
this._element['className']
= [this._element['className'], className].join(' ');
}}
/**
* 菜单类
*/
joyeach.controls.Menu =
function(options){
this._element = null;
this.setXY =
function(x,y){
if (x)
this._element.style.left = x + 'px';
if (y)
this._element.style.top = y + 'px';
};
this.getXY = function(){
return
[parseInt(this._element.style.left),
parseInt(this._element.style.top)];
};
this.addItem =
function(item){
this._element.appendChild(item._element);
Event.fireEvent(this,
'onadditem', {sender:this, item:item});
};
this.getItemAt =
function(index){
return
this._element.childNodes[index]._control;
};
this.removeItemAt =
function(index){
var element =
this._element.childNodes[i];
this._element.removeChild(element);
Event.fireEvent(this,
'onremoveitem', {sender:this, item:element._control});
};
this.removeItem =
function(item){
item._element.parentNode.removeChild(item._element);
Event.fireEvent(this,
'onremoveitem', {sender:this, item:item});
};
this.show =
function(x,y){
if (x || y)
this.setXY(x,y);
this._element.style.display =
'block';
Event.fireEvent(this,
'onshow', {sender:this});
};
this.hide = function(){
this._element.style.display =
'none';
Event.fireEvent(this,
'onhide', {sender:this});
};
this.close = function(){
this._element.parentNode.removeChild(this._element);
Event.fireEvent(this,
'onclose', {sender:this});
};
this._init =
function(options){
this._element =
document.createElement('div');
options = options ||
{};
if (options.css)
this._element.className = options.css;
this.setXY(options.x,options.y);
//fire event onpopup
Event.fireEvent(this,
'onpopup', {sender:this});
document.body.appendChild(this._element);
};
//initialize menu
this._init(options);
};
/**
* 菜单项类.
*/
joyeach.controls.MenuItem
= function(){
this.setText =
function(){
};
this.getText =
function(){
};
this.setTitle =
function(){
};
this.getTitle =
function(){
};
this._init = function(){
};
this._init();
};
//菜单类和菜单相类分别实现ICSSManager接口
extend(joyeach.controls.Menu.prototype,
I
Class
Manager);
extend(joyeach.controls.MenuItem.prototype,
I
Class
Manager);
})();
其中
IClassManager
接口方法实现里面的
this._element
可以在抽象成方法
this.getElement
。
此方案源于
prototype.js
和
yahoo
ui library
。
相关推荐
然而,JavaScript没有内置的接口关键字,这意味着我们需要通过某种方式来模拟接口。 在JavaScript中实现接口的一种常见方法是使用类和原型。我们可以创建一个空的构造函数(接口类),并定义其原型上的方法作为接口...
4. 虽然JavaScript没有原生接口,但可以通过约定和模式来模拟接口行为。 5. 在团队合作中,需谨慎使用面向对象特性,避免过度设计。 6. 时刻关注性能和代码可读性,适度封装和继承,避免不必要的内存开销。 总之,...
在JavaScript中,可以通过闭包或者模块模式来实现。 2. **工厂模式**:用于创建对象,避免直接使用new关键字。它可以抽象出创建对象的过程,使代码更灵活。 3. **构造函数模式**:JavaScript中类的模拟,通过`new`...
这篇博文将深入探讨如何在JavaScript中模拟接口,以及如何利用这些技术来提高代码的可维护性和扩展性。 首先,理解JavaScript的核心特性是关键。JavaScript基于原型继承,这意味着对象可以从其他对象继承属性和方法...
在JavaScript中,多态性可以通过重写方法来实现。 #### JavaScript中的面向对象编程实践 - **构造函数与原型**:构造函数用于创建对象实例,而原型则定义了所有实例共享的属性和方法。例如: ```javascript ...
同时,JavaScript的面向对象特性,如原型继承和类模拟,也是设计模式的重要基础。 此外,书中还会涉及一些实用技巧,如错误处理、性能优化和测试驱动开发(TDD),这些都是高质量JavaScript开发不可或缺的部分。...
2. **模拟接口**:介绍如何在JavaScript中通过构造函数、原型链或者ES6的类来模拟接口,确保对象符合特定的结构和行为。 3. **类型检查库**:可能会提及TypeScript,这是一种JavaScript的超集,它引入了类型系统,...
2. 原型继承模式:利用JavaScript的原型链实现类的继承。 3. revealing module pattern:暴露模块内部变量和函数的一种方式,提高代码组织性和可维护性。 4. 工厂函数与类模式:在没有类的JavaScript中,模拟面向...
- **原型链继承**:JavaScript使用原型链实现继承机制,每个对象都有一个指向其原型对象的链接,当查找一个对象的属性时,如果该对象自身不存在该属性,则会沿着原型链向上查找。 - **构造函数**:虽然JavaScript不...
在JavaScript中,虽然没有传统的类定义,但可以通过构造函数来模拟类的行为。构造函数是一个用来初始化新创建的对象的特殊函数,通过`new`关键字调用。例如,我们可以创建一个表示人的构造函数: ```javascript ...
在JavaScript中,多态主要体现在不同的对象可以共享同一接口,但具体实现方式可以不同。 #### 知识点五:封装与模块化 - **封装**:封装是隐藏对象的具体实现细节,并提供一个清晰的公共接口供外部访问。...
在ES6之后,引入了class和extends关键字,使得继承看起来更像是传统面向对象语言的实现方式,但实际上在JavaScript中仍然是基于原型的继承。 以上知识点详细介绍了JavaScript面向对象编程中的基本特性、对象的定义...
在JavaScript中,由于函数是第一类公民,多态性主要体现在函数的动态绑定和重写上。 **JavaScript中的OOP实践** JavaScript提供了多种实现OOP的方式: 1. **构造函数与原型**:构造函数用于初始化新创建的对象,...
JavaScript是一种广泛应用于网页和网络应用的编程语言,它在客户端运行,为用户提供动态交互体验。在正规本科学校的教学中,JavaScript通常被视为Web开发的基础,是每个学生必须掌握的重要技能。"javascript课件及...
- **原始的封装模式**:通过JSON数据来模拟数据类型,但这种方式只适用于单一实例的情况,难以应对多个实例的需求。 - **函数封装模式**:通过函数返回JSON对象来创建对象实例,提高了代码的复用性,但仍缺乏类与...
在JavaScript中,我们可以通过闭包或者`private`、`public`模拟实现封装: ```javascript function Car(make, model) { var _make = make; // private variable this.model = model; // public property this....
在JavaScript中,可以通过立即执行函数表达式(IIFE)或模块模式来实现封装。 7. **类(ES6)**: ES6引入了`class`语法糖,使得JavaScript的面向对象编程更接近传统的类式语言。虽然在底层仍然基于原型,但`class...
JavaScript还支持面向对象编程,通过构造函数和原型链实现类的模拟。ES6引入了类和模块等新特性,使代码组织更加清晰。类是基于原型的继承的语法糖,模块系统则解决了命名冲突和代码复用问题。 在浏览器环境中,...