面试的时候,总会被问到,你对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. Python3 randrange() 函数

    描述 randrange() 方法返回指定递增基数集合中的一个随机数,基数缺省值为1. 语法 以下是 randrange() 方法的语法: import random random.randrange ...

  2. (一)Servlet简介

    相关名词解释 HTML:Hyper Text Markup Language,超文本标记语言 HTTP:Hyper Text Transfer Protocol,超文本传输协议 URL:Uniform ...

  3. 各位情人节快乐, Python帮忙撒狗粮, 我连夜做了这个程序!

    阅读本文大概需要5分钟 码农的情人节 一年一度的情人节要来啦,这个浪漫温馨的节日,走在大街小巷,走在地铁里,走在商场里,走在电影院,姑娘们手里几乎都捧着一束花,心里都是乐滋滋的,一脸幸福的样子,忽然想 ...

  4. java8中stream的map和flatmap的理解

    转自https://blog.csdn.net/wynjauu/article/details/78741093 假如我们有这样一个需求给定单词列表["Hello","W ...

  5. go语言nsq源码解读七 lookup_protocol_v1.go

    本篇将解读nsqlookup处理tcp请求的核心代码文件lookup_protocol_v1.go. 1234567891011121314151617181920212223242526272829 ...

  6. 快照(Snapshot)技术发展综述

    快照(Snapshot)技术发展综述 刘爱贵 摘要:传统数据备份技术存在备份窗口.恢复时间目标RTO和恢复时间点RPO过长的问题,无法满足企业关键性业务的数据保护需求,因此产生了数据快照技术.本文对快 ...

  7. canvas实现俄罗斯方块

    好久没使用canvas了,于是通过写小游戏"俄罗斯方块"再次熟悉下canvas,如果有一定的canvas基础,要实现还是不难的.实际完成的Demo请看:canvas俄罗斯方块 . ...

  8. python3的socket使用

    如果需要设置两台机器的端口,请查看博文 centos7开放端口和防火墙设置 需要实现两台机器的信息交互,使用 socket 进行调度.其中服务端为: #!/usr/bin/env python # - ...

  9. 一致性 Hash 算法的实际应用

    前言 记得一年前分享过一篇<一致性 Hash 算法分析>,当时只是分析了这个算法的实现原理.解决了什么问题等. 但没有实际实现一个这样的算法,毕竟要加深印象还得自己撸一遍,于是本次就当前的 ...

  10. 【重学计算机】操作系统D1章:计算机操作系统概述

    1. 计算机软硬件系统 冯诺伊曼结构 以运算单元为核心,控制流由指令流产生 程序和数据存储在主存中 主存是按地址访问,线性编址 指令由操作码和地址码组成 数据以二进制编码 其他:参考<重学计算机 ...