javascript中什么是接口
在javascript中,接口是一系列抽象方法的声明,是一些方法特征的集合,它提供了一种用以说明一个对象应该具有哪些方法的手段。接口能够促进代码的重用性,还有助于稳定不同类之间的通信方式,减少了继承两个对象的过程中出现的问题。
本教程操作环境:windows7系统、javascript1.8.5版、Dell G3电脑。
什么是接口
接口是一系列抽象方法的声明,是一些方法特征的集合,这些方法都应该是抽象的,需要由具体的类去实现,然后第三方就可以通过这组抽象方法调用,让具体的类执行具体的方法。
接口是面向对象JavaScript程序员的工具箱中最有用的工具之一。在设计模式中提出的可重用的面向对象设计的原则之一就是“针对接口编程而不是实现编程”,即我们所说的面向接口编程,这个概念的重要性可见一斑。
但问题在于,在JavaScript的世界中,没有内置的创建或实现接口的方法,也没有可以判断一个对象是否实现了与另一个对象相同的一套方法,这使得对象之间很难互换使用,好在JavaScript拥有出色的灵活性,这使得模拟传统面向对象的接口,添加这些特性并非难事。
接口提供了一种用以说明一个对象应该具有哪些方法的手段,尽管它可以表明这些方法的含义,但是却不包含具体实现。有了这个工具,就能按对象提供的特性对它们进行分组。
例如,假如A和B以及接口I,即便A对象和B对象有极大的差异,只要他们都实现了I接口,那么在A.I(B)方法中就可以互换使用A和B,如B.I(A)。
还可以使用接口开发不同的类的共同性。如果把原本要求以一个特定的类为参数的函数改为要求以一个特定的接口为参数的函数,那么所有实现了该接口的对象都可以作为参数传递给它,这样一来,彼此不相关的对象也可以被相同地对待。
接口的利与弊
既定的接口具有自我描述性,并能够促进代码的重用性,接口可以提供一种信息,告诉外部一个类需要实现哪些方法。还有助于稳定不同类之间的通信方式,减少了继承两个对象的过程中出现的问题。
这对于调试也是有帮助的,在JavaScript这种弱类型语言中,类型不匹配很难追踪,使用接口时,如果出现了问题,会有更明确的错误提示信息。当然接口并非完全没有缺点,如果大量使用接口会一定程度上弱化其作为弱类型语言的灵活性,另一方面,JavaScript并没有对接口的内置的支持,只是对传统的面向对象的接口进行模拟,这会使本身较为灵活的JavaScript变得更加难以驾驭。
此外,任何实现接口的方式都会对性能造成影响,某种程度上归咎于额外的方法调用开销。接口使用的最大的问题在于,JavaScript不像是其他的强类型语言,如果不遵守接口的约定,就会编译失败,其灵活性可以有效地避开上述问题,如果是在协同开发的环境下,其接口很有可能被破坏而不会产生任何错误,也就是不可控性。
在面向对象的语言中,使用接口的方式大体相似。接口中包含的信息说明了类需要实现的方法以及这些方法的签名。类的定义必须明确地声明它们实现了这些接口,否则是不会编译通过的。
显然在JavaScript中我们不能如法炮制,因为不存在interface和implement关键字,也不会在运行时对接口是否遵循约定进行检查,但是我们可以通过辅助方法和显式地检查模仿出其大部分特性。
javascript中怎么实现接口
JavaScript中有三种方式实现接口:
(1)注释描述接口
(2)属性检测接口
(3)鸭式辨型接口
1、注释描述接口:不推荐
优点:易于实现,不需要额外的类或函数。
缺点:纯文档约束,程序不能检查实现接口的对象是否实现了所有接口方法
/** * interface Composite{ * function a(); * function b(); * } */ // CompositeImpl implements Composite var CompositeImpl = function(){ //业务逻辑 }; CompositeImpl.prototype.a = function(){ //业务逻辑 }; CompositeImpl.prototype.b = function(){ //业务逻辑 };
2、属性检测接口:不推荐
第二种方法要更严谨一点。所有类都明确地声明自己实现了哪些接口,那些想与这些类打交道的对象可以针对这些声明进行检查。那些接口自身仍然只是注释,但现在你可以通过检查一个属性得知某个类自称实现了什么接口。
优点:能够检查实现了哪些接口
缺点:并未确保类真正实现了自称实现的接口。你只知道它是否说自己实现了接口。
var interfacesImpl = function(){ //在实现类内部用一个数组保存要实现的方法名 //通常这个属性名是团队中规定好的 //声明自己实现了这两个方法,但实际上并不一定 this.implementsInterfaces = ["Composite","FormItem"]; }; //专门为这个实现对象写一个检测函数,传入实例对象,用于检查实例对象是否实现了所有接口 function checkImplements(obj){ //调用检查方法 obj是否实现了两个接口,如果没有都实现则抛出异常 if(!isImplements(obj,"Composite","FormItem")){ throw new Error("接口没有全部实现!"); } //obj是要检查的对象 function isImplements(obj){ //传入的第0个参数是要检查的对象,所以从1开始检查 for(var i=1; i<arguments.length; i++){ //接收接口中每个接口的名字 var interfaceName = arguments[i]; //默认未实现该接口 var foundFlag = false; //循环查询传入实例对象的实现接口数组,检查是否全部实现 for(var j=0; j<obj.implementsInterfaces.length; j++){ //如果实现了这个接口,就修改标记并跳出 //debugger if(obj.implementsInterfaces[j] == interfaceName){ foundFlag = true; break; } } //如果遍历实现接口数组之后没找到,返回false if(!foundFlag){ return false; } } return true; } } //使用实例对象并检测 var o = new interfacesImpl(); checkImplements(o);
3、鸭式辨型法:推荐
背后的观点:如果对象具有与接口定义的方法同名的所有方法,那么久可以认为它实现了这个接口。
/** * 接口类 * * @param {String} name 接口的名字 * @param {Array} methods 要实现方法名称的数组 */ var Interface = function (name, methods) { //判断参数个数 if(arguments.length !== 2){ throw new Error("接口构造器参数必须是两个!"); } this.name = name; this.methods = []; for(var i=0; i<methods.length; i++){ if(typeof methods[i] !== "string"){ throw new Error("接口实现的函数名称必须是字符串!"); } this.methods.push(methods[i]); } } //实例化接口对象---传入接口名和要实现的方法数组 var CompositeInterface = new Interface("CompositeInterface",["add","remove"]); var FormItemInterface = new Interface("FormItemInterface",["update","select"]); //实现接口的类 var CompositeImpl = function(){ } //实现接口的方法 CompositeImpl.prototype.add = function(obj){ //... } CompositeImpl.prototype.remove = function(obj){ //... } CompositeImpl.prototype.select = function(obj){ //... } //在这里少实现一个方法,下面检查是否全部实现了接口 // CompositeImpl.prototype.update = function(obj){ // //... // } //实例化 实现接口的对象 var c = new CompositeImpl(); //检验接口里的方法是否全部实现,如果不通过则抛出异常 Interface.ensureImplements = function(obj){ //如果接收到参数小于2,说明异常 if(arguments.length < 2){ throw new Error("接口检查方法的参数必须多余两个!"); } //接口实现检查 for(var i=0,len = arguments.length; i<len; i++){ //获取当前接口 var instanceInterface = arguments[i]; //判断接收到的是不是接口的对象,如果不是则抛出异常 if(instanceInterface.constructor !== Interface){ throw new Error("接口检测函数必须传入接口对象!"); } //检查实例化接口的对象是不是实现了接口里的所有方法 for(var j=0; j<instanceInterface.methods.length; j++){ //接收到的字符串方法 var methodName = instanceInterface.methods[j]; //如果obj里面没有methodsName这个方法,或者有这个属性但是不是函数,就抛出异常 if(!obj[methodName] || typeof obj[methodName] !== "function"){ throw new Error("接口方法" + methodName + "没有实现!"); } } } } //传入要检查的类,和要实现的所有接口对象 Interface.ensureImplements(c, CompositeInterface, FormItemInterface); c.add();
【相关推荐:javascript学习教程】
以上是javascript中什么是接口的详细内容。更多信息请关注PHP中文网其他相关文章!

热AI工具

Undresser.AI Undress
人工智能驱动的应用程序,用于创建逼真的裸体照片

AI Clothes Remover
用于从照片中去除衣服的在线人工智能工具。

Undress AI Tool
免费脱衣服图片

Clothoff.io
AI脱衣机

Video Face Swap
使用我们完全免费的人工智能换脸工具轻松在任何视频中换脸!

热门文章

热工具

记事本++7.3.1
好用且免费的代码编辑器

SublimeText3汉化版
中文版,非常好用

禅工作室 13.0.1
功能强大的PHP集成开发环境

Dreamweaver CS6
视觉化网页开发工具

SublimeText3 Mac版
神级代码编辑软件(SublimeText3)

我们在电脑组装的过程中,安装过程虽然简单,不过往往都是在接线上遇到问题,经常有装机用户误将CPU散热器的供电线插到了SYS_FAN上,虽然风扇可以转动,不过在开机可能会有F1报错“CPUFanError”,同时也导致了CPU散热器无法智能调速。下面装机之家分享一下电脑主板上CPU_FAN、SYS_FAN、CHA_FAN、CPU_OPT接口知识科普。电脑主板上CPU_FAN、SYS_FAN、CHA_FAN、CPU_OPT接口知识科普1、CPU_FANCPU_FAN是CPU散热器专用接口,12V工作

Go语言作为一门现代化的、高效的编程语言,拥有丰富的编程范式和设计模式可以帮助开发者编写高质量、可维护的代码。本文将介绍Go语言中常见的编程范式和设计模式,并提供具体的代码示例。1.面向对象编程在Go语言中,可以使用结构体和方法实现面向对象编程。通过定义结构体和给结构体绑定方法,可以实现数据封装和行为绑定在一起的面向对象特性。packagemaini

PHP接口简介及其定义方式PHP是一种广泛应用于Web开发的开源脚本语言,具有灵活、简单、强大等特点。在PHP中,接口(interface)是一种定义多个类之间公共方法的工具,实现了多态性,让代码更加灵活和可重用。本文将介绍PHP接口的概念及其定义方式,同时提供具体的代码示例展示其用法。1.PHP接口概念接口在面向对象编程中扮演着重要的角色,定义了类应

报错的原因在python中,Tornado中抛出NotImplementedError()的原因可能是因为未实现某个抽象方法或接口。这些方法或接口在父类中声明,但在子类中未实现。子类需要实现这些方法或接口才能正常工作。如何解决解决这个问题的方法是在子类中实现父类声明的抽象方法或接口。如果您正在使用一个类来继承另一个类,并且您看到了这个错误,则应该在子类中实现父类中所有声明的抽象方法。如果您正在使用一个接口,并且您看到了这个错误,则应该在实现该接口的类中实现该接口中所有声明的方法。如果您不确定哪些

接口和抽象类在设计模式中用于解耦和可扩展性。接口定义方法签名,抽象类提供部分实现,子类必须实现未实现的方法。在策略模式中,接口用于定义算法,抽象类或具体类提供实现,允许动态切换算法。在观察者模式中,接口用于定义观察者行为,抽象类或具体类用于订阅和发布通知。在适配器模式中,接口用于适配现有类,抽象类或具体类可实现兼容接口,允许与原有代码交互。

鸿蒙系统作为华为推出的全新操作系统,在行业内引起了不小的轰动。作为华为在美国禁令之后的一次全新尝试,鸿蒙系统被寄予了厚望和期待。近日,我有幸得到了一部搭载鸿蒙系统的华为手机,经过一段时间的使用和实测,我将分享一些关于鸿蒙系统的功能实测和使用感受。首先,让我们来看一下鸿蒙系统的界面和功能。鸿蒙系统整体采用了华为自家的设计风格,简洁清晰,操作流畅。在桌面上,各种

Java允许在接口和抽象类中定义内部类,为代码重用和模块化提供灵活性。接口中的内部类可实现特定功能,而抽象类中的内部类可定义通用功能,子类提供具体实现。

接口:无实现的契约接口在Java中定义了一组方法签名,但不提供任何具体实现。它充当一种契约,强制实现该接口的类实现其指定的方法。接口中的方法是抽象方法,没有方法体。代码示例:publicinterfaceAnimal{voideat();voidsleep();}抽象类:部分实现的蓝图抽象类是一种父类,它提供了一个部分实现,可以被它的子类继承。与接口不同,抽象类可以包含具体的实现和抽象方法。抽象方法是用abstract关键字声明的,并且必须被子类覆盖。代码示例:publicabstractcla
