JavaScript 类的封装操作示例详解


Posted in Javascript onMay 16, 2020

本文实例讲述了JavaScript 类的封装操作。分享给大家供大家参考,具体如下:

一,首先,为什么要使用封装?

这是从信息的角度出发的,信息的隐藏是最终的目的,而封装只不过是实现隐藏的一种方法。

这里我们需要明白一点就是:类的定义有如下的三种方式:

(第一种)门户大开型方式       (第二种)用命令规范区别私有和公有的方式    (第三种)闭包

现在详细描述一下每一种类的定义方式:

针对第一种,门户大开类型

首先,我们来看一种情况

(1)声明一个简单的类,代码如下

function Person(age,name) {
    this.name=name;
    
    this.age=age;
  }

(2)实例化类+调用

var p=new Person(-10,"小明");
alert(p.age)//结果出现年龄出现负数

从上述的运行结果中,我们可以看出程序可以正常执行,但这并符合实际,因为年龄出现 了负数,这不是我们想要的,我们需要一个能正确处理并产生与实际情况相符的解决方案。

为了能解决上述年龄出现的问题,我们可以这样做:扩展类的原型链

Person.prototype={
    checkAge:function (age) {
     if(0<age&&age<150){
       return true;
     }else {
      return false;
        }
          }
       }

加上解决方案后,代码如下

(1)基本类

function Person(age,name) {
    this.name=name;
    //调用方法判断验证
    if(!this.checkAge(age)){
      throw new Error("年龄必须在0-150之间");
    }
    this.age=age;
  }

(2)年龄判断验证

Person.prototype={
          checkAge:function (age) {
            if(0<age&&age<150){
              return true;
            }else {
              return false;
            }
          }
      }

(3)调用

var p2=new Person(10,"小明");
alert(p2.age)

我们还可以给name添加一个读取验证,name为空时使用默认值 同样是扩展类的原型链

代码如下,

Person.prototype["getName"]=function () {
        return this.name||"我是默认的";
      }
//调用
var p3=new Person(10,"");
alert(p3.getName())//结果为“我是默认的”

总结一下:当类被定义为门户大开类型时会出现与实际不符合的情况 ,虽然我们可以加在类上扩展原型类加验证方法解决,但是这样会使类变得臃肿。

针对第二种,用命名规范区别私有和公有

步骤如下,

(1)定义类 在类中定义变量(私有和公有变量)+验证方法的调用

//用命名规范来区别私有和公有
  function Person(name,age,email) {
    //定义私有变量

    this._name;//私有
    this.setName(name);//只是方法的调用,方法中有验证,而不是在类中验证

    this._age;//私有
    this.setAge(age);
     this.email=email;//公有的
  }

(2)在类的原型上面 扩展赋值方法

Person.prototype={//直接扩展至原型上,可以在本类的内部使用this调用
    setName:function (name) {
    this._name=name;
    },
    setAge:function (age) {
      //需要做判断符号实际情况
      if(age>0&&age<150){//验证不在类中,类不会变的臃肿
        this._age=age;
      }else {
        throw new Error("年龄必须是在0到150范围内")
      }
    }

  }

(3)应用

var text1=new Person("测试",-10,"qq.com");
 alert(text1._age)//-10 程序会报错 这是我们想要的(说明验证是对的)
var p2=new Person("测试2",10,"qq.cpm");
  alert(p2._age)//程序正常运行 达到我们的目标

总结一下:在类的定义是使用命名规范来定义私有变量和公有变量,并将验证方法和赋值方法扩展到本类的原型链上,在类中调用方法即可(会有返回值),这样不会导致类的臃肿。

针对第三种,闭包实现封装

这种方式有点像高级语言,在定义类是使用get,set方法实现数据的操作

(1)定义一个基本类(变量+操作变量的方法)

