深入理解JavaScript系列(50):Function模式(下篇)
介绍 本篇我们介绍的一些模式称为初始化模式和性能模式,主要是用在初始化以及提高性能方面,一些模式之前已经提到过,这里只是做一下总结。 立即执行的函数 在本系列第4篇的《立即调用的函数表达式》中,我们已经对类似的函数进行过详细的描述,这里我们只是再举两个简单的例子做一下总结。 // 声明完函数以后,立即执行该函数
(function () {
console.log('watch out!');
} ()); //这种方式声明的函数,也可以立即执行
!function () {
console.log('watch out!');
} (); // 如下方式也都可以哦
~function () { /* code */ } ();
-function () { /* code */ } ();
+function () { /* code */ } (); 立即执行的对象初始化 该模式的意思是指在声明一个对象(而非函数)的时候,立即执行对象里的某一个方法来进行初始化工作,通常该模式可以用在一次性执行的代码上。 ({
// 这里你可以定义常量,设置其它值
maxwidth: 600,
maxheight: 400, // 当然也可以定义utility方法
gimmeMax: function () {
return this.maxwidth + "x" + this.maxheight;
}, // 初始化
init: function () {
console.log(this.gimmeMax());
// 更多代码...
}
}).init(); // 这样就开始初始化咯 分支初始化 分支初始化是指在初始化的时候,根据不同的条件(场景)初始化不同的代码,也就是所谓的条件语句赋值。之前我们在做事件处理的时候,通常使用类似下面的代码: var utils = {
addListener: function (el, type, fn) {
if (typeof window.addEventListener === 'function') {
el.addEventListener(type, fn, false);
} else if (typeof document.attachEvent !== 'undefined') {
el.attachEvent('on' + type, fn);
} else {
el['on' + type] = fn;
}
},
removeListener: function (el, type, fn) {
}
}; 我们来改进一下,首先我们要定义两个接口,一个用来add事件句柄,一个用来remove事件句柄,代码如下: var utils = {
addListener: null,
removeListener: null
}; 实现代码如下: if (typeof window.addEventListener === 'function') {
utils.addListener = function (el, type, fn) {
el.addEventListener(type, fn, false);
};
} else if (typeof document.attachEvent !== 'undefined') { // IE
utils.addListener = function (el, type, fn) {
el.attachEvent('on' + type, fn);
};
utils.removeListener = function (el, type, fn) {
el.detachEvent('on' + type, fn);
};
} else { // 其它旧浏览器
utils.addListener = function (el, type, fn) {
el['on' + type] = fn;
};
utils.removeListener = function (el, type, fn) {
el['on' + type] = null;
};
} 用起来,是不是就很方便了?代码也优雅多了。 自声明函数 一般是在函数内部,重写同名函数代码,比如: var scareMe = function () {
alert("Boo!");
scareMe = function () {
alert("Double boo!");
};
}; 这种代码,非常容易使人迷惑,我们先来看看例子的执行结果: // 1. 添加新属性
scareMe.property = "properly";
// 2. scareMe赋与一个新值
var prank = scareMe;
// 3. 作为一个方法调用
var spooky = {
boo: scareMe
};
// 使用新变量名称进行调用
prank(); // "Boo!"
prank(); // "Boo!"
console.log(prank.property); // "properly"
// 使用方法进行调用
spooky.boo(); // "Boo!"
spooky.boo(); // "Boo!"
console.log(spooky.boo.property); // "properly" 通过执行结果,可以发现,将定于的函数赋值与新变量(或内部方法),代码并不执行重载的scareMe代码,而如下例子则正好相反: // 使用自声明函数
scareMe(); // Double boo!
scareMe(); // Double boo!
console.log(scareMe.property); // undefined 大家使用这种模式时,一定要非常小心才行,否则实际结果很可能和你期望的结果不一样,当然你也可以利用这个特殊做一些特殊的操作。 内存优化 该模式主要是利用函数的属性特性来避免大量的重复计算。通常代码形式如下: var myFunc = function (param) {
if (!myFunc.cache[param]) {
var result = {};
// ... 复杂操作 ...
myFunc.cache[param] = result;
}
return myFunc.cache[param];
}; // cache 存储
myFunc.cache = {}; 但是上述代码有个问题,如果传入的参数是toString或者其它类似Object拥有的一些公用方法的话,就会出现问题,这时候就需要使用传说中的hasOwnProperty方法了,代码如下: var myFunc = function (param) {
if (!myFunc.cache.hasOwnProperty(param)) {
var result = {};
// ... 复杂操作 ...
myFunc.cache[param] = result;
}
return myFunc.cache[param];
}; // cache 存储
myFunc.cache = {}; 或者如果你传入的参数是多个的话,可以将这些参数通过JSON的stringify方法生产一个cachekey值进行存储,代码如下: var myFunc = function () {
var cachekey = JSON.stringify(Array.prototype.slice.call(arguments)),
result;
if (!myFunc.cache[cachekey]) {
result = {};
// ... 复杂操作 ...
myFunc.cache[cachekey] = result;
}
return myFunc.cache[cachekey];
}; // cache 存储
myFunc.cache = {}; 或者多个参数的话,也可以利用arguments.callee特性: var myFunc = function (param) {
var f = arguments.callee,
result;
if (!f.cache[param]) {
result = {};
// ... 复杂操作 ...
f.cache[param] = result;
}
return f.cache[param];
}; // cache 存储
myFunc.cache = {}; 总结 就不用总结了吧,大家仔细看代码就行咯 同步与推荐 本文已同步至目录索引:深入理解JavaScript系列 深入理解JavaScript系列文章,包括了原创,翻译,转载等各类型的文章,如果对你有用,请推荐支持一把,给大叔写作的动力。
深入理解JavaScript系列(50):Function模式(下篇)的更多相关文章
- 深入理解JavaScript系列(48):对象创建模式(下篇)
介绍 本篇主要是介绍创建对象方面的模式的下篇,利用各种技巧可以极大地避免了错误或者可以编写出非常精简的代码. 模式6:函数语法糖 函数语法糖是为一个对象快速添加方法(函数)的扩展,这个主要是利用pro ...
- 深入理解JavaScript系列(49):Function模式(上篇)
介绍 本篇主要是介绍Function方面使用的一些技巧(上篇),利用Function特性可以编写出很多非常有意思的代码,本篇主要包括:回调模式.配置对象.返回函数.分布程序.柯里化(Currying) ...
- 深入理解JavaScript系列(47):对象创建模式(上篇)
介绍 本篇主要是介绍创建对象方面的模式,利用各种技巧可以极大地避免了错误或者可以编写出非常精简的代码. 模式1:命名空间(namespace) 命名空间可以减少全局命名所需的数量,避免命名冲突或过度. ...
- 深入理解JavaScript系列(44):设计模式之桥接模式
介绍 桥接模式(Bridge)将抽象部分与它的实现部分分离,使它们都可以独立地变化. 正文 桥接模式最常用在事件监控上,先看一段代码: addEvent(element, 'click', getBe ...
- 深入理解JavaScript系列(31):设计模式之代理模式
介绍 代理,顾名思义就是帮助别人做事,GoF对代理模式的定义如下: 代理模式(Proxy),为其他对象提供一种代理以控制对这个对象的访问. 代理模式使得代理对象控制具体对象的引用.代理几乎可以是任何对 ...
- 深入理解JavaScript系列(33):设计模式之策略模式(转)
介绍 策略模式定义了算法家族,分别封装起来,让他们之间可以互相替换,此模式让算法的变化不会影响到使用算法的客户. 正文 在理解策略模式之前,我们先来一个例子,一般情况下,如果我们要做数据合法性验证,很 ...
- 深入理解JavaScript系列(46):代码复用模式(推荐篇)
介绍 本文介绍的四种代码复用模式都是最佳实践,推荐大家在编程的过程中使用. 模式1:原型继承 原型继承是让父对象作为子对象的原型,从而达到继承的目的: function object(o) { fun ...
- 深入理解JavaScript系列(45):代码复用模式(避免篇)
介绍 任何编程都提出代码复用,否则话每次开发一个新程序或者写一个新功能都要全新编写的话,那就歇菜了,但是代码复用也是有好要坏,接下来的两篇文章我们将针对代码复用来进行讨论,第一篇文避免篇,指的是要尽量 ...
- 深入理解JavaScript系列(42):设计模式之原型模式
介绍 原型模式(prototype)是指用原型实例指向创建对象的种类,并且通过拷贝这些原型创建新的对象. 正文 对于原型模式,我们可以利用JavaScript特有的原型继承特性去创建对象的方式,也就是 ...
随机推荐
- 创建 ASP.NET Web API的Help Page
转:创建WEBAPI项目 转:添加测试API中的ASP.NET Web API帮助页面
- QQ浏览器兼容模式下Cookie失效 导致的NetCore Cookie认证失效
最近在写NetCore项目采用的是NetCore的Cookie认证.结果偶然发现QQ浏览器登录不好用.这里先需要了解一下set-cookie中的SameSite属性 导致原因 首先Fiddler 4 ...
- 虚拟化 - Docker
Docker Desktop (for windows and mac) Docker Desktop 注意 安装时有可能卡主,可以关掉重新装 重启启动时,可能报错"VIRTUALIZATI ...
- 【RabbitMQ学习记录】- 消息队列存储机制源码分析
本文来自 网易云社区 . RabbitMQ在金融系统,OpenStack内部组件通信和通信领域应用广泛,它部署简单,管理界面内容丰富使用十分方便.笔者最近在研究RabbitMQ部署运维和代码架构,本篇 ...
- [ActionScript 3.0] PrintJob打印功能
package { import flash.display.Bitmap; import flash.display.Sprite; import flash.events.MouseEvent; ...
- 修复已损坏的交换机IMG
1.找出与当前交换机匹配的升级镜像以及合适的BOOT启动程序(这要通过渠道获取) 2.搭建 TFTP 服务器. 3.启动交换机,链接console线缆 4.在 BOOT 模式,完成一下操作 1.配置I ...
- Hibernate入门教程
Hibernate 随心所欲的使用面向对象思想操纵数据库. Table of contents 介绍 搭建开发环境 半sql半面向对象写法 完全的sql写法 完全的面向对象写法 Hibernate H ...
- python全栈开发_day4_if,while和for
一.if 1)if的用途 if常用于判断. 2)if的语法 tag=True tag2=True if tag: print("代码") elif tag2: print(&quo ...
- 浅析PHP反序列化漏洞之PHP常见魔术方法(一)
作为一个学习web安全的菜鸟,前段时间被人问到PHP反序列化相关的问题,以前的博客中是有这样一篇反序列化漏洞的利用文章的.但是好久过去了,好多的东西已经记得不是很清楚.所以这里尽可能写一篇详细点的文章 ...
- koa的中间件compose
用到的知识点: 1.bind函数 2.函数递归调用自身 3.promise 'use strict' /** * Expose compositor. */ module.exports = comp ...