javaScript设计模式之面向对象编程(object-oriented programming,OOP)(一)
面试的时候,总会被问到,你对javascript面向对象的理解?
面向对象编程(object-oriented programming,OOP)是一种程序设计范型。它讲对象作为程序的设计基本单元,讲程序和数据封装其中,以提高程序的重用性、灵活性和扩展性。
一、举个例子
有这么一个需求:做一个验证表单功能,仅需要验证用户名,邮箱,密码等
觉得在项目产品开发中,自己是这么写的
function checkName(){
//验证姓名
}
function checkEmail(){
//验证邮箱
}
function checkPassword(){
//验证码密码
}
声明了3个全局变量,
下面是创建3个函数保存在变量里来实现你的功能,而你写的是将你的变量名放在function后边,也代表了你的变量,所以声明了3个全局变量。
//创建了3个函数保存在变量里
var checkName = function(){
//验证姓名
}
var checkEmail = function(){
//验证码邮箱
}
var checkPassword = function(){
//验证密码
}
从功能上讲没有任何问题,但是如果别人也定义了同样的方法就会覆盖原有的功能,这种相互覆盖的问题不易觉察到。
我们可以将这些检查函数放在一个变量里保存,这样减少覆盖和被覆盖的风险。
(1)用对象收编变量
对象,他有属性和方法,我们访问属性或者方法,可以通过点语法向下遍历查询得到,我们可以创建一个检测对象,我们把方法放在里面。
var CheckObject = {
checkName:function(){
//验证姓名
},
checkEmail:function(){
//验证邮箱
},
checkPassword:function(){
//验证密码
}
}
这个时候我们将所有的函数作为CheckObject对象的方法,这样我们就只有一个对象,比如检测姓名CheckObject.checkName().
(2)对象的另一种形式
首先声明一个对象,然后给他添加方法,在JavaScript中函数也是对象。
var CheckObject = function(){};
CheckObject.checkName = function(){
//验证姓名
}
CheckObject.checkEmail = function(){
//验证邮箱
}
CheckObject.checkPassword = function(){
//验证密码
}
但是当别人想用你写的对象方法就比较麻烦,因为这个对象不能复制一份(这个对象类在用new关键字创建新的对象时,新创建的对象时不能继承这些方法)
(3)真假对象
如果想简单的复制一下,你可以将这些方法放在一个函数对象中。
var CheckObject = function(){
return {
checkName = function(){
//校验姓名
},
checkEmail = function(){
//校验邮箱
}
checkPassword = function(){
//校验密码
}
}
}
当每次调用这个函数的时候,把我们之前的对象返回出来,当别人每次调用这个函数时都会返回新对象。这样我们每个人使用的时候就不会相互影响,比如检测邮箱可以这样:
var a = CheckObject();
a.checkEmail();
(4)类也可以
虽然通过创建新对象完成需求,但是他不是一个真正的意义上的类的创建方式,并且创建对象a和对象CheckObject没有任何关系,返回的对象与CheckObject对象无关,稍微优化一下。
var CheckObject = function(){
this.checkName = function(){
//验证姓名
}
this.checkEmail = function(){
//验证邮箱
}
this.checkPassword = function(){
//验证密码
}
}
上面的这样的对象,就可以看成是类,我们就可以不需要使用创建对象方法创建,既然是一个类,就用关键词new来创建
var a = new CheckObject();
a.checkEmail();
这样就可以用CheckObject类创建出来对象,我们其他人就可以对类实例化(用类创建对象),这样每一个人都有一套自己的方法。
(5)一个检测类
通过this的定义,每一次通过new关键字创建新对象时候,新创建的对象都会对类的this上的属性进行复制,所以新创建的对象都会有自己的一套方法,然而有时候造成消耗很奢侈,我们需要处理一下。
var CheckObject = function(){};
CheckObject.prototype.checkName = function(){
//验证姓名
}
CheckObject.prototype.checkEmail = function(){
//验证邮箱
}
CheckObject.prototype.checkPassword = function(){
//验证密码
}
这样创建对象实例时候,创建出来的对象所拥有的方法都是一个,因为他们需要依赖prototype原型依次寻找,而找到方法是同一个,但是prototype写很多遍,可以这么写
var CheckObject = function(){};
checkObject.prototype = {
checkName:function(){
//验证姓名
},
checkEmail:function(){
//验证邮箱
},
checkPassword:function(){
//验证密码
}
}
以上两种方法不能混着用。
如在后边为对象的原型对象赋值新对象,那么会覆盖之前对prototype对象赋值的方法。
var a = new CheckObject();
a.checkName();
a.checkEmail();
a.checkPassword();
(6)方法还可以这样用
1、this对象
var CheckObject = {
checkName:function(){
//验证姓名
return this;
},
checkEmail:function(){
//验证邮箱
return this;
},
checkPassword:function(){
//验证密码
return this;
}
}
使用:
CheckObject.checkName().checkEmail().checkPassword();
2、类的原型对象
var CheckObject = function(){};
CheckObject.prototype = {
checkName:function(){
//验证姓名
return this;
},
checkEmail:function(){
//验证邮箱
return this;
},
checkPassword:function(){
//验证密码
return this;
}
}
但是使用的时候需要创建一下
var a = new CheckObject();
a.checkName().checkEmail().checkPassword();
(7)函数祖先
比如你想给每一个函数都添加一个检测邮箱的方法。
Function.prototype.checkEmail = function(){
//检测邮箱
}
这样使用这个方法就比较简单,
1、函数形式
var f = function(){};
f.checkEmail();
2、类的形式
var f = new Function();
f.checkEmail();
你这种方式,原则上没有问题,但是污染了全局原生对象Function,这样别人创建的函数也会被你创建的函数污染,造成不必要的开销,但是你可以抽象出一个统一添加方法的功能方法。方法如下:
Function.prototype.addMethod = function(name,fn){
this[name] = fn;
}
这个时候,如果你想添加邮箱验证的方法和姓名验证的方法,可以这样使用
var methods = function(){};
//或者
var methods = new Function();
methods.addMethod('checkName',function(){
//验证姓名
})
methods.addMethod('checkEmail',function(){
//验证邮箱
})
methods.checkName();
methods.checkEmail();
(8)链式添加
如果想链式添加,在addMethods中将this返回,就可以
Function.prototype.addMethod = function(name,fn){
this[name] = fn;
return this;
}
如果你还想添加方法,可以这样:
var methods = function(){};
methods.addMethod('checkName',function(){
//验证姓名
}).addMethod('checkEmail',function(){
//验证邮箱
});
如果我想链式使用,应该如何实现?
既然添加方法可以将this返回实现,那么添加的每一个方法都将this返回是不是也就实现了呢?
var methods = function(){};
methods.addMethod('checkName',function(){
//验证姓名
return this;
}).addMethod('checkEmail',function(){
//验证邮箱
return this;
})
测试一下:
methods.checkName().checkEmail();
(9)换一种使用方式
1、函数式调用
Function.prototype.addMethod = function(name,fn){
this[name] = fn;
return this;
}
2、类式调用
Function.prototype.addMethod = function(name,fn){
this.prototype[name] = fn;
return this;
}
使用类式调用,不能直接使用,需要通过new关键字来创建新对象
var m = new Methods();
m.checkEmail();
JavaScript中函数时一等公民。
1、如何实现方法的链式调用?
只需在类中的每个方法中通过this关键字返回对象实例的引用。每次函数调用都会返回一个新对象,表面上是CheckObject对象,实际是返回的新对象,这样每次调用就不会相互影响了。
2、为函数添加多个方法的addMethod方法?
(1)this对象
var CheckObject = {
checkName: function(){
//验证姓名
return this;
} ,
checkEmail: function(){
//验证邮箱
return this;
} ,
checkPassword: function(){
//验证密码
return this;
} ,
}
(2)类的原型对象
var CheckObject = function(){};
CheckObject.prototype = {
checkName:function(){
//验证姓名
return this;
} ,
checkEmail:function(){
//验证邮箱
return this;
},
checkPassword:function(){
//验证密码
return this;
}
}
javaScript设计模式之面向对象编程(object-oriented programming,OOP)(一)的更多相关文章
- javaScript设计模式之面向对象编程(object-oriented programming,OOP)(二)
接上一篇 面向对象编程的理解? 答:面向对象编程,就是将你的需求抽象成一个对象,然后针对这个对象分析其特征(属性)与动作(方法).这个对象我们称之为类.面向对象编程思想其中一个特点就是封装,就是把你需 ...
- python, 面向对象编程Object Oriented Programming(OOP)
把对象作为程序的基本单元,一个对象包含了数据和操作数据的函数. 面向过程的程序设计把计算机程序视为一系列的命令集合,即一组函数的顺序执行.为了简化程序设计,面向过程把函数继续切分为子函数,即把大块函数 ...
- javaScript设计模式之面向对象编程(object-oriented programming,OOP)--寄生组合式继承
组合式继承:将类式继承同构造函数继承组合使用,但是存在一个问题,子类不是父类的实例,而子类的原型式父类的实例,所以才有了寄生组合式继承. 意思就是说,寄生就是寄生式继承,寄生式继承就是依托于原型继承, ...
- Python学习札记(三十) 面向对象编程 Object Oriented Program 1
参考:OOP NOTE 1.面向对象编程--Object Oriented Programming,简称OOP,是一种程序设计思想.OOP把对象作为程序的基本单元,一个对象包含了数据和操作数据的函数. ...
- Python学习札记(四十) 面向对象编程 Object Oriented Program 11
参考:使用元类 NOTE: type() 1.type()函数可以用于检查一个类或者变量的类型. #!/usr/bin/env python3 class Myclass(object): " ...
- Python学习札记(三十八) 面向对象编程 Object Oriented Program 9
参考:多重继承 NOTE #!/usr/bin/env python3 class Animal(object): def __init__(self, name): self.name = name ...
- Python学习札记(三十七) 面向对象编程 Object Oriented Program 8 @property
参考:@property NOTE 1.在绑定参数时,为了避免对属性不符合逻辑的操作,需要对传入的参数进行审核. #!/usr/bin/env python3 class MyClass(object ...
- Python学习札记(三十六) 面向对象编程 Object Oriented Program 7 __slots__
参考:slots NOTE 1.动态语言灵活绑定属性及方法. #!/usr/bin/env python3 class MyClass(object): def __init__(self): pas ...
- Python学习札记(三十五) 面向对象编程 Object Oriented Program 6
参考:实例属性和类属性 NOTE Python是动态语言,根据类创建的实例可以任意绑定属性. class Student(object): def __init__(self, name): self ...
随机推荐
- indexer_worker.go
package) ) ) ) { request.rankerReturnChannel <- rankerReturnRequest{} con ...
- loj548 「LibreOJ β Round #7」某少女附中的体育课
这道题好神啊!!! 发现这题就是定义了一种新的卷积,然后做k+1次卷积. 这里我们就考虑构造一个变换T,使得$T(a) \cdot T(b) =T(a∘b)$,这里是让向量右乘这个转移矩阵. 于是我们 ...
- BZOJ_1251_序列终结者
BZOJ_1251_序列终结者 [问题描述] 给定一个长度为N的序列,每个序列的元素是一个整数(废话).要支持以下三种操作: 1. 将[L,R]这个区间内的所有数加上V. 2. 将[L,R]这个区间翻 ...
- Android--APP性能测试工具GT的使用总结
GT(随身调)是APP的随身调测平台,它是直接运行在手机上的"集成调测环境"(IDTE, Integrated Debug Environment).利用GT,仅凭一部手机,无需连 ...
- 读书笔记--Android Gradle权威指南(下)
前言 最近看了一本书<Android Gradle 权威指南>,收获挺多,就想着来记录一些读书笔记,方便后续查阅. 本篇内容是基于上一篇:读书笔记--Android Gradle权威指南( ...
- 如何优雅地在 Spring Boot 中使用自定义注解,AOP 切面统一打印出入参日志 | 修订版
欢迎关注个人微信公众号: 小哈学Java, 文末分享阿里 P8 资深架构师吐血总结的 <Java 核心知识整理&面试.pdf>资源链接!! 个人网站: https://www.ex ...
- MediatR 知多少
引言 首先不用查字典了,词典查无此词.猜测是作者笔误将Mediator写成MediatR了.废话少说,转入正题. 先来简单了解下这个开源项目MediatR(作者Jimmy Bogard,也是开源项目A ...
- JS 图片放大镜
今天练习一个小demo, 从本地读取图片, 然后实现类似淘宝放大镜的效果, 再加两个需求 1 .可以调节缩放比例,默认放大两倍 2 . 图片宽高自适应, 不固定宽高 话不多说先看效果: 原理:1, 右 ...
- redis一致性hash算法理解
一般算法: 对对象先hash然后对redis数量取模,如果结果是0就存在0的节点上. 1.2同上,假设有0-3四个redis节点.20个数据: 进行取模后分布如下: 现在因为压力过大需要扩容,增加一台 ...
- 约定Jenkins构建脚本
对于Jenkins的使用,我感觉只用到其中一小部分功能,但也就是这一小部分功能,也推动了整个CI/CD的过程,Jenkins的使用方式有很多中,可能我用到的只是其中一种,但是已经满足我的需求,便不再贪 ...