首页 > 其他分享 >js设计模式(上)

js设计模式(上)

时间:2024-04-27 14:12:06浏览次数:22  
标签:function return fns js var console 设计模式 fn

 

引用:(23条消息) 《Javascript设计模式与开发实践》关于设计模式典型代码的整理(上):单例模式、策略模式、代理模式、迭代器模式、发布-订阅模式、命令模式、组合模式_QQsilhonette的博客-CSDN博客

1、单例模式:保证一个类仅有一个实例,并提供一个访问它的全局访问点。

使用闭包封装私有变量
// 使用闭包创建单例
var user = (function () {
var _name = 'sven',
_age = 29;

return {
getUserInfo: function () {
return _name + '-' + _age;
}
}
})();
惰性单例(只在合适的时候创建对象,并且之创建唯一的一个,试用于dom重复生成、事件绑定等场景)
// 惰性单例生成
var getSingle = function (fn) {
var result;
return function () {
return result || (result = fn.apply(this, arguments));
}
};
2、策略模式:定义一系列的算法,把它们一个个封装起来,并且使它们可以相互替换。

// 策略模式
var strategies = {
"S": function (salary) {
return salary * 4;
},
"A": function (salary) {
return salary * 3;
},
"B": function (salary) {
return salary * 2;
},
};

var calculateBonus = function (level, salary) {
return strategies[level](salary);
}
// 测试
console.log(calculateBonus('S', 20000));
console.log(calculateBonus('A', 10000));
3、代理模式:为一个对象提供一个代用品或占位符,以便控制对它的访问。

// 虚拟代理
var myImage = (function () {
var imgNode = document.createElement('img');
document.body.appendChild(imgNode);

return {
setSrc: function (src) {
imgNode.src = src;
}
}
})();

var proxyImage = (function () {
var img = new Image;
img.onload = function () {
myImage.setSrc(this.src);
}
return {
setSrc: function (src) {
myImage.setSrc('file:// /C:/Users/svenzeng/Desktop/loading.gif');
img.src = src;
}
}
})();
// 测试
proxyImage.setSrc('http:// imgcache.qq.com/music/photo/k/000GGDys0yA0Nk.jpg' );
// 缓存代理
var mult = function () {
console.log('开始计算乘积');
var a = 1;
for(var i = 0, l = arguments.length; i < l; i++) {
a = a * arguments[i];
}
return a;
}

var proxyMult = (function () {
var cache = {};
return function () {
var args = Array.prototype.join.call(arguments, ',');
if(args in cache) {
return cache[args];
}
return cache[args] = mult.apply(this, arguments);
}
})();
// 测试
proxyMult(1,2,3,4);
proxyMult(1,2,3,4);

4、迭代器模式:提供一种方法顺序访问一个聚合对象中的各个元素,而又不需要暴露该对象的内部表示。

// 迭代器模式
var each = function(ary, callback) {
for (var i = 0, l = ary.length; i < l; i++) {
callback.call(ary[i], i, ary[i]);
}
};
// 测试
each([1, 2, 3], function(i, n) {
alert ([i, n]);
});
5、发布-订阅模式:它定义对象间的一种一对多的依赖关系,当一个对象的状 态发生改变时,所有依赖于它的对象都将得到通知。

// 发布-订阅模式
var event = {
clientList: [],
listen: function (key, fn) {
if (!this.clientList[key]) {
this.clientList[key] = [];
}
this.clientList[key].push(fn); // 订阅的消息添加进缓存列表
},
trigger: function () {
var key = Array.prototype.shift.call(arguments);
fns = this.clientList[key];
if (!fns || fns.length === 0) { // 如果没有绑定对应的消息
return false;
}
for (var i = 0, fn; fn = fns[i++];) {
fn.apply(this, arguments);
}
},
remove: function (key, fn) {
var fns = this.clientList[key];
if (!fns) { // 如果 key 对应的消息没有被人订阅,则直接返回
return false;
}
if (!fn) { // 如果没有传入具体的回调函数,表示需要取消 key 对应消息的所有订阅
fns && (fns.length = 0);
} else {
for (var l = fns.length - 1; l >= 0; l--) {
var _fn = fns[l];
if (_fn ===fn) {
fns.splice(l, 1); // 删除订阅者的回调函数
}
}
}
}
};
// 安装发布—订阅功能
var installEvent = function (obj) {
for (var i in event) {
obj[i] = event[i];
}
};
// 测试
var salesOffices = {};
installEvent( salesOffices );

salesOffices.listen( 'squareMeter88', fn1 = function( price ){
console.log( '价格= ' + price );
}); // 小明订阅消息
salesOffices.listen( 'squareMeter88', fn2 = function( price ){
console.log( '价格= ' + price );
}); // 小红订阅消息
salesOffices.remove( 'squareMeter88', fn1 );
salesOffices.trigger( 'squareMeter88', 2000000 ); // 输出:2000000

6、命令模式:用一种松耦合的方式来设计程序,使得请求发送者和请求接收者能够消除彼此之间的耦合关系。

// 命令模式
var bindClick = function (button, func) {
button.onclick = func;
};

