面试的时候,总会被问到,你对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)(一)的更多相关文章

  1. javaScript设计模式之面向对象编程(object-oriented programming,OOP)(二)

    接上一篇 面向对象编程的理解? 答:面向对象编程,就是将你的需求抽象成一个对象,然后针对这个对象分析其特征(属性)与动作(方法).这个对象我们称之为类.面向对象编程思想其中一个特点就是封装,就是把你需 ...

  2. python, 面向对象编程Object Oriented Programming(OOP)

    把对象作为程序的基本单元,一个对象包含了数据和操作数据的函数. 面向过程的程序设计把计算机程序视为一系列的命令集合,即一组函数的顺序执行.为了简化程序设计,面向过程把函数继续切分为子函数,即把大块函数 ...

  3. javaScript设计模式之面向对象编程(object-oriented programming,OOP)--寄生组合式继承

    组合式继承:将类式继承同构造函数继承组合使用,但是存在一个问题,子类不是父类的实例,而子类的原型式父类的实例,所以才有了寄生组合式继承. 意思就是说,寄生就是寄生式继承,寄生式继承就是依托于原型继承, ...

  4. Python学习札记(三十) 面向对象编程 Object Oriented Program 1

    参考:OOP NOTE 1.面向对象编程--Object Oriented Programming,简称OOP,是一种程序设计思想.OOP把对象作为程序的基本单元,一个对象包含了数据和操作数据的函数. ...

  5. Python学习札记(四十) 面向对象编程 Object Oriented Program 11

    参考:使用元类 NOTE: type() 1.type()函数可以用于检查一个类或者变量的类型. #!/usr/bin/env python3 class Myclass(object): " ...

  6. Python学习札记(三十八) 面向对象编程 Object Oriented Program 9

    参考:多重继承 NOTE #!/usr/bin/env python3 class Animal(object): def __init__(self, name): self.name = name ...

  7. Python学习札记(三十七) 面向对象编程 Object Oriented Program 8 @property

    参考:@property NOTE 1.在绑定参数时,为了避免对属性不符合逻辑的操作,需要对传入的参数进行审核. #!/usr/bin/env python3 class MyClass(object ...

  8. Python学习札记(三十六) 面向对象编程 Object Oriented Program 7 __slots__

    参考:slots NOTE 1.动态语言灵活绑定属性及方法. #!/usr/bin/env python3 class MyClass(object): def __init__(self): pas ...

  9. Python学习札记(三十五) 面向对象编程 Object Oriented Program 6

    参考:实例属性和类属性 NOTE Python是动态语言,根据类创建的实例可以任意绑定属性. class Student(object): def __init__(self, name): self ...

随机推荐

  1. JAVAEE——Mybatis第二天:输入和输出映射、动态sql、关联查询、Mybatis整合spring、Mybatis逆向工程

    1. 学习计划 1.输入映射和输出映射 a) 输入参数映射 b) 返回值映射 2.动态sql a) If标签 b) Where标签 c) Sql片段 d) Foreach标签 3.关联查询 a) 一对 ...

  2. Java 读书笔记 (六) 引用类型

    Java里使用long类型的数据要在数值后面加上L,否则会作为整型解析. 引用类型 引用类型是一个对象类型,它的值是指向内存空间的引用,就是地址, 所指向的内存中保存着变量所表示的一个值或一组值. i ...

  3. 「SDOI2018」物理实验

    题目大意: 这题不好描述,直接看原题吧…… 题解: 很无脑的题……就是卡精度+难写.代码能力还是太差了. 其实可以直接用long double肝过去.但我的代码似乎太丑了,以至于跑得奇慢无比. 代码: ...

  4. 【k短路&A*算法】BZOJ1975: [Sdoi2010]魔法猪学院

    Description 找出1~k短路的长度.   Solution k短路的求解要用到A*算法 A*算法的启发式函数f(n)=g(n)+h(n) g(n)是状态空间中搜索到n所花的实际代价 h(n) ...

  5. Android代码混淆的问题解决(java.io.FileNotFoundException)

    Android Studio(2.3.3) 在给代码混淆时,提示: Warning:Exception while processing task java.io.FileNotFoundExcept ...

  6. Typora + Mathpix Snip,相见恨晚的神器

    word 文档虽然很好,但当我需要输入一大堆公式的时候,word 公式让我疯狂. Why markdown?首先,GitHub 上都在用,那我也得会吧,不然 README.md 怎么写:其次,mark ...

  7. SpringCloud分布式微服务搭建(一)

    本例子主要使用了eureka集群作为注册中心来保证高可用,客户端来做ribbon服务提供者的负载均衡. 负载均衡有两种,第一种是nginx,F5这种集中式的LB,对所有的访问按照某种策略分发. 第二种 ...

  8. Java:并发不易,先学会用

    我从事Java编程已经11年了,绝对是个老兵:但对于Java并发编程,我只能算是个新兵蛋子.我说这话估计要遭到某些高手的冷嘲热讽,但我并不感到害怕. 因为我知道,每年都会有很多很多的新人要加入Java ...

  9. sau交流学习社区--看小说的lovebook一个无线端BS应用

    一.前言 loveBook爱上阅读,是一款webapp的读小说等书籍的并且阅读的应用.如果觉得可以,欢迎fork和star. 自己最近在追斗破苍穹电视剧,下班时候在地铁上总听到有人说,斗破苍穹书籍比电 ...

  10. 【Python3爬虫】用Python中的队列来写爬虫

    一.写在前面 当你看着你的博客的阅读量慢慢增加的时候,内心不禁有了些小激动,但是不得不吐槽一下--博客园并不会显示你的博客的总阅读量是多少.而这一篇博客就将教你怎么利用队列这种结构来编写爬虫,最终获取 ...