在学习设计模式前必须要知道和掌握的***。

  为类添加新方法:

Function.prototype.method = function(name,fn) {
this.prototype[name] = fn;
} //改进版:支持链式调用 Function.prototype.method = function(name,fn) {
this.prototype[name] = fn;
return this;
}

  函数是一等对象,可以存储在变量中,可以作为参数传给其他函数,可以作为返回值从其他函数传出,还可以再运行的时候进行构造。这正是用以构造传统面向对象框架的基础。

  对象具有易变性。类方法可以在类实例创建之后再添加,实例仍然能够获得新添加的方法。个人觉得,这也是对象扩展的威力源泉。

  一、接口

  “针对接口,而不是实现编程”

  接口提供了一种用以说明一个对象应该具备哪些方法的手段。既定的一批接口具有自我描述性,并能促进代码的重用。接口可以告诉程序员一个类实现了哪些方法,从而帮助其使用这个类。接口最实在的用途是什么?~一个程序员可以针对所需要的类定义一个接口,并转交给另一个程序员。第二个程序员可以随心所欲地编写自己的代码,只要他定义的类实现了那个接口就行。

  当然接口也有弊端。比如额外的方法调用的开销无法避免。

  而接口使用中的最大问题在于,无法强迫其他程序员遵守你定义的接口。不像其它语言(像java等,编译期间会因为接口继承后没有写实现而报错),javascript中必须用手工的办法保证某个类实现了一个接口(你可能对此不理解是什么意思,稍安,等下立马解释^_^)。如果项目的其他程序员不认真对待接口,那么这些接口的使用是无法得到强制性保证的。除非项目的所有人都同意使用接口并对其进行检查,否则接口的很多价值都无从体现。

  解惑的时候到了,为什么前文说“javascript中必须用手工的办法保证某个类实现了一个接口”。事实上,javascript没有interface和implements关键字,也不在运行时对接口约定是否得到遵守进行检查。我们只能在javascript中模仿接口。一下介绍模仿接口的三种方法:注释法、属性检查法、鸭式辨型法。

  ① 注释法:

/*
interface Composite {
function add(child);
function remove(child);
function getChild(index);
} interface FormItem {
function sava();
}
*/ var compositeForm = function (id,method,action) {
....
}; compositeForm.prototype.add = function(child) {
....
}; compositeForm.prototype.remove = function(child) {
.....
};

  这种方法易于实现,但是不会提供错误信息。

  ② 用属性检查模仿接口

/*
interface Composite {
function add(child);
function remove(child);
function getChild(index);
} interface FormItem {
function sava();
}
*/ var compositeForm = function(id,method,action) {
this.implementInterfaces = ['Composite','FormItem'];
......
}; function addForm(formInstance) {
if(!implements(formInstance,'Composite','FormItem')) {
throw new Error("Object does not implement a required interface.");
....
}
} function implement(object) { //检查接口是否被实现
for(var i = 0;i < arguments.length;i++) {
var interfaceName = arguments[i];
var interfaceFound = false;
for(var j = 0;j < object.implementsInterfaces.length;j++) {
if(interfaceName == object.implementsInterfaces[j]) {
interfaceFound = true;
break;
}
}
if(!interfaceFound) {
return false;
}
}
return true;
}

  优点:它对所有实现的接口提供了文档说明。如果需要的接口不在一个类宣称支持的接口之列,你会看到错误消息。通过利用这些错误,你可以强迫其它程序员声明这些接口。

  缺点:它并未确保类真正实现自称实现的接口。很可能,只是有了这个接口的实现声明,方法体忘记写了,一个空的方法体造成了假象。

  ③ 用鸭式辨型模仿接口

  思想:类是否声明自己支持哪些接口不重要,只要它具有这些接口中的方法就行。“像鸭子一样走路并且嘎嘎叫的就是鸭子”。如果一个对象具有与接口定义的方法同名的所有方法,那么就可以认为它实现了这个接口。(个人觉得,这有点像客户端检测机制,我们不是去判断浏览器的类型,而是转而判断浏览器是否支持此项功能^_^换个角度思考问题往往有事半功倍之效。)

  缺点:类并不声明自己实现了哪些接口,这降低了代码的可重用性,并且也缺乏其他两种方法的自我描述性。

  

  个人觉得,最好的就接口实现时方法一和方法三的结合。也就是可读性和保证性相结合。

var Composite = new Interface('Composite',['add','remove','getChild']);
var FormItem = new Interface('FormItem',['save']); var CompositeForm = function(id,method,action) {
....
}; function addForm(formInstance) {
Interface.ensureImplements(formInstance,Composite,FormItem);
....
} 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]);
}
}; Interface.ensureImplements = function() {
if(arguments.length < 2) {
throw new Error("....");
} for(var i = 1,len = arguments.length;i < len;i++) {
var interface = arguments[i];
if(interface.constructor !== Interface) {
throw new Error("....");
} 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("....");
}
}
}
}

  接口在运用设计模式实现复杂系统的时候最能体现其价值。降低了对象间的耦合程度。在大型项目中,易于程序员的合作,如果你知道测试中的桩测试,你对此用个空方法体进行占位,提供API,无疑会使程序员间的合作开发更便捷。

  

