01.Javascript中的接口----Interface

AI权益加码!Claude Code、Cursor等20+工具免费用! 购周边限时加赠Coding Plan Lite,畅享主流AI工具!学习进阶更高效! 阅读详情

 

01.Javascript中的接口----Interface

本文主要讲述如何用原生的Javascript代码来模拟并实现接口

前言

众所周知,在Java、C#等语言中,接口由专门的关键字interface来定义,而接口的实现则有implements关键字来完成,接口有什么特点呢?简单地说有(不完全归纳):

  1. 不可被实例化
  2. 所有方法都是抽象方法
  3. 所有属性都是public static final的

但是在Javascript语言中,没有现成的关键字可以直接用来定义一个接口,也没有现成的关键字可以直接用来实现所谓的extends和implements。既然没有现成的,下面将阐述如何用原生的Javascript代码来模拟并实现接口。

Javascript中的接口

接口的定义
    /**
     * Interface构造器
     * @param {String} name 接口名
     * @param {Array} methods 接口中的抽象方法     
     * @exception {Error} 参数不合格时抛出异常
     * @example
     *      var IActionListener = new Interface("IActionListener",["method1","method2"]);
     */
    var Interface = function(name, methods) {
        if(arguments.length != 2) {
            throw new Error("Interface有且只有两个参数,而当前参数个数为:" + arguments.length );
        }
        this.name = name;           
        this.methods = [];          
        for(var i = 0, len = methods.length; i < len; i++) {                
            if(typeof methods[i] !== 'string') {                    
                throw new Error("Interface中的方法名必须合法");             
            }
           this.methods.push(methods[i]);          
        }       
    };

这个Interface类是用来模仿Java中的interface关键字的,但不同的是,Java中通过interface IActionListener{}的形式来定义一个接口,而这里则是通过var IActionListener = new Interface("IActionListener",["method1"])的形式来定义。

这个接口类接受两个参数,第一个表示需要定义的接口名称,第二个参数表示该接口中即将声明的抽象方法。该类在产生新接口的时候,会检查参数的合法性,只要通过检查,接口便产生了,同时具有两个属性:接口名和方法列表。

接口的实现
    /**
     * 接口实现的检查,保证object是InterfaceN的实例
     * @param {Object} oInterface 待检查的接口实例
     * @param {Class} InterfaceN 被实现的Interface
     * @exception {Error} 参数不合格时抛出异常
     * @example 
     *      Interface.ensureImplements(oActionListener,IActionListener);
     */
    Interface.ensureImplements = function(oInterface,Interface1,Interface2,InterfaceN) {
        if(arguments.length < 2) {
            throw new Error("Interface.ensureImplements方法至少需要两个参数,而当前参数个数为:" + arguments.length);
        }
        for(var i = 1, len = arguments.length; i < len; i++) {
            var interface = arguments[i];
            if(interface.constructor !== Interface) {
                throw new Error(interface + "不是Interface的实例,不是接口");
            }
            for(var j = 0, methodsLen = interface.methods.length; j < methodsLen; j++) {
                var method = interface.methods[j];
                if(!oInterface[method] || typeof oInterface[method] !== 'function') {
                    throw new Error("所给参数没有实现" + interface.name + "接口," + method + "未找到");
                }
            }
        }
    };

这个静态方法是用来模仿Java中的implements关键字的,但不同的是,Java中通过class ActionListener implements IActionListener{}来实现的,而这里则是通过 interface.ensureImplements(oActionListener,IActionListener)的形式来保证的。

这个静态方法接受两个参数,第一个表示接口实现类的实例对象,第二个参数表示接口实现类(当然了,这里其实是一个对象)。方法的内部会校验实例对象 是否都实现了接口中的所有抽象方法,如果在该实例中存在没有被实现的抽象方法(方法未找到),则表明该实例对象不是接口实现类的实例对象。

接口实例的创建与使用
    //创建接口
    var IActionListener = new Interface("IActionListener",["method1","method2"]);        
    //接口实例的创建
    var oActionListener = {
        method1 : function(){
            alert("这是方法1");
        },
        method2 : function(){
            alert("这是方法2");
        }
    };
    //implements确认
    Interface.ensureImplements(oActionListener,IActionListener);
    //调用实例中的方法
    oActionListener.method1();

这是一个简单的接口定义并实现的过程。

在Javascript中,必然存在着很多种接口的模拟方式,这里只是其中的一种实现思路。

