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 ...
随机推荐
- java面向对象中四种权限(private,protected,public,友好型)详解
转自http://blog.csdn.net/a1237871112/article/details/50926975 及http://blog.csdn.net/blackmanren/articl ...
- 比较集合List<T>集合,前后多了哪些数据,少了哪些数据Except
1.少了哪些数据 private List<int> GetRoleIdListReduce(List<int> roleIdListOld, List<int> ...
- BZOJ_1798_[AHOI2009]维护序列_线段树
BZOJ_1798_[AHOI2009]维护序列_线段树 题意:老师交给小可可一个维护数列的任务,现在小可可希望你来帮他完成. 有长为N的数列,不妨设为a1,a2,…,aN .有如下三种操作形式: ( ...
- BZOJ_1334_[Baltic2008]Elect_DP+语文题
BZOJ_1334_[Baltic2008]Elect_DP Description N个政党要组成一个联合内阁,每个党都有自己的席位数. 现在希望你找出一种方案,你选中的党的席位数要大于 总数的一半 ...
- 再谈async与await
回顾C#5.0是如何进行异步编程的 static void Main(string[] args) { string url = "https://docs.microsoft.com/zh ...
- JavaWeb学习总结(转载)
JavaWeb学习总结(五十三)--Web应用中使用JavaMail发送邮件 JavaWeb学习总结(五十二)--使用JavaMail创建邮件和发送邮件 JavaWeb学习总结(五十 ...
- 【SAP S/4 1511之变】:主数据之变
本博文主要讲述SAP S/4 1511版本的变化,主要是跟ECC版本的对比.变化还是挺多的,相当一部分是后勤,但绝大部分还是财务成本这一块.作为从事S/4版本的从业者,了解1511版本的变化还是挺有必 ...
- 基于Unity的AR开发初探:第一个AR应用程序
记得2014年曾经写过一个Unity3D的游戏开发初探系列,收获了很多好评和鼓励,不过自那之后再也没有用过Unity,因为没有相关的需求让我能用到.目前公司有一个App开发的需求,想要融合一下AR到A ...
- 新手学习WEB前端流程以及学习中常见的误区
学习web前端编程技术肯定是以就业拿到高薪工作为主要目的的,可是高薪不会那么轻易拿到,这是一个最简单的道理.没有付出就没有回报,在整个学习web前端编程技术的过程中,你需要付出时间.精力.金钱.废话不 ...
- 解决Error:All flavors must now belong to a named flavor dimension. Learn more at...
低版本的gradle里面不会出现这个错误,高版本出现,不多说,看如何解决 在defaultConfig{}中添加:flavorDimensions "default" 保证所有的f ...