var MenuBar = {
refresh: function () {
console.log('刷新菜单界面');
}
};

var SubMenu = {
add: function () {
console.log('增加子菜单');
},
del: function () {
console.log('删除子菜单');
}
};
// 测试
bindClick(button1, MenuBar.refresh);
bindClick(button2, SubMenu.add);
bindClick(button3, SubMenu.del);

7、组合模式:将对象组合成树形结构,以表示“部分-整体”的层次结构。

// 组合模式
var closeDoorCommand = {
execute: function () {
console.log('关门');
}
};

var openPcCommand = {
execute: function () {
console.log('开电脑');
}
};
var openQQCommand = {
execute: function () {
console.log('登录 QQ');
}
};

var MacroCommand = function () {
return {
commandsList: [],
add: function (command) {
this.commandsList.push(command);
},
execute: function () {
for (var i = 0, command; command = this.commandsList[i++];) {
command.execute();
}
}
}
};
// 测试
var macroCommand = MacroCommand();
macroCommand.add(closeDoorCommand);
macroCommand.add(openPcCommand);
macroCommand.add(openQQCommand);

macroCommand.execute();

————————————————
版权声明:本文为CSDN博主「QQsilhonette」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/QQsilhonette/article/details/84943932

标签:function,return,fns,js,var,console,设计模式,fn
From: https://www.cnblogs.com/zhengwei-cq/p/16533761.html

相关文章

  • js调整div顺序
    js调整div顺序并保留div原有事件等<divclass="my_tabs"><divclass="el-tabs__nav-scroll"><divclass="el-tabs__nav"><divclass="el-tabs__itemis-active">AAAA</div><d......
  • vue,js直接导出excel,xlsx的方法,XLSX_STYLE 行高设置失效的问题解决
    1、先安装依赖:xlsx、xlsx-style、file-saver三个包npminstallxlsxxlsx-stylefile-saver2、引入:<script>import*asXLSXfrom'xlsx/xlsx.mjs'importXLSX_STYLEfrom'xlsx-style';import{saveAs}from'file-saver';exportdefau......
  • JS相关技巧
    随意修改网页js代码document.body.contentEditable="true"document.designMode="on"或javascript:document.body.contentEditable='true';document.designMode='on';void0(浏览器输入框执行,chrome需要粘贴后,需要在前面手打javascript:因为粘贴的会自动过滤)复......
  • AssemblyResolve巧解未能加载文件或程序集“Newtonsoft.Json, Version=6.0.0.0的问题
    问题:未能加载文件或程序集“Newtonsoft.Json,Version=6.0.0.0,Culture=neutral,PublicKeyToken=30ad4fe6b2a6aeed”或它的某一个...问题分析:原因是因为引用的Microsoft.AspNet.SignalR.Client库的依赖项是6.0版本的Newtonsoft.Json,而且是动态加载进去的(用Assembly.LoadFrom),......
  • 使用 Docker 部署 Nuxt.js 应用程序
     来源:https://medium.com/@jkpeyi/deploying-a-nuxt-js-application-with-docker-69bf822c066d  WhendevelopingaNuxt.jsapplication,it’sessentialtobeabletodeployiteasilyandreproducibly.Inthisarticle,wewillexplorehowtouseDockertod......
  • NodeJS命令行注入:示例及预防
    在本文中,我们将学习如何在NodeJS中使用命令行函数进行注入漏洞攻击。现代网站可以是一个复杂的软件,它由许多分布在不同环境中的部分组成。如果你的应用程序没有得到有效的保护,那么分布在这些环境中的每一个组成部分都有可能受到命令行注入漏洞的攻击。本文将介绍如......
  • vue箭头函数、js-for循环、事件修饰符、摁键事件和修饰符、表单控制、完整购物车版本
    【箭头函数】1<!DOCTYPEhtml>2<htmllang="en">3<head>4<metacharset="UTF-8">5<title>Title</title>6<scriptsrc="https://cdn.jsdelivr.net/npm/vue/dist/vue.js">&l......
  • Node.js Express 框架(2)
    1.读取文件并返回给客户端res.sendFile(path):读取文件并返回给客户端,适合静态页面app.get("/",function(req,res){res.sendFile(path.join(__dirname,"index.html"))})res.render(path,data):读取文件,配合模版引擎可以将数据渲染到文件中并返回给客户端,适合动态页面......
  • 设计模式
    设计模式的七大原则1、开闭原则(OpenClosePrinciple)开闭原则的意思是:对扩展开放,对修改关闭。在程序需要进行拓展的时候,不能去修改原有的代码,实现一个热插拔的效果。简言之,是为了使程序的扩展性好,易于维护和升级。想要达到这样的效果,我们需要使用接口和抽象类,后面的具体设计中......
  • vue3打包js内存溢出
     第一步:npminstall-gincrease-memory-limit第二步:npminstallincrease-memory-limit—save-dev第三步:package.json文件中修改   "build:win32":"cross-envLIMIT=2048increase-memory-limitBUILD_TARGET=win32node.electron-vue/build.js",//添加这个......