function Person(name,age,email) {
    //(1)声明变量和对变量进行操作的get和set方法
    this.email=email;//公有变量
    //get方法
    this.getName=function (name){
      return this.name;//为什么是this调用呢?请看set方法
    }
    this.getAge=function (age){
      return this.age;
    }
    //set方法 这里相当于在类上的扩展
    this.setName=function (name) {
      this.name=name;//Person.prototype.name 这里写明了get中this的写法的来源
    }
    this.setAge=function (age) {
      if(age>0&&age<150){
        this.age=age;//Person.prototype.name 这里写明了get中this的写法的来源
      }else {
        throw new Error("年龄必须是在0到150范围内");
      }
    }


    //(2)写一个构造函数 做初始化 实现闭包 确保set是在get之前的,不然get时会出现错误
    this.init=function () {
     this.setName(name);
     this.setAge(age);
    }
    this.init();//显示调用
  }

(2)应用

var p=new Person("text",-10,"qq.com");
  alert(p.age)//程序由于不符合实际而被阻断,符合要求

 注:额外的闭包写法   var 方式

var _sex="M";
    this.getSex=function () {
       return _sex;
    }
    this.setSex=function () {
        _sex=sex;
    }

总结一下:

(1)这里只是函数和属性的简单封装,还有更为复杂是业务需要封装,使用get和set方法时,需要一个构造函数用于两者先后顺序的初始化实现闭包,之后显示调用,确保set是在get之前的。

(2)闭包的实现,是通过get和set实现的,this.方式赋值时没有暴露在外面而是通过get,set方法实现闭包。

二,静态化

普通属性和函数是作用在对象上到,而静态函数是定义到类上的。

第一种静态函数的写法 :写在类上

(1)首先,定义一个简单的类,例如

function Person(name,age) {
    this.name=name;
    this.age;age;
    this.showName=function () {
      alert(this.name);
    }
  }

(2)定义一个写在类上的方法,Person.add --》(类.函数)或者(类.属性),例如

Person.add=function (x,y) {
    return x+y;
  }

(3)应用

alert(Person.add(10,20));//结果为30

总结一下,该种定义方式有点类似于高级语言的静态类,使用与高级语言的相同通过类直接调用。

第二种静态函数的写法 :使用类中类的方式完成每一个对象全拥有当前类中相同的属性和函数 。注意:  类中类的方式是一次性赋值的

(1)类的定义格式如下

var cat=(function () {
    //私有静态属性
     var AGE=1;
     function add(x,y) {
       return x+y;
     }


     return function () {//类中类 return返回的类中持有与上面类中相同的属性与函数 则共同的AGE和add称为静态属性和静态函数
       this.AGE=AGE;
       this.add=function (x,y) {
        return add(x,y)
       }
     }
  })()//实例化cat,实质是通过return实例化的

(2)应用

alert(new cat().add(1,3))//4
 alert(new cat().AGE)//1

总结一下:从上面的代码格式中我们不难看出在一个类中定义有私有的属性和方法,与一个返回可以初始化本类私有静态属性和方法的类,该类我们称为类中类。当我们实例化外层类时实质上是通过该类内部的类return实例化的。

封装的优点:

(1)保护内部数据完整性是封装一大用处
(2)对象的重构变得轻松,(如果没有封装你敢动正在运用的代码吗?) 答案肯定是不敢的。
(3)化模块间的耦合

弊端:

(1)私有的方法会变得难以进行单元测试
(2)使用封装意味着与复杂的代码打交道
(3)最大问题封装在JavaScript中很难实现  除非运用自如,否则到处封装,使测试变得困难。

以上只是学习的初步理解,不好还希望多多理解。

感兴趣的朋友可以使用在线HTML/CSS/JavaScript代码运行工具:http://tools.3water.com/code/HtmlJsRun测试上述代码运行效果。

希望本文所述对大家JavaScript程序设计有所帮助。