模拟之不当,还请见谅。

非常希望您能提出宝贵的意见。

从ensureImplements方法到implements方法的升级(2010-09-22更新)

前面定义的ensureImplements(oInterface,Interface1,Interface2,InterfaceN)是通过 实例来保证的,但是按照常理来说,一个接口被实现以后,便可以进行实例化,但是这里不是真正意义上的实现,而是一种检查、一种保证。为了让接口实现后仍然 能通过new关键字实例化对象,下面需要将原来的方法进行升级,于是我定义了下面的方 法:implements(ImplementsClass,Interface1,Interface2,InterfaceN),代码如下:

/**
 * 接口的实现
 * @param {function} ImplementsClass 待实现的类
 * @param {object} InterfaceN 被实现的Interface,Interface的实例
 * @exception {Error} 参数不合格时抛出异常
 * @example 
 *      implements(ActionListener,IActionListener);
 */
 var implements = function(ImplementsClass,Interface1,Interface2,InterfaceN){
    if(arguments.length < 2) {
        throw new Error("Interface.ensureImplements方法至少需要两个参数,而当前参数个数为:" + arguments.length);
    }
    //保证ImplementsClass的类型为function
    if(typeof arguments[0] !== "function"){
        throw new Error("实现类的类型必须为function");
    }
    for(var i = 1, len = arguments.length; i < len; i++) {
        var interface = arguments[i];
        if(interface.constructor !== Interface) {
            throw new Error(interface + "不是Interface的实例,不是接口");
        }
        //这里循环进行接口抽象方法的实现
        for(var j = 0, methodsLen = interface.methods.length; j < methodsLen; j++) {
            var method = interface.methods[j];
            if(!arguments[0].prototype[method]){
                arguments[0].prototype[method] = function(){};
            }
        }
    }
 }

经过这样的升级,我们的代码就可以写成这样了:

//创建接口
var IActionListener = new Interface("IActionListener",["method1","method2"]); 
//创建实现类
var ActionListener = function(){};
//实现
implements(ActionListener,IActionListener);
//这个时候,ActionListener.prototype已经是如下这个样子了:
/*
    ActionListener.prototype = {
        method1 : function(){},
        method2 : function(){}
    };
*/
//接下来可以真正的填充被空实现的方法的逻辑了
ActionListener.prototype = {
    method1 : function(){
        alert("这是方法1");
    },
    method2 : function(){
        alert("这是方法2");
    }
};
//调用实例中的方法
oActionListener.method1();

OK,一切正常。到此为止,在后续的文章中提到的implements方法,就是这个方法了,请务必留意,谢谢。

 

TypeScript & 高级语法 & 详细解释 in、keyof、extends、索引签名、Record、typeof 的含义(不定时更新) 很早就听过 TypeScript,当时自己试了下觉得挺简单的,就是给数据声明一个类型提高可读和维护性,不过当时 TS 还不盛行,项目也没机会用到就一直落着,随着 TS 不断普及,许多项目都开始引入了 TS,这不最近在 github 看到一些 TS 代码后,心里开始吐槽: 这好好的非要给 JS 装饰的这么花里胡哨的?我都认不出来这是什么语言了,你确定这是提升 JS 语言可读性而不是添乱?有同学跟我一样的请举个手!后来静下心来想了想,既来之则安之,与其吐槽,不如静下心来好好重温下 TS ,在这期间也提取了一些有 阅读详情

相关推荐

JavaScript 设计模式 —— 接口

接口提供了一种用以说明一个对象应该具有哪些方法的手段。尽管它可以表明(或至少是暗示)这些方法的语义,但它并不规定这些方法应该如何实现。例如,如果一个接口包含有一个名为setName的方法,那么你有理由认为这个方法的实现应该具有一个字符串参数,并且会把这个参数赋给一个name变量。有了这个工具,你就能按对象提供的特性对它们进行分组。

cccloveforever的博客 3145

JavaScript中的接口——使用Interface js

总结一下,虽然JavaScript中没有内置的接口机制,但我们可以借助第三方库如Interface.js来模拟接口的行为。在JavaScript中,虽然没有内置的接口机制,但我们可以使用一些技巧和模式来模拟接口的行为。在本篇文章中,我们将介绍一种名为Interface.js的库,它提供了一种简单而灵活的方式来定义和实现接口Interface.js是一个轻量级的JavaScript库,它基于约定而非语言特性,允许我们在代码中定义和使用接口接口的定义和实现之后,我们可以在其他地方使用这个接口

