API模式:回调模式、配置对象、返回函数;

  初始化模式:即时函数、即时对象初始化、初始化分支;

  性能模式:备忘模式、自定义模式

 //*********************** API模式 ***********************
/**
* ---------------------- 回调模式 ----------------------
*
* 1>要写出通用和可复用的代码,回调模式可以帮助实现这种通用化。
* 2>不需要预测和实现能想到的每一项功能,因为这样会迅速使我们的代码膨胀,
* 而绝大多数用户永远不会需要其中大量的功能。相反,可以专注于核心功能并提供“挂钩”形式的回调函数,
* 这会使我们很容易构建、扩展,以及自定义我们的方法。
*/
//方式一
var findNodes = function () {
var i = 10000,
nodes = [],
found;
while (i) {
i -= 1;
//这里是复杂的业务逻辑
nodes.push(found);
}
return nodes;
} var hide = function (nodes) {
for (var i = 0, len = nodes.length; i < len; i += 1) {
nodes[i].style.display = 'none';
}
} hide(findNodes()); //方式二
var findNodes = function (callback) {
var i = 10000,
nodes = [],
found;
while (i) {
i -= 1;
//这里是复杂的业务逻辑
if (typeof callback === 'function') {
callback(found);
}
nodes.push(found);
}
return nodes;
} var hide = function (node) {
node.style.display = 'none';
} findNodes(hide); //简洁点,将回调函数直接写在findNodes函数中
findNodes(function (node) {
node.style.display = 'block';
}) /**
* ---------------------- 配置对象模式 ----------------------
*
* 封装传递参数为一个对象,灵活了函数的调用方式,何乐而不为
*/
function addPerson(name, gender, age, address) {
//...
} //将参数封装
var conf = {
name: 'king',
gender: 'male',
age: 25,
address: 'xxxxxx'
}
addPerson(conf); //简写之
addPerson({
name: 'king',
gender: 'male',
age: 25,
address: 'xxxxxx'
}) /**
* ---------------------- 返回函数模式 ----------------------
*
* 函数里面返回函数,它创建了一个闭包,可以使用这个闭包存储一些私有数据,
* 而这些数据仅可被该返回函数访问,但外部代码却无法访问。
*/
var setup = function () {
var count = 0;
return function () {
return count++;
}
}
var next = setup();
next(); //
next(); //
next(); //
//*********************** 初始化模式 ***********************
/**
* ---------------------- 即时函数模式 ----------------------
*/
//文件module1.js中定义的模块module1
(function () {
//模块1的所有代码
})(); //文件module2.js中定义的模块module2
(function () {
//模块2的所有代码
})(); /**
* ---------------------- 即时对象初始化模式 ----------------------
*
* 这种模式的优点与即时函数模式的优点是相同的:可以在执行一次性的初始化任务时保护全局命名空间。、
* 与仅仅将一堆代码包装到匿名函数的方法相比。这种模式看起来设计更多的语法特征,
* 但是如果初始化任何更加复杂(它们也往往的确比较复杂),它会使整个初始化过程显得更有结构化。
* 其语法结构如下:
* ({...}).init();
* ({...}.init());
*/
({
name: 'king',
password: '123',
say: function () {
return 'I am ' + this.name + ', and my password is ' + this.password;
},
init: function () {
console.log(this.say());
}
/**
* 这种模式主要适用于一次性的任务,而且在init()完毕后也没有保存对该对象的访问。
* 如果想在init()完毕后保存对该对象的一个引用,可以通过在init()尾部添加"return this;"语句实现该功能。
*/
}).init(); //I am king, and my password is 123 /**
* ---------------------- 初始化时分支模式 ----------------------
*/
//每次调用utils.addListener()或utils.removeListener()时,都会重复地进行相同检查
var utils = {
addListener: function (elem, type, fn) {
if (typeof window.addEventListener === 'function') {
elem.addEventListener(type, fn, false);
} else if (typeof window.attachEvent === 'function') { //IE
elem.attachEvent('on' + type, fn);
} else {
elem['on' + type] = fn;
}
},
removeListener: function () {
if (typeof window.removeEventListener === 'function') {
elem.removeEventListener(type, fn, false);
} else if (typeof window.detachEvent === 'function') { //IE
elem.detachEvent('on' + type, fn);
} else {
elem['on' + type] = null;
}
}
} //采用分支
var utils = {
addListener: null,
removeListener: null
}
//分开嗅探浏览器特征,然后使用加载时分支仅执行一次嗅探
if (typeof window.addEventListener === 'function') {
utils.addListener = function (elem, type, fn) {
elem.addEventListener(type, fn, false);
};
utils.removeListener = function (elem, type, fn) {
elem.removeListener(type, fn, false);
};
} else if (typeof window.detachEvent === 'function') { //IE
utils.addListener = function (elem, type, fn) {
elem.attachEvent('on' + type, fn);
};
utils.removeListener = function (elem, type, fn) {
elem.detachEvent('on' + type, fn);
};
} else {
utils.addListener = function (elem, type, fn) {
elem['on' + type] = fn;
};
utils.removeListener = function (elem, type, fn) {
elem['on' + type] = null;
};
}
//*********************** 性能模式 ***********************
/**
* ---------------------- 备忘模式 ----------------------
*
* 使用函数属性以便使得计算过的值无须再次计算
*/
var myfunc = function (param) {
if (!myfunc.cache[param]) {
var result = {};
//...开销很大的操作...
myfunc.cache[param] = result;
}
return myfunc.cache[param];
}
//缓存存储
myfunc.cache = {}; /**
* ---------------------- 自定义函数模式 ----------------------
*
* 当函数有一些初始化准备工作要做,并且仅需要执行一次,那么这个模式就非常有用。
* 因为并没有任何理由去执行本可以避免的重复工作,即该函数的一些部门可能并不再需要。
* 在这种情况下,自定义函数可以更新自身的实现。使用此模式可以显著地帮助提升应用程序的性能,
* 这是由于重新定义的函数仅执行了更少的工作。
*/
var scareMe = function () {
alert('Boo!');
scareMe = function () {
alert('Double boo!');
};
} scareMe(); //Boo!
scareMe(); //Double boo!
scareMe(); //Double boo!

