基本封装方法

请看下面的例子:var Person = function(name,age){

this.name = name;

this.age = age || "未填写";

this.hobbys = [];

}

Person.prototype = {

sayName:function(){

console.log(this.name);

},

sayAge:function(){

console.log(this.age);

},

addHobby:function(hobbys){

this.hobbys = this.hobbys.concat(hobbys);

}

}

var person1 = new Person("Jane","20");

var person2 = new Person("TabWeng","21");

person1.addHobby(['sing','drawing']);

person2.addHobby(['football','study','running']);

person1.sayName();

console.log(person1.hobbys.toString());

person2.sayName();

console.log(person2.hobbys.toString());

运行结果:

Jane

sing,drawing

TabWeng

football,study,running

这在JavaScript创建对象中讲过,把可以共用的属性和方法写在原型上,需要每个实例各自都有的副本的属性和方法放在构造函数中。

现在有个问题,名称的输入不能有数字,要怎么解决呢?解决的方法可以写一个检查名称的函数,这个函数写在原型上。var Person = function(name,age){

//校验名称

if(this.checkName(name)){

throw new Error("名字 "+name+" 不能存在数字");

}

this.name = name;

this.age = age || "未填写";

this.hobbys = [];

}

Person.prototype = {

//校验函数

checkName:function(name){

re = /\d/;

return re.test(name);

},

sayName:function(){

console.log(this.name);

},

sayAge:function(){

console.log(this.age);

},

addHobby:function(hobbys){

this.hobbys = this.hobbys.concat(hobbys);

}

}

var person1 = new Person("Helen666","20");

var person2 = new Person("TabWeng","21");

person1.addHobby(['sing','drawing']);

person2.addHobby(['football','study','running']);

person1.sayName();

console.log(person1.hobbys.toString());

person2.sayName();

console.log(person2.hobbys.toString());

这段代码中,我们写了一个checkName()函数,来校验名称,暂且只是校验不能有数字吧,然后再构造函数里的第一行代码中进行校验,若校验不通过,则抛出异常。

这里我传入一个名称Helen666,结果抛出如下异常:

Error: 名字 Helen666 不能存在数字

这样就做到了一个基本的封装,实现内部校验。

但是又有个问题,我们还可以这样来定义名称:var person1 = new Person("Helen","20");

person1.name = "Helen666";

person1.sayName(); //Helen666

这样名称还是可以修改为不合法的名称,于是我们想到用get方法 和set方法来做控制,只能通过set方法来赋值,同时通过set方法进行校验,而通过get方法来获得值。现在的代码修改如下:// Interfacevar People = new Interface("People",["setName","getName","setAge","getAge","addHobby","getHobby","sayName","sayAge"]);var Person = function(name,age){ //implement People

this.setName(name);

this.setAge(age);

this._hobbys = [];}Person.prototype = {

//校验函数

checkName:function(name){

re = /\d/;

return re.test(name);

},

sayName:function(){

console.log(this._name);

},

sayAge:function(){

console.log(this._age);

},

addHobby:function(hobbys){

this._hobbys = this._hobbys.concat(hobbys);

},

getHobby:function(){

return this._hobbys;

},

setName:function(name){

if(this.checkName(name)){

throw new Error("名字 "+name+" 不能含有数字");

}

this._name = name;

},

getName:function(){

return this._name;

},

setAge:function(age){

this._age = age || "未设置";

},

getAge:function(){

return this._age;

}}var person1 = new Person("Helen","20");person1.addHobby(['sing','drawing']);function record(person){

Interface.ensureImplements(person,People);

person.sayName();

console.log(person.getHobby().toString());}record(person1);

运行结果:

Helen

sing,drawing

首先,这段代码我们使用了接口,定义了People接口,而person来实现这个接口,注意注释的内容。(关于接口,请看这篇 JavaScript使用接口)

其次,我们使用了get方法 和 set方法来取值和赋值,我们可以约定程序员只能通过set来赋值,而在set方法里面我们对所赋予的值进行了校验,以确保准确。但是这仅仅是一种约定,程序员依然可以通过 person1.name = "123" 来赋值,修改内部属性。

为了规范和起到提醒作用,我们把内部属性的命名进行规范,在这些属性前面加上“_”,比如 **_name** 、**_age** ,这样如果程序员要直接修改属性,那么他就必须这样写person1._name = "123",这明显是一种故意的做法,一般程序员不会这么做,起到规范和提醒的作用。

尽管如此,这种仅仅是用规定进行约束,还是无法阻止通过person1._name进行修改,下面的方法可以做到把内部属性真正做到私有化。

通过闭包进行封装// Interface

var People = new Interface("People",["setName","getName","setAge","getAge","addHobby","getHobby","sayName","sayAge"]);

var Person = function(name,age){ //implement People

// 私有变量

var _name,_age,_hobbys = [];

this.addHobby = function(hobbys){

_hobbys = _hobbys.concat(hobbys);

},

this.getHobby = function(){

return _hobbys;

},

this.setName = function(name){

if(this.checkName(name)){

throw new Error("名字 "+name+" 不能含有数字");

}

_name = name;

},

this.getName = function(){

return _name;

},

this.setAge = function(age){

_age = age || "未设置";

},

this.getAge = function(){

return _age;

}

this.setName(name);

this.setAge(age);

}

Person.prototype = {

checkName:function(name){

re = /\d/;

return re.test(name);

},

sayName:function(){

console.log(this.getName());

},

sayAge:function(){

console.log(this.getAge());

}

}

