JS 设想形式 一(接口)

什么是接口

接口是父类请求子类完成的要领,然则父类并不划定子类应当怎样完成。比方,我有一个Person父类,定义了一个job的接口。然后定义一个Student类继续Person这个父类。他在就肯定要定义job这个函数。

接口之利

在面向对象的编程中接口有肯定的自我描述性。并能增进代码的重用。接口能够通知要运用他的程序员这个类完成了哪些要领。一个程序员为类写下了接口,第二个程序员就只需完成了接口,就能够轻易大的项目标解耦。也能够完成依靠倒转准绳

接口之弊

JS并没有供应接口的内置语法,由于JS是动态编译的。其他完成接口的言语如C++,JAVA都是在编译历程当中完成对接口的校验。JS没有这个历程,要完成接口的校验肯定会带来机能上的影响。

《javascript设想形式》的一个例子

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]);        
    }    
};    

// Static class method.

Interface.ensureImplements = function(object) {
    if(arguments.length < 2) {
        throw new Error("Function Interface.ensureImplements called with " + 
          arguments.length  + "arguments, but expected at least 2.");
    }

    for(var i = 1, len = arguments.length; i < len; i++) {
        var interface = arguments[i];
        if(interface.constructor !== Interface) {
            throw new Error("Function Interface.ensureImplements expects arguments " + "two and above to be instances of Interface.");
        }
        
        for(var j = 0, methodsLen = interface.methods.length; j < methodsLen; j++) {
            var method = interface.methods[j];
            if(!object[method] || typeof object[method] !== 'function') {
                throw new Error("Function Interface.ensureImplements: object " + "does not implement the " + interface.name + " interface. Method " + method + " was not found.");
            }
        }
    } 
};
var DynamicMap = new Interface('DynamicMap', ['centerOnPoint', 'zoom', 'draw']);

function displayRoute(mapInstance) {
    Interface.ensureImplements(mapInstace, DynamicMap);
    mapInstance.centerOnPoint(12, 34);
    mapInstance.zoom(5);
    mapInstance.draw();
    ...
}

以上是书中的完成要领。

能够看到每次在运用前都会做一次接口的遍历如许会大大影响效力。而且这个有肯定的强制性影响了JS代码的天真性。我试着做了另一种要领来做到接口的提醒作用。并削减强制性。

我的要领

var Interface = function (object, 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.');
    }
    object[methods[i]] = function () {
      throw new Error(this.constructor.name + ' Interface function is undefined');
    };
  }
};
function Person(name) {
  this.name = name;
  this.sayjob = function () {
    console.log('say');
    this.job();
  };
  this.sayage = function () {
    console.log('say');
    this.age();
  };
}
function creatPerson(name) {
  var object = new Person(name);
  Interface(object, ['job', 'age']);
  return object;
}
function Student(name) {
  this.__proto__ = creatPerson(name);
  this.job = function () {
    console.log('job is student');
  };
}
function creatStudent(name) {
  var object = new Student(name);
  return object;
}
var b = creatStudent('b');
b.job();
//b.age();
b.sayjob();
//b.sayage();

总结

我运用了JS的原型来完成,当接口函数被挪用时刻检察根据JS的运转原应当子类没有完成时刻会挪用父类中的要领弹出毛病并给出提醒。我以为接口的重要目标是做限定,不过在JS这类天真度特别高的言语中,我个人以为如许的限定影响了机能。也带丧失了天真性。所以我把他修改成这类体式格局完成,已达到代码中给提醒的目标来完成接口的个设想形式。

    原文作者:zchq88
    原文地址: https://segmentfault.com/a/1190000005025231
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