Javascript 相关文章推荐
常用的javascript function代码
May 23 Javascript
JavaScript简单实现鼠标移动切换图片的方法
Feb 23 Javascript
页面get请求 中文参数方法乱码问题的快速解决方法
May 31 Javascript
JS实现iframe自适应高度的方法(兼容IE与FireFox)
Jun 24 Javascript
利用JS实现数字增长
Jul 28 Javascript
利用JS屏蔽页面中的Enter按键提交表单的方法
Nov 25 Javascript
老生常谈的跨域处理
Jan 11 Javascript
jQuery动态生成不规则表格(前后端)
Feb 21 Javascript
原生JS实现Ajax跨域请求flask响应内容
Oct 24 Javascript
详解node.js 下载图片的 2 种方式
Mar 02 Javascript
jQuery使用bind动态绑定事件无效的处理方法
Dec 11 jQuery
layui监听单元格编辑前后交互的例子
Sep 16 Javascript
jquery+css3实现的经典弹出层效果示例
May 16 #jQuery
js抽奖转盘实现方法分析
May 16 #Javascript
JSONP 的原理、理解 与 实例分析
May 16 #Javascript
JavaScript随机数的组合问题案例分析
May 16 #Javascript
Taro UI框架开发小程序实现左滑喜欢右滑不喜欢效果的示例代码
May 18 #Javascript
vue el-tree 默认展开第一个节点的实现代码
May 15 #Javascript
基于leaflet.js实现修改地图主题样式的流程分析
May 15 #Javascript
You might like
广播爱好者需要了解的天线知识
2021/03/01 无线电
Ajax+PHP 边学边练 之二 实例
2009/11/24 PHP
PHP中if和or运行效率对比
2014/12/12 PHP
PHP正则表达式匹配替换与分割功能实例浅析
2017/02/04 PHP
CakePHP框架Model函数定义方法示例
2017/08/04 PHP
详解php命令注入攻击
2019/04/06 PHP
javascript 兼容鼠标滚轮事件
2009/04/07 Javascript
jquery 全局AJAX事件使用代码
2010/11/05 Javascript
基于jQuery的输入框无值自动显示指定数据的实现代码
2011/01/24 Javascript
标题过长使用javascript按字节截取字符串
2014/04/24 Javascript
jQuery filter函数使用方法
2014/05/19 Javascript
详谈JavaScript内存泄漏
2014/11/14 Javascript
clipboard.js无需Flash无需依赖任何JS库实现文本复制与剪切
2015/10/10 Javascript
jQuery 1.9.1源码分析系列(十五)之动画处理
2015/12/03 Javascript
jQuery实现三级菜单的代码
2016/05/09 Javascript
jQuery实现鼠标滚动图片延迟加载效果附源码下载
2016/06/28 Javascript
AngularJS入门教程之多视图切换用法示例
2016/11/02 Javascript
JavaScript 中调用 Kotlin 方法实例详解
2017/06/09 Javascript
jquery获取链接地址和跳转详解(推荐)
2017/08/15 jQuery
基于Bootstrap表单验证功能
2017/11/17 Javascript
详解webpack4.x之搭建前端开发环境
2019/03/28 Javascript
跟混乱的页面弹窗说再见
2019/04/11 Javascript
vue实现微信浏览器左上角返回按钮拦截功能
2020/01/18 Javascript
linux下安装easy_install的方法
2013/02/10 Python
python 获取指定文件夹下所有文件名称并写入列表的实例
2018/04/23 Python
Python中pandas dataframe删除一行或一列:drop函数详解
2018/07/03 Python
python 的numpy库中的mean()函数用法介绍
2020/03/03 Python
Python3爬虫关于识别检验滑动验证码的实例
2020/07/30 Python
海蓝之谜英国官网:La Mer英国
2020/01/15 全球购物
秘书英文求职信
2014/04/16 职场文书
物理教育专业求职信
2014/06/25 职场文书
党员对十八届四中全会的期盼思想汇报范文
2014/10/17 职场文书
春季运动会开幕词
2015/01/28 职场文书
综合素质评价个性发展自我评价
2015/03/06 职场文书
小升初自荐信怎么写
2015/03/26 职场文书
2016年端午节红领巾广播稿
2015/12/18 职场文书