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脚本调试方法小结
Nov 24 Javascript
jquery tools之tooltip
Jul 25 Javascript
html dom节点操作(获取/修改/添加或删除)
Jan 23 Javascript
js统计页面的来访次数实现代码
May 09 Javascript
jQuery中click事件用法实例
Dec 26 Javascript
前端程序员必须知道的高性能Javascript知识
Aug 24 Javascript
angularJs使用$watch和$filter过滤器制作搜索筛选实例
Jun 01 Javascript
详解angularjs的数组传参方式的简单实现
Jul 28 Javascript
基于webpack 实用配置方法总结
Sep 28 Javascript
JS实现图片上传多次上传同一张不生效的处理方法
Aug 06 Javascript
pm2发布node配置文件ecosystem.json详解
May 15 Javascript
react中props 的使用及进行限制的方法
Apr 28 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
PHP应用JSON技巧讲解
2013/02/03 PHP
thinkPHP5框架路由常用知识点汇总
2019/09/15 PHP
Prototype使用指南之string.js
2007/01/10 Javascript
js对象转json数组的简单实现案例
2014/02/28 Javascript
用户代理字符串userAgent可实现的四个识别
2015/09/20 Javascript
js阻止默认浏览器行为与冒泡行为的实现代码
2016/05/15 Javascript
JS实现回到页面顶部动画效果的简单实例
2016/05/24 Javascript
javascript解析ajax返回的xml和json格式数据实例详解
2017/01/05 Javascript
前端把html表格生成为excel表格的实例
2017/09/19 Javascript
jQuery实现手机号正则验证输入及自动填充空格功能
2018/01/02 jQuery
使用vue-cli创建项目的图文教程(新手入门篇)
2018/05/02 Javascript
vue单页面实现当前页面刷新或跳转时提示保存
2018/11/02 Javascript
Nodejs监听日志文件的变化的过程解析
2019/08/04 NodeJs
ionic+html5+API实现双击返回键退出应用
2019/09/17 Javascript
vue使用recorder.js实现录音功能
2019/11/22 Javascript
uniapp 仿微信的右边下拉选择弹出框的实现代码
2020/07/12 Javascript
python读取Android permission文件
2013/11/01 Python
python在命令行下使用google翻译(带语音)
2014/01/16 Python
Python中的XML库4Suite Server的介绍
2015/04/14 Python
Django实现组合搜索的方法示例
2018/01/23 Python
python3实现163邮箱SMTP发送邮件
2018/05/22 Python
Python参数解析模块sys、getopt、argparse使用与对比分析
2019/04/02 Python
Django模型序列化返回自然主键值示例代码
2019/06/12 Python
使用Python实现文字转语音并生成wav文件的例子
2019/08/08 Python
Python基于yield遍历多个可迭代对象
2020/03/12 Python
python实现Oracle查询分组的方法示例
2020/04/30 Python
css3实现信纸/同学录效果的示例代码
2018/12/11 HTML / CSS
幼儿园实习生辞职信
2014/01/20 职场文书
新员工试用期自我鉴定
2014/04/17 职场文书
给老婆的保证书范文
2014/04/28 职场文书
文案策划岗位职责
2015/02/11 职场文书
2015年英语教师工作总结
2015/05/20 职场文书
详解JavaScript中的执行上下文及调用堆栈
2021/04/29 Javascript
element多个表单校验的实现
2021/05/27 Javascript
python中if和elif的区别介绍
2021/11/07 Python
python神经网络ResNet50模型
2022/05/06 Python