javascript常用的设计模式


Posted in Javascript onFebruary 09, 2017

js最好是一种面向对象的语言。它的出现时比较迟的。但是它是目前最火的脚本语言。而且,随着近期的微信商城等页面的兴起,相信程序员和互联网的从业者都知道了js正在势头上了。

那么,如果你想要在前端这条路上走得更远,设计模式就必须要懂。下面介绍几种常见的设计模式。

一、单例模式

单例模式也称作为单子模式,更多的也叫做单体模式。为软件设计中较为简单但是最为常用的一种设计模式。 在JavaScript里,实现单例的方式有很多种,其中最简单的一个方式是使用对象字面量的方法,其字面量里可以包含大量的属性和方法:

var mySingleton = {
property1: "something",
property2: "something else",
method1: function () {
  console.log('hello world');
}};

如果以后要扩展该对象,你可以添加自己的私有成员和方法,然后使用闭包在其内部封装这些变量和函数声明。只暴露你想暴露的public成员和方法,样例代码如下:

var mySingleton = function () {
  /* 这里声明私有变量和方法 */
  var privateVariable = 'something private';
  function showPrivate() {
    console.log(privateVariable);
  }
  /* 公有变量和方法(可以访问私有变量和方法) */
  return {
    publicMethod: function () {
      showPrivate();
    },
    publicVar: 'the public can see this!'
  };
};
var single = mySingleton();
single.publicMethod(); // 输出 'something private'
console.log(single.publicVar); // 输出 'the public can see this!'

上面的代码很不错了,但如果我们想做到只有在使用的时候才初始化,那该如何做呢?为了节约资源的目的,我们可以另外一个构造函数里来初始化这些代码,如下:

var Singleton = (function () {
  var instantiated;
  function init() {
    /*这里定义单例代码*/
    return {
      publicMethod: function () {
        console.log('hello world');
      },
      publicProperty: 'test'
    };
  }
  return {
    getInstance: function () {
      if (!instantiated) {
        instantiated = init();
      }
      return instantiated;
    }
  };
})();
/*调用公有的方法来获取实例:*/
Singleton.getInstance().publicMethod();

二、工厂模式

工厂模式是由一个方法来决定到底要创建哪个类的实例, 而这些实例经常都拥有相同的接口. 这种模式主要用在所实例化的类型在编译期并不能确定, 而是在执行期决定的情况。 说的通俗点,就像公司茶水间的饮料机,要咖啡还是牛奶取决于你按哪个按钮。

实例:

function A( name ){
       this.name = name;
    }
    function ObjectFactory(){
       var obj = {},
           Constructor = Array.prototype.shift.call( arguments );
obj.__proto__ = typeof Constructor .prototype === 'number' ? Object.prototype
: Constructor .prototype;
       var ret = Constructor.apply( obj, arguments );
       return typeof ret === 'object' ? ret : obj;
    }
    var a = ObjectFactory( A, 'svenzeng' );
    alert ( a.name ); //svenzeng

这段代码来自es5的new和构造器的相关说明, 可以看到,所谓的new, 本身只是一个对象的复制和改写过程, 而具体会生成什么是由调用ObjectFactory时传进去的参数所决定的。

三、 适配模式

简单的说,适配模式主要是为了解决一些接口不兼容产生的解决方法。借助于适配器我们可以在不修改这些不兼容接口的情况下给使用者提供统一的包装过的适配接口。表面上又感觉和之前的门面模式比较像,均是对其他对象或者接口进行包装再呈现,而适配器模式偏向的是解决兼容性问题,门面模式则偏向方便性为原则。

比如一个简单的学生查询学科成绩的方法:

function selectScore( name, id, course_id ){
  // arguments 姓名 学号 课程id
  ...
}

当我需要一个班级某门学科的整体成绩列表,而我手上只有每个学生如下的数据

[
  { name: 'lily', studentID: '0911' },
  { name: 'suny', studentID: '0912' },
  ...
]

我需要查询 英语 其课程ID为 101,那么对于该任务,写一个适配器方式是很恰当不过的

function selectEnglishScore( stutentObj ){
  selectScore( stutentObj.name, stutentObj.studentID , 101);
}

这是一个最简单的关于适配器来处理参数方面兼容的形式。 其实简单的来说,适配器模式意义上很简单 - 适配,解决兼容问题。

例子二,比如你觉得jquery里边的$选择器需要改成$id才能和你的项目搭配,那么这时候写一个方法,将$转换成$id就很轻松了。如下:

$id = function( id ){
 return jQuery( '#' + id )[0];
}

四、外观模式

外观模式(门面模式),是一种相对简单而又无处不在的模式。外观模式提供一个高层接口,这个接口使得客户端或子系统更加方便调用。 用一段再简单不过的代码来表示:

var getName = function(){
 return ''svenzeng"
}
var getSex = function(){
  return 'man'
}

如果你需要分别调用getName和getSex函数. 那可以用一个更高层的接口getUserInfo来调用.:

var getUserInfo = function(){
 var info = a() + b();
 return info;
}

也许你会问为什么一开始不把getName和getSex的代码写到一起, 比如这样:

var getNameAndSex = function(){
 return 'svenzeng" + "man";
}