ByteZenith的博客 1585

TypeScript interface不是语法糖,而是类型系统地基

interface是TypeScript中用于描述数据‘形状’(shape)的核心类型构造,它不生成运行时代码,却在编译期构建类型契约。其声明合并、开放扩展、继承语义和对类/函数/泛型的原生支持,使其成为API响应建模、Vue组件Props约束、Pinia状态定义及自定义指令类型安全的关键基础设施。相比type,interface更适配工程协作与长期演进——尤其在vue 3 + typescript项目和typescript面试题高频场景中,精准使用interface能显著降低undefined错误、提升I

dengkuituo0680的博客 304

js接口(Interface)定义和示例

定义接口Interface)的实现。 然后定义一个接口ResultSet有两个函数['getDate','getResults'],并且这个接口名字是Interface的第一个参数。 最后示例是实现一个对象resultObject,遵循接口ResultSet,这个对象resultObject必须实现接口定义的两个函数['getDate','getResults'],且通过resultFo...

ch_majia的博客 2万+

JavaScript接口Interfaces)

在现代软件开发中,接口Interfaces)是一个至关重要的概念。它不仅在程序设计中具有极高的灵活性和可维护性,而且可以帮助我们有效地组织代码结构。在JavaScript语言中,尽管其设计上并不原生支持接口这一概念,但我们依然可以通过一些设计模式和编程技巧实现类似于接口的功能。本文将深入探讨JavaScript中的接口概念,具体实现方式,以及如何利用这些知识提高代码的质量和可维护性。

2401_90032085的博客 3026

01.Javascript中的接口----Interface [转载]

转载地址:http://blog.csdn.net/ymmc001/archive/2010/11/05/5990021.aspx 本文主要讲述如何用原生的Javascript代码来模拟并实现接口 前言 众所周知,在Java、C#等语言中,接口由专门的关键字interface来定义,而接口的实现则有implements关键字来完成,接口有什么特点呢?简单地说有(不完全归纳): ...

weixin_30425949的博客 129

Interface 接口

一个类实现interface接口时,要求必须实现该接口中所有的抽象方法。4.接口也是一种“高层”的数据类型,可以用于定义“引用”的类型,也适用于"向上转型"和"向下转型"。* 语法2:接口中,允许定义“抽象方法”,public 和 abstract关键字可以省略。7.实现 Comparable接口的类,该类的对象之间可以进行“比较”,用于“排序”。* 语法4:实现类通过implements关键字实现接口,可以同时实现多个接口。5.接口的所有方法都是抽象方法,接口不能定义实例字段(成员变量)。

m0_68041576的博客 582

interface 原来是这样用的呀 ?typescript入门指南05(持续更新中)

TypeScript中的接口Interface)用于定义对象的结构和类型。接口类似于制定一份合同或规范,描述了对象应该具有的属性、方法等特征,但并不提供具体的实现。type 和 interface的都有定义类型的功能,但是声明类型和继承方面是有所区分的,使用时,需根据业务场景进行区分声明类型type可以表示非对象类型(字符串、numebr、、、)interface 只能表示 对象类型(包括数组、函数等)继承type 不支持继承。

程序员一诺 1188

CMake属性继承机制:PRIVATE、PUBLIC、INTERFACE详解

CMake是现代C++项目构建的重要工具,其属性继承机制中的PRIVATE、PUBLIC、INTERFACE关键字是构建复杂依赖关系的关键。本文将深入解析这三个重要的属性作用域,帮助开发者更好地管理项目依赖。 ## 什么是属性继承机制? 在CMake中,当使用`target_link_libraries()`或`target_include_directories()`等函数时,PRIVATE

gitblog_00041的博客 965

[原]Java思想之容器implements与接口interface

http://homeway.me/ 0x01.About查了一些国内资料,都说java中extended与implements的区别是,一个类只能有一个继承,一个类可以有多个容器。后来去看了些国外资料。在我理解上,interface就是一个公共的类,可以包含公共函数、变量。Java接口是用于指定一组抽象方法的类来实现一个抽象类型。当一个类实现一个接口,它必须继承所有的内声明的抽象方法,好像

夏日小草 2897

闭包、Lambda与Interface:语言设计中的契约建模三要素

