javascript设计模式 第一章 灵活的javascript
javascript 设计模式
第1章 灵活的语言--JavaScript
初级程序员接到一个验证表单功能的任务,需要验证用户名、邮箱、密码等
** 此文章内容大部分来自 《javascript设计模式》一书,请支持正版。**
1.简单的验证check.js
代码如下:
function checkName(){
//验证姓名
}
function checkEmail(){
//验证邮箱
}
function checkPassword(){
//验证密码
}
这段代码功能可以实现,但是创建了3个全局变量,这就增加了代码的脆弱性。可能在的check.js文件中只有这3个变量。如果你引入了别人的类库,或者你的这个js文件给别人使用的话,就增加了全局变量被覆盖的可能。可能你覆盖别人的也可能别人覆盖你的功能。
2.函数的另一种形式
代码如下:
var checkName = function(){
//验证姓名
}
var checkEmail = function(){
//验证邮箱
}
var checkPassword = function(){
//验证密码
}
这种方式多了个变量提升,但是并未改变创建了3个全局变量的问题。
3.用对象收编变量
代码如下:
var CheckObject = {
checkName:function(){
//验证姓名
},
checkEmail:function(){
//验证邮箱
},
checkPassword:function(){
//验证密码
}
}
这种对象收编方式大大减少了对象被覆盖的问题,使用直接CheckObject.checkName()
点的方式就可以。
4.对象的另一种形式
var CheckObject = function(){}
CheckObject.checkName = function(){
//验证姓名
}
checkObject.CheckEmail = function(){
//验证邮箱
}
checkObject.checkPassword = function(){
//验证密码
}
3和4的这两种方式还会有问题,当别人想用你写的对象方法时就会有些麻烦了,因为这个对象不能复制一份,或者说这个对象类在用new
关键字创建新的对象时,新创建的对象是不能继承这些方法。
举个列子:
A同事写了个获取用户名的操作,B同事感觉默认名字“张三”不合适,他想改为其他的。因为对象只有一份B这样修改后其他任何人再此使用都可能为“李四”。也就是说很容易覆盖一个公共的方法。
//获取用户名
var MyMethod = {
getDefaultName:function(){
var defaultName = '张三';
return defaultName;
},
}
MyMethod.getDefaultName();//张三
//B同事修改了MyMethod
MyMethod.getDefaultName = function(){
var defaultName = '李四';
return defaultName;
}
MyMethod.getDefaultName();//李四
5.真假对象
var CheckObject = function(){
return {
checkName:function(){
//验证姓名
},
checkEmail:function(){
//验证邮箱
},
checkPassword:function(){
//验证密码
}
}
}
这段代码简单的复制了一遍对象,每次调用函数的时候,把之前的那个对象返回出来,当别人每次调用这个函数时都返回了一个全新的对象。如:
var a = CheckObject();
a.checkEmail();
其实他不是一个真正意义上类的创建方式,并且创建的对象a
和对象CheckObject
没有任何关系,返回出来的对象本身就与CheckObject
对象无关。
6.类
var CheckObject = function(){
this.checkName = function(){
//验证姓名
}
this.checkEmail = function(){
//验证邮箱
}
this.checkPassword = function(){
//验证密码
}
}
var a = new CheckObject();
a.checkEmail();
这样可以看成一个类,每一次通过new
关键字创建新对象的时候,新创建的对象都会对类的this
上的属性进行复制,这些新创建的对象都会有自己的一套方法,但是这么做造成了消耗是很奢侈的,因为每次创建new
的时候都会复制CheckObject
里面所有的方法。
7.一个检测类
var CheckObject = function(){}
CheckObject.prototype.checkName = function(){
//验证姓名
}
CheckObject.prototype.checkEmail = function(){
//验证邮箱
}
CheckObject.prototype.checkPassword = function(){
//验证密码
}
或
var CheckObject = function(){}
CheckObject.prototype = {
constructor:CheckObject,
checkName:function(){
//验证姓名
},
checkEmail:function(){
//验证邮箱
},
checkPassword:function(){
//验证密码
}
}
使用它们:
var a = new CheckObject();
a.checkName();
a.checkEmail();
a.checkPassword();
这样创建对象实例的时候,创建出来的对象所拥有的方法就是一个了,因为它们都要依赖 prototype
原型依次寻找,而找到的方法都是同一个,它们都绑定在CheckObject
对象类的原型上。
8.方法还可以这样用
上面代码可以看出来多次使用a
这时候我们可以想到链接调用,在每个方法的末尾处将当前的对象返回。
var CheckObject = function(){}
CheckObject.prototype = {
constructor:CheckObject,
checkName:function(){
//验证姓名
return this;
},
checkEmail:function(){
//验证邮箱
return this;
},
checkPassword:function(){
//验证密码
return this;
}
}
使用它们:
var a = new CheckObject();
a.checkName().checkEmail().checkPassword();
9.函数的祖先
模仿prototype.js
的作法为每一个函数添加一个检测邮箱的方法可以这么做。
Function.prototype.checkEmail = function(){
//验证邮箱
}
使用方式:
var f = function(){};
f.checkEmail();
// 或者使用类的方式
var f= new Function();
f.checkEmial();
这样做的弊端是污染了原生对象Function,别人创建的函数也会被创建checkEmail
,造成不必要的开销。使用下面的这种方式:
Function.prototype.addMethod = function(name,fn){
this[name] = fn;
}
使用方式:
var methods = function(){}
//或者
var methods = new Function();
methods.addMethod('checkName',funciton(){
//验证姓名
});
methods.addMethod('checkEmail',funciton(){
//验证邮箱
});
methods.checkName();
methods.checkEmail();
10.同样添加链式
Function.prototype.addMethod = function(){
this[name] = fn;
return this;
}
这样添加方法就方便了一些
var methods = new Function();
methods.addMethod('checkName',funciton(){
//验证姓名
}).addMethod('checkEmail',funciton(){
//验证邮箱
});
同时被添加的每个方法也可以做链式返回
var methods = new Function();
methods.addMethod('checkName',funciton(){
//验证姓名
return this;
}).addMethod('checkEmail',funciton(){
//验证邮箱
return this;
});
methods.checkName().checkEmail();
11.使用类的方式来实现
上面是函数式调用,对于习惯类式调用的方法如下:
Function.prototype.addMethod = function(){
this.prototype[name] = fn;
return this;
}
使用方式:
var methods = function(){}:
methods.addMethod('checkName',funciton(){
//验证姓名
return this;
}).addMethod('checkEmail',funciton(){
//验证邮箱
return this;
});
这里注意。methods
不能直接点出来使用,而是要通过new
关键字来创建新对象。
var m = new Methods();
m.checkEmail();
javascript设计模式 第一章 灵活的javascript的更多相关文章
- 你不知道的javaScript上卷(第一章 作用域是什么)
在写这篇博客时这本书我已经是看过一遍了,为了加深印象和深入学习于是打算做这系列的前端经典书籍导读博文,大家如果觉得这本书讲的好可以自己买来看看,我是比较喜欢看纸质版书的,因为这样才有读书的那种感觉. ...
- [head first 设计模式] 第一章 策略模式
[head first 设计模式] 第一章 策略模式 让我们先从一个简单的鸭子模拟器开始讲起. 假设有个简单的鸭子模拟器,游戏中会出现各种鸭子,此系统的原始设计如下,设计了一个鸭子超类,并让各种鸭子继 ...
- 读《编写可维护的JavaScript》第一章总结
第一章 基本的格式化 1.4 ① 换行 当一行长度到达了单行最大的字符限制时,就需要手动将一行拆成俩行.通常我们会在运算符后换行,下一行会增加俩个层级的缩进. // 好的做法: 在运算符后换行,第二行 ...
- 读高性能JavaScript编程 第一章
草草的看完第一章,虽然看的是译文也是感觉涨姿势了, 我来总结一下: 由于 大多数浏览器都是 single process 处理 ui updatas and js execute 于是产生问题: js ...
- Effective JavaScript :第一章
第一章 一.严格模式与非严格模式 1.在程序中启用严格模式的方式是在程序的最开始增加一个特定的字符串字面量: ‘use strict’ 同样可以在函数体的开始处加入这句指令以启用该函数的严格模式. f ...
- JavaScript设计模式基础之面向对象的JavaScript(一)
动态语言类型与鸭子类型 此内容取自JavaScript设计模式与开发实践一书 编程语言按照数据类型大体可以分为2类,一类就是静态类型语言,另一类则是动态类型语言 静态类型语言也可以称之为编译语言,而动 ...
- 【设计模式+原型理解】第一章:使用Javascript来巧妙实现经典的设计模式
刚开始学习设计模式之前,我是没想说要学习设计模式的,我只是因为想学习JS中的原型prototype知识,一开始我想JS中为什么要存在原型这个东西?于是慢慢通过原型而接触到设计模式,后来发现我这个过程是 ...
- (第一章)改善JavaScript,编写高质量代码。
根据<编写高质量代码改善JavaScript程序的188个建议>这本书,来记录我目前所了解的建议方式. 建议1:警惕Unicode乱码 根据ECMA标准规定JavaScript语言可以使用 ...
- head first 设计模式第一章笔记
设计模式是告诉我们如何组织类和对象以解决某种问题. 学习设计模式,也就是学习其他开发人员的经验与智慧,解决遇到的相同的问题. 使用模式的最好方式是:把模式装进脑子,然后在设计的时候,寻找何处可以使用它 ...
随机推荐
- java 线程 join(wait) 后,是如何唤醒
概要:锁是线程,锁对象执行完毕后,会调用自身对象上的notify(); Join 方法:本质上还是根据wait方法实现的.分析join源码发现join方法本身是使用了synchronized修饰符的. ...
- bzoj1257 数学整理二分查询
2013-11-15 21:55 原题传送门http://www.lydsy.com/JudgeOnline/problem.php?id=1257 要求求sigma k mod i(i<=n) ...
- C# 正则表达式判断IP,URL等及其解释
C# 正则表达式判断IP,URL等及其解释 判断IP格式方法: public static bool ValidateIPAddress(string ipAddress) { Regex valid ...
- mySQL的存储过程详解
mysql存储过程详解 1. 存储过程简介 我们常用的操作数据库语言SQL语句在执行的时候需要要先编译,然后执行,而存储过程(Stored Procedure)是一组为了完成特定功能的S ...
- 华为MateBook笔记本对比微软Surface Pro 4,谁更好?
继上网本.超极本等概念之后,变形本和二合一设备逐渐升温,今年终于整体爆发,继苹果的iPad Pro.微软的Surface Pro 4之后,华为推出了自己的第一部电脑产品同时也是二合一设备的华为Mate ...
- 超越IEtab、网银支付助手,无需再次登陆的Firefox的IE插件
强烈推荐! fire-ie最大亮点就是:可以传递firefox下的cookie,从而避免了再次登陆或打开支付页面的繁琐. 在线安装:https://addons.mozilla.org/zh-CN/f ...
- c# 使用ssh连接远程主机(ssh.net演示)
本教程使用的是ssh.net这个库.项目地址:https://github.com/sshnet/SSH.NET 使用ssh客户端连接远程主机执行命令,并拿到输出结果: using (var sshC ...
- 使用base64对图片的二进制进行编码,使其可以利用ajax进行显示
有时候我们需要动态的将图片的二进制在页面上进行显示,如我们需要弄一个验证码的功能,那么如果我们的验证码的图片在后台得到的是该图片的二进制,那么当我们需要在页面上点击一个按钮利用ajax进行切换的时候, ...
- Django CRM查询(一对多,多对多以及相关的反查)
Customer模型: class Customer(models.Model): name = models.CharField(max_length=32) qq = models.CharFie ...
- hdu6191(树上启发式合并)
hdu6191 题意 给你一棵带点权的树,每次查询 \(u\) 和 \(x\) ,求以 \(u\) 为根结点的子树上的结点与 \(x\) 异或后最大的结果. 分析 看到子树,直接上树上启发式合并,看到 ...