【读书笔记】读《JavaScript模式》 - JavaScript函数常用模式的更多相关文章

  1. 【读书笔记】读《JavaScript模式》 - 函数复用模式之现代继承模式

    现代继承模式可表述为:其他任何不需要以类的方式考虑得模式. 现代继承方式#1 —— 原型继承之无类继承模式 function object(o) { function F() {}; F.protot ...

  2. 《JavaScript高级程序设计》读书笔记--(1)JavaScript简介

    概述 JavaScript是一种直译式脚本语言,是一种动态类型.弱类型.基于原型的语言,内置支持类型.它的解释器被称为JavaScript引擎,为浏览器的一部分,广泛用于客户端的脚本语言,最早是在HT ...

  3. javascript创建对象之函数构造模式和原型模式结合使用(四)

    创建自定义类型的常见方式就是组合使用构造函数模式与原型模式一起使用. 构造函数模式用于定义实例对象的特有的部分(属性和方法),原型模式用于定义共享的部分. 这样最大限度的节省了内存的开销. funct ...

  4. 《CLR via C#》读书笔记(一)——CLR的执行模式

    前言 万事开头难,很早之前就想写博客记录些东西,迟迟未行动,甚是遗憾.原因诸多,大体上无非都是懒.没意志力等等.这次从自己的读书笔记开始,兴许能够有所改变. 一.CLR概念 CLR(Common La ...

  5. MDX Step by Step 读书笔记(七) - Performing Aggregation 聚合函数之 Max, Min, Count , DistinctCount 以及其它 TopCount, Generate

    MDX 中最大值和最小值 MDX 中最大值和最小值函数的语法和之前看到的 Sum 以及 Aggregate 等聚合函数基本上是一样的: Max( {Set} [, Expression]) Min( ...

  6. CSharp设计模式读书笔记(18):中介者模式(学习难度:★★★☆☆,使用频率:★★☆☆☆)

    中介者模式(Mediator Pattern):用一个中介对象(中介者)来封装一系列的对象交互,中介者使各对象不需要显式地相互引用,从而使其耦合松散,而且可以独立地改变它们之间的交互,中介者模式又称为 ...

  7. 【读书笔记】读《JavaScript模式》 - 函数复用模式之类式继承模式

    实现类式继承的目标是通过构造函数Child()获取来自于另外一个构造函数Parent()的属性,从而创建对象. 1.类式继承模式#1 —— 默认方式(原型指向父函数实例) function Paren ...

  8. 读书笔记(06) - 语法基础 - JavaScript高级程序设计

    写在开头 本篇是小红书笔记的第六篇,也许你会奇怪第六篇笔记才写语法基础,笔者是不是穿越了. 答案当然是没有,笔者在此分享自己的阅读心得,不少人翻书都是从头开始,结果永远就只在前几章. 对此,笔者换了随 ...

  9. 《JavaScript高级程序设计》读书笔记(一)JavaScript简介

    起于客户端数据验证特性----闭包----匿名函数----元编程等----等想要全面理解和掌握JavaScript----本质----历史----局限性 ECMAScript 脚本语言标准 JavaS ...

随机推荐

  1. webkit模块介绍

    一.Webkit模块   用到的第三方库如下:   cairo 一个2D绘图库 casqt Unicode处理用的库,从QT中抽取部分代码形成的 expat 一个XML SAX解析器的库 freety ...

  2. Protocol Buffer技术详解(语言规范)

    Protocol Buffer技术详解(语言规范) 该系列Blog的内容主体主要源自于Protocol Buffer的官方文档,而代码示例则抽取于当前正在开发的一个公司内部项目的Demo.这样做的目的 ...

  3. SQL injection

    SQL injection is a code injection technique, used to attack data-driven applications, in which malic ...

  4. C#中Delegate和Event以及它们的区别(转载)

    一.Delegate委托可以理解为一个方法签名. 可以将方法作为另外一个方法的参数带入其中进行运算.在C#中我们有三种方式去创建委托,分别如下: public delegate void Print( ...

  5. B/S C/S架构的界面测试

    网站是B/S架构的典型,从做网站的有限经验来整理一下B/S测试的基本要点,并把它与C/S进行区分. 与C/S相比,以下4个测试是除了常用测试外还要注意的: (1)链接测试 (2)表单测试 (3)脚本测 ...

  6. PHP array_intersect() 函数

    PHP Array 函数 定义和用法 array_intersect() 函数返回两个或多个数组的交集数组. 结果数组包含了所有在被比较数组中,也同时出现在所有其他参数数组中的值,键名保留不变. 注释 ...

  7. 转 Xenserver HVM is required for this operation的解决办法

    今天在XenServer中安装虚拟机时出现如下错误: 原因:没有开启XenServer服务器主机的虚拟化支持功能 解决办法:在XenServer主机的BIOS里开启CPU的虚拟化支持功能 本文出自 “ ...

  8. show slave各项参数解释

    how slave status 各个参数的解释 -- mysql 分类: mysql基础2012-08-23 11:03 2315人阅读 评论(0) 收藏 举报 服务器sslfilesqltable ...

  9. Tenth scrum meeting - 2015/11/4

    我们的项目开发已经渐渐进入了后期,每个模块都只剩下了一小块任务待做,同学们在做自己的模块的同时也开始对各个同学的模块进行合并. 其中最麻烦的就是视频播放模块与其他模块的合并了,由于该模块的实现需要添加 ...

  10. iOS开发——底层OC篇&运行时常用

    运行时常用 什么是Runtime(前面的文章已经说的很清楚了,这里就简单的介绍一下) 我们写的代码在程序运行过程中都会被转化成runtime的C代码执行,例如[target doSomething]; ...