编程语言中的函数抽象能力,本质是运行时行为与类型契约的协同表达。闭包解决环境捕获与生命周期管理问题,Lambda提供轻量级函数字面量语法,Interface则定义可验证的高阶行为协议。三者共同构成现代语言支撑模块化、可组合与类型安全的核心语义层。其技术价值在于将‘函数作为值’从语法糖升维为系统级能力,广泛应用于DSL设计、日志/策略插件化、异步任务编排等工程场景。本文聚焦语义建模而非语法实现,深入剖析三者在内存布局、类型检查与调用约定上的咬合逻辑,揭示如何通过最小可行设计达成安全、高效与可调试的语言特性。

世范水晶 418

抽象类,接口(interface)与匿名对象

继承的特性是单一继承,接口可以实现多个继承,接口里的所有方法全是抽象方法,接口和类的关系是实现,implements 格式: interface 接口名{ } 接口成员特点 接口中只能有抽象方法,只能有常量 默认且只能使用 public&abstract修饰方法 (建议主动加上默认修饰符) 默认使用public static final 修饰成员变量 注意:接口不能创建对象(不能实例化) 类与接口的关系是实现关系,一个类实现一个接口必须实现它的所有方法 接口与类的关系 ...

weixin_50776418的博客 537

JS-YAML:为什么你的下一个JavaScript项目需要这个YAML处理神器?

在现代JavaScript开发中,你是否经常需要处理配置文件、数据交换格式或复杂的结构化数据?如果你还在为JSON的繁琐语法和缺乏注释支持而烦恼,那么JS-YAML正是你需要的解决方案。这个强大的YAML解析器和生成器不仅速度快,而且功能完整,支持YAML 1.2规范,为你的JavaScript项目带来了全新的数据序列化体验。 ## 🌟 JS-YAML的价值主张:超越JSON的数据表达艺术

gitblog_00414的博客 947

JavaScript 中使用接口

JavaScript 中使用接口 这篇是 js-interface 的 README,虽然并不是很复杂的一个东西,如果有人看的话我就写写源码思路了 ORZ 介绍 在做一个前后分离的项目时,有些头疼 Api 之类的东西要怎么管理,在阅读 《JavaScript 设计模式》 一书时,第二章提到了在 JavaScript 中模拟接口 (in...

weixin_33975951的博客 221

javascript接口鸭式辨型法实现

鸭式辨型法实现的核心:一个类实现接口的主要目的:把接口里的方法都实现(检测方法) javascript没有接口的概念,实现接口主要有3种,注解描述,属性检测,鸭式辨型,其中鸭式辨型最为常用 javascript interface // 鸭式辨型法实现的核心:一个类实现接口的主要目的:把接口里的方法都实现

指尖残雪 1810

js二维数组传递java,ActiveX获取JavaScript传递的二维数组

此文参考了http://blog.csdn.net/playstudy/article/details/8259737,在此基础上做了改进// WebDlg.idl : WebDlg 的 IDL 源//// 此文件将由 MIDL 工具处理以// 产生类型库(WebDlg.tlb)和封送处理代码。#include "olectl.h"import "oaidl.idl";import "ocidl....

weixin_35626308的博客 255

Nodejs开发之接口

虽然js本身是面向对象语言,但是对于接口的支持并不严格,目前有很多种模拟的实现方式。具体可参考文章:http://jscriptpatterns.blogspot.com/2013/01/javascript-interfaces.html 本文提供的时另外一种思路,接口实现中的主要的两个问题是,无法保证接口实现者正确完整的实现定义的接口和影响运行效率,本文的思路是将接口实现检察放到单元测试中,

heiantianshi1的专栏 1万+

JS-YAML实战:破解JavaScript配置管理的性能瓶颈与数据解析难题

在现代JavaScript开发中,配置管理混乱、数据序列化效率低下、复杂数据结构处理困难成为开发者面临的主要痛点。JS-YAML作为一款高性能的YAML解析器和生成器,通过支持YAML 1.2规范、提供完整的数据类型支持和卓越的性能表现,为开发者提供了优雅的解决方案。 ## 配置混乱?统一管理方案 你是否曾为JSON配置文件的冗长和缺乏注释而烦恼?是否因为配置文件难以维护导致部署问题频发?JS

gitblog_00337的博客 1035
上一篇: Firefox扩展开发
下一篇: 02.Javascript中的继承----Inherits
Alien
博客等级 码龄18年 123粉丝 16原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值