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 ...
随机推荐
- PACKAGE-INFO.JAVA 作用及用法详解
转自http://strong-life-126-com.iteye.com/blog/806246 及http://blog.sina.com.cn/s/blog_93dc666c0101gzlr. ...
- buffer_pool.go
package nsqd import ( "bytes" "sync" ) var bp sync.Pool func init() { ...
- BZOJ_2738_矩阵乘法_整体二分
BZOJ_2738_矩阵乘法_整体二分 Description 给你一个N*N的矩阵,不用算矩阵乘法,但是每次询问一个子矩形的第K小数. Input 第一行两个数N,Q,表示矩阵大小和询问组数: 接下 ...
- HttpClient4 TIME_WAIT和CLOSE_WAIT
最近,公司的接口服务器(客户端,向外发送数据)频繁出现了connect timeout 以及readtime out 的情况,经过运维平台检测,并没有网络延时的情况.于是,开始怀疑连接池出了问题. 使 ...
- appium 提示报错“TypeError: 'unicode' object is not callable”的解决方式!
这里提到的这个报错,是小错误且容易经常会犯,有时需要特别注意使用. 目的要求结果:根据某个元素的id值获取到对应id的text值,并且将获取的text值与本身存在的text值做比较,查看text值是否 ...
- common-pool2连接池详解与使用
我们在服务器开发的过程中,往往会有一些对象,它的创建和初始化需要的时间比较长,比如数据库连接,网络IO,大数据对象等.在大量使用这些对象时,如果不采用一些技术优化,就会造成一些不可忽略的性能影响.一种 ...
- TensorFlow之RNN:堆叠RNN、LSTM、GRU及双向LSTM
RNN(Recurrent Neural Networks,循环神经网络)是一种具有短期记忆能力的神经网络模型,可以处理任意长度的序列,在自然语言处理中的应用非常广泛,比如机器翻译.文本生成.问答系统 ...
- Python学习笔记1 -- TypeError: 'str' object is not callable
Traceback (most recent call last): File "myfirstpython.py", line 39, in <module> pri ...
- 【STM32H7教程】第9章 STM32H7重要知识点数据类型,变量和堆栈
完整教程下载地址:http://forum.armfly.com/forum.php?mod=viewthread&tid=86980 第9章 STM32H7重要知识点数据类型,变量和堆栈 ...
- mybatis 增加热加载xml
由于在本地开发环境上每次修改mybatis xml文件都需要手动重启服务,调试的很麻烦,所以需要热加载xml文件来避免浪费时间,于是网上搜一下资料,看了下有一大堆,但试了下真正能跑起来没有(大都代码没 ...