var person1 = new Person("Helen","20");

person1.addHobby(['sing','drawing']);

function record(person){

Interface.ensureImplements(person,People);

person.sayName();

console.log(person.getHobby().toString());

}

record(person1);

在构造函数中,属性不使用this,外部也就无法访问到这个属性,而闭包通过作用域链可以访问到这个属性,那么我们就通过闭包设置了为属性赋值的唯一入口,从而起到了严格校验这些属性的作用。

尽管如此,在构造函数中定义方法很多时候是没必要的,因为这样每创建一个实例,就会产生一个方法的副本,这是需要内存支持的,所以在使用的过程中,如果能用上面的基本封装方法,尽量用,除非对于私有属性有非常严格的校验要求才用闭包这种方法。

本文原创发布php中文网,转载请注明出处,感谢您的尊重!

php 用js 封装,JavaScript使用封装相关推荐

  1. php js写法,javaScript封装的各种写法

    这篇文章主要介绍了javaScript封装的各种写法,通过列举优缺点和使用场景详细介绍了几种JavaScript封装的格式,对JavaScript的感兴趣朋友可以参考下本篇文章 在javascript ...

  2. 第一百三十节,JavaScript,封装库--连缀

    JavaScript,封装库--连缀 学习要点: 1.连缀介绍 2.改写库对象 本章我们重点来介绍,在调用库的时候,我们需要能够在前台调用的时候可以同时设置多个操作,比如设置CSS,设置innerHT ...

  3. js进阶ajax函数封装(匿名函数作为参数传递)(封装函数引入文件的方式非常好用)...

    js进阶ajax函数封装(匿名函数作为参数传递)(封装函数引入文件的方式非常好用) 一.总结 2.匿名函数作为参数传递 二.js进阶ajax函数封装 ajax1.js 1 function ajax( ...

  4. JavaScript面向对象——封装及相关原理解析

    <JavaScript设计模式>面向对象编程--封装及相关原理解析 说明:本人编写js习惯不写分号:文章中的源码可根据自己的编程风格修改. 面向对象 面向对象编程就是将你的需求抽象成一个对 ...

  5. 第一百四十一节,JavaScript,封装库--DOM加载

    JavaScript,封装库--DOM加载 DOM加载,跨浏览器封装DOM加载,当网页文档结构加载完毕后执行函数,不等待图片音频视频等文件加载完毕 /** dom_jia_zai()函数,DOM页面加 ...

  6. 第一百三十一节,JavaScript,封装库--CSS

    JavaScript,封装库--CSS 将封装库里的方法,改成了原型添加方法 增加4个方法 tian_jia_class()方法,给获取到的元素添加class属性,参数是class属性值,可以连缀1 ...

  7. android 和 js 之间交互的封装

    HybridBridge 项目地址:YouJZ/HybridBridge 简介:android 和 js 之间交互的封装 更多:作者   提 Bug    标签: webview-js-android ...

  8. JS中常用方法的封装【转载】

    JS中常用方法的封装[转载] 转载理由:我想这么好的内容,可不能因为作者的博客倒闭了就没了,所以就Fork了一份,并复制了一份到自己的博客. 编写自己的代码库(javascript常用实例的实现与封装 ...

  9. 面向对象的 JavaScript:封装、继承与多态

    本文作者:家园工作室研发组成员 @维尔希宁 本文出处: 面向对象的 JavaScript:封装.继承与多态​blog.lenconda.top 本文遵循署名-非商业性使用-禁止演绎3.0 未本地化版本 ...

最新文章

  1. Chapter12:动态内存
  2. ORA-25155: NATURAL 联接中使用的列不能有限定词
  3. python字符串出现次数最多的_python – Pandas:获取组中出现次数最多的字符串值...
  4. java intern_java String的intern方法
  5. 短线王的盯盘宝怎么样_2022考研英语韦林全程班怎么样?资源分享
  6. linux phpize
  7. Java计算时间差_传统的SimpleDateFormat类
  8. OGC 开放地理信息系统协会
  9. oracle实现主键自增长及自动生成策略
  10. reactbootstrap php,什么是React-Bootstrap
  11. 驱动精灵等软件卸载后剩余文件的删除
  12. 【读书笔记】Vue.js 初次接触
  13. 【数据处理】正则匹配指定字符传后面的字符
  14. 福清龙华职业中专计算机应用学校什么,福建省福清龙华职业中专学校招生专业|福建省福清龙华职业中专学校有哪些专业...
  15. 利用触发器生成三分频
  16. input只能输入数字0-9(不含小数点)
  17. java文本写入方法(PrintStream,FileWriter,BufferedWriter)
  18. windows下安装ruby on rails
  19. Win10文件夹搜索功能失效怎么办?
  20. Chrome浏览器 v71.0.3578.99

热门文章

  1. 作者:周绮凤,女,博士,厦门大学自动化系副教授。
  2. 【软件测试】黑盒测试の场景测试法
  3. 【Python】Matplotlib利用楔形绘制圆环形饼图
  4. 【Java】基于Socket的C/S聊天程序
  5. Canvas 画占比图 解决canvas锯齿 bug
  6. UVa11549计算器谜题[floyd判圈]
  7. linux公司常用基础命令必知必会一
  8. 配置spring事务管理的几种方式(声明式事务)
  9. mysql 5.6 设置long_query_time的值无效的原因
  10. 同方挑战惠普 大打“惠民”牌