答案是显而易见的,饭堂的炒菜师傅不会因为你预定了一份烧鸭和一份白菜就把这两样菜炒在一个锅里。他更愿意给你提供一个烧鸭饭套餐。同样在程序设计中,我们需要保证函数或者对象尽可能的处在一个合理粒度,毕竟不是每个人喜欢吃烧鸭的同时又刚好喜欢吃白菜。 外观模式还有一个好处是可以对用户隐藏真正的实现细节,用户只关心最高层的接口。比如在烧鸭饭套餐的故事中,你并不关心师傅是先做烧鸭还是先炒白菜,你也不关心那只鸭子是在哪里成长的。

最后写个我们都用过的外观模式例子:

var stopEvent = function( e ){  //同时阻止事件默认行为和冒泡
 e.stopPropagation();
 e.preventDefault();
}

好了,今天的额设计模式就先到这里。如果大家想要了解更多的设计模式可以去汤姆大叔的博客欣赏哦。还有,这里的很多的设计模式其实都是将解决问题的方法细化了的说法,如果去看一下prototype或者jquery都会知道,其实里边的代码很多都用到了设计模式的。

以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,同时也希望多多支持三水点靠木!

Javascript 相关文章推荐
基于jQuery的图片左右无缝滚动插件
May 23 Javascript
javascript采用数组实现tab菜单切换效果
Dec 12 Javascript
jQuery实现高亮显示的方法
Mar 10 Javascript
javascript表格隔行变色加鼠标移入移出及点击效果的方法
Apr 10 Javascript
js中setTimeout()与clearTimeout()用法实例浅析
May 12 Javascript
js编写当天简单日历效果【实现代码】
May 03 Javascript
微信小程序教程系列之设置标题栏和导航栏(7)
Jun 29 Javascript
React Hooks的深入理解与使用
Nov 12 Javascript
微信小程序实现单列下拉菜单效果
Apr 25 Javascript
js比较两个单独的数组或对象是否相等的实例代码
Apr 28 Javascript
解决vue项目 build之后资源文件找不到的问题
Sep 12 Javascript
vant 中van-list的用法说明
Nov 11 Javascript
简单实现js选项卡切换效果
Feb 09 #Javascript
原生JS轮播图插件
Feb 09 #Javascript
jQuery页面弹出框实现文件上传
Feb 09 #Javascript
如何在Angular2中使用jQuery及其插件的方法
Feb 09 #Javascript
详解angular2采用自定义指令(Directive)方式加载jquery插件
Feb 09 #Javascript
vue-router跳转页面的方法
Feb 09 #Javascript
基于JavaScript实现复选框的全选和取消全选
Feb 09 #Javascript
You might like
thinkphp获取栏目和文章当前位置的方法
2014/10/29 PHP
php+js实现百度地图多点标注的方法
2016/11/30 PHP
详解Yii2高级版引入bootstrap.js的一个办法
2017/03/21 PHP
阿里云PHP SMS短信服务验证码发送方法
2017/07/11 PHP
Mootools 1.2教程(3) 数组使用简介
2009/09/14 Javascript
Javascript学习笔记4 Eval函数
2010/01/11 Javascript
JavaScript 面向对象编程(2) 定义类
2010/05/18 Javascript
jQuery getJSON()+.ashx 实现分页(改进版)
2013/03/28 Javascript
JS实现商品倒计时实现代码
2013/05/03 Javascript
jquery弹出层类代码分享
2013/12/27 Javascript
原生javaScript做得动态表格(注释写的很清楚)
2013/12/29 Javascript
移动手机APP手指滑动切换图片特效附源码下载
2015/11/30 Javascript
JavaScript学习笔记--常用的互动方法
2016/12/07 Javascript
vuejs绑定class和style样式
2017/04/11 Javascript
Angular 4依赖注入学习教程之Injectable装饰器(六)
2017/06/04 Javascript
javascript设计模式 ? 原型模式原理与应用实例分析
2020/04/10 Javascript
javascript设计模式 ? 策略模式原理与用法实例分析
2020/04/21 Javascript
VUE UPLOAD 通过ACTION返回上传结果操作
2020/09/07 Javascript
[02:21]DOTA2英雄基础教程 蝙蝠骑士
2013/12/16 DOTA
Python用UUID库生成唯一ID的方法示例
2016/12/15 Python
Python模拟鼠标点击实现方法(将通过实例自动化模拟在360浏览器中自动搜索python)
2017/08/23 Python
Python 删除连续出现的指定字符的实例
2018/06/29 Python
Python 使用PIL中的resize进行缩放的实例讲解
2018/08/03 Python
Matplotlib中文乱码的3种解决方案
2018/11/15 Python
详解使用python绘制混淆矩阵(confusion_matrix)
2019/07/14 Python
浅谈Python中threading join和setDaemon用法及区别说明
2020/05/02 Python
如何利用Python给自己的头像加一个小国旗(小月饼)
2020/10/02 Python
家庭睡衣和家庭用品:Little Blue House
2018/03/18 全球购物
介绍一下内联、左联、右联
2013/12/31 面试题
机械设计职业生涯规划书
2013/12/27 职场文书
初中地理教学反思
2014/01/11 职场文书
认错检讨书
2014/10/02 职场文书
党的群众路线教育实践活动专题组织生活会发言材料
2014/10/17 职场文书
实习指导老师意见
2015/06/04 职场文书
Pandas自定义选项option设置
2021/07/25 Python
vue el-table实现递归嵌套的示例代码
2022/08/14 Vue.js