深入js的面向对象学习篇——温故知新(一)的更多相关文章

  1. 深入js的面向对象学习篇(继承篇)——温故知新(三)

    写这篇有关继承的文章时,突然想起,几天前的面试.因为习惯在学习知识的时候加上自己的理解,很喜欢用自己话来解释,于是乎当面试被问起继承原理时,噼里啪啦一大堆都是自己组织的话,(也可能是因为个人紧张.外加 ...

  2. 深入js的面向对象学习篇(封装是一门技术和艺术)——温故知新(二)

    下面全面介绍封装和信息隐藏. 通过将一个方法或属性声明为私用的,可以让对象的实现细节对其它对象保密以降低对象之间的耦合程度,可以保持数据的完整性并对其修改方式加以约束.在代码有许多人参与设计的情况下, ...

  3. 【js】面向对象学习资料

    1.面向对象模式: https://m.jb51.net/article/74549.htm 2.面向对象基础篇 http://www.cnblogs.com/chiangchou/p/js-oop1 ...

  4. js之面向对象----封装篇

    学习了一天的面向对象总结一下,共分为三类 - -! 老规矩 第一部分是概念性知识!!! 面向对象编程,我们可以把他想象成我们在造人.一个对象便是一个人,这个人有胳膊有腿,这便是一个对象的属性或者方法. ...

  5. js面向对象学习 - 对象概念及创建对象

    原文地址:js面向对象学习笔记 一.对象概念 对象是什么?对象是“无序属性的集合,其属性可以包括基本值,对象或者函数”.也就是一组名值对的无序集合. 对象的特性(不可直接访问),也就是属性包含两种,数 ...

  6. js学习篇1--数组

    javascript的数组可以包含各种类型的数据. 1. 数组的长度 ,直接用 length 属性; var arr=[1,2,3]; arr.length; js中,直接给数组的length赋值是会 ...

  7. js面向对象学习

    纯属笔记,加强记忆,不是教程,欢迎纠错,没有逻辑,不太适合学习使用. -------------- 继承多态等太多概念难以理解,还是从实践中慢慢学吧!争取能大致看懂网上的开源的代码. -------- ...

  8. 我的JS 中级学习篇

    在codefordream上进入中级学习后,感觉立马从js的基础学习往前跳了好远,上面的东西好像都是第一次看到一样.这时候才发现,说来也曾接触过js,但是这时候才发现对js的认识就停在知道两点:js中 ...

  9. JavaScript--我发现,原来你是这样的JS:面向对象编程OOP[2]--(创建你的那个对象吧)

    一.介绍 我们继续面向对象吧,这次是面向对象编程的第二篇,主要是讲创建对象的模式,希望大家能从博客中学到东西. 时间过得很快,还是不断的学习吧,为了自己的目标. 二.创建对象 1.前面的创建对象方式 ...

随机推荐

  1. Spring(3.2.3) - Beans(11): depends-on

    大多数情况下,Bean 之间的依赖非常直接:被依赖的 Bean 作为属性.在 XML 配置文件中最常见的就是使用 <ref/> 元素.在一些特殊情况下,Bean 之间的依赖不够直接.比如, ...

  2. 【原创】birt 报表工具 不能运行 不能预览问题

    在windows 7以上版本中可能会遇到不能预览,或者不能再web查看器中查看 ,但是可以以html的方式查看.在网上看了好多解决方法,我试了都不可行,说明我遇到的问题不和他们的一样,这样怎么办呢? ...

  3. 设置一个View的背景图片的集中方法

    控制器view的背景图片的方法, 四种: 1.直接在控制器view上添加一个imageView大小设置的和view一样 UIImageView *beijingimage = [UIImageView ...

  4. 在button中加入一个view图片

    #import "ViewController.h" @interface ViewController () @end @implementation ViewControlle ...

  5. UEditor的使用方法

    文本编辑器程序员都会用到,今天无意中发现UEditor是个好东西,特奉献给大家,并提供下载. 这个编辑器的亮点是可以显示当前输入多少字符,还可以输入多少字符. 新创建的MVC项目,在layout页面里 ...

  6. Codevs 1158 尼克的任务

    1158 尼克的任务 时间限制: 1 s 空间限制: 128000 KB 题目等级 : 黄金 Gold 题目描述 Description 尼克每天上班之前都连接上英特网,接收他的上司发来的邮件,这些邮 ...

  7. 用sublime编译C++的方法

    sublime代码高亮这么好看,怎么能不用sublime敲代码呢: ) 本人用的版本是sublime Text3中文版 在网上查了查,自己的sublime现在也能编译C++了,设置步骤如下: 1.找到 ...

  8. Android 源码编译及常见错误及解决方法

    最近要往arm开发板上移植android系统,大大小小的问题遇到了太多太多,都是泪啊.本人初接触嵌入式开发,对问题的根源不是太了解,不过好在每解决一个问题,便记录一下.话不多说,正式罗列问题: hos ...

  9. CodeBlock使用技巧

    CodeBlock是一款采用C++编写的完全开源.功能强大的IDE,工欲善其事必先利其器,为了更加方便后期的开发调试,下面先就网上的一些 官方主页地址为:    http://www.codebloc ...

  10. ALI OSS RequestTimeTooSkewed

    php版阿里oss sdk,请求时抛RequestTimeTooSkewed错误,说时间差距太大,搜了一下发现是服务器的时间设置问题. 我们在安装完Centos Linux操作系统之后,点击系统的时间 ...