php 用js 封装,JavaScript使用封装
基本封装方法
请看下面的例子: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使用封装相关推荐
- php js写法,javaScript封装的各种写法
这篇文章主要介绍了javaScript封装的各种写法,通过列举优缺点和使用场景详细介绍了几种JavaScript封装的格式,对JavaScript的感兴趣朋友可以参考下本篇文章 在javascript ...
- 第一百三十节,JavaScript,封装库--连缀
JavaScript,封装库--连缀 学习要点: 1.连缀介绍 2.改写库对象 本章我们重点来介绍,在调用库的时候,我们需要能够在前台调用的时候可以同时设置多个操作,比如设置CSS,设置innerHT ...
- js进阶ajax函数封装(匿名函数作为参数传递)(封装函数引入文件的方式非常好用)...
js进阶ajax函数封装(匿名函数作为参数传递)(封装函数引入文件的方式非常好用) 一.总结 2.匿名函数作为参数传递 二.js进阶ajax函数封装 ajax1.js 1 function ajax( ...
- JavaScript面向对象——封装及相关原理解析
<JavaScript设计模式>面向对象编程--封装及相关原理解析 说明:本人编写js习惯不写分号:文章中的源码可根据自己的编程风格修改. 面向对象 面向对象编程就是将你的需求抽象成一个对 ...
- 第一百四十一节,JavaScript,封装库--DOM加载
JavaScript,封装库--DOM加载 DOM加载,跨浏览器封装DOM加载,当网页文档结构加载完毕后执行函数,不等待图片音频视频等文件加载完毕 /** dom_jia_zai()函数,DOM页面加 ...
- 第一百三十一节,JavaScript,封装库--CSS
JavaScript,封装库--CSS 将封装库里的方法,改成了原型添加方法 增加4个方法 tian_jia_class()方法,给获取到的元素添加class属性,参数是class属性值,可以连缀1 ...
- android 和 js 之间交互的封装
HybridBridge 项目地址:YouJZ/HybridBridge 简介:android 和 js 之间交互的封装 更多:作者 提 Bug 标签: webview-js-android ...
- JS中常用方法的封装【转载】
JS中常用方法的封装[转载] 转载理由:我想这么好的内容,可不能因为作者的博客倒闭了就没了,所以就Fork了一份,并复制了一份到自己的博客. 编写自己的代码库(javascript常用实例的实现与封装 ...
- 面向对象的 JavaScript:封装、继承与多态
本文作者:家园工作室研发组成员 @维尔希宁 本文出处: 面向对象的 JavaScript:封装.继承与多态blog.lenconda.top 本文遵循署名-非商业性使用-禁止演绎3.0 未本地化版本 ...
最新文章
- Chapter12:动态内存
- ORA-25155: NATURAL 联接中使用的列不能有限定词
- python字符串出现次数最多的_python – Pandas:获取组中出现次数最多的字符串值...
- java intern_java String的intern方法
- 短线王的盯盘宝怎么样_2022考研英语韦林全程班怎么样?资源分享
- linux phpize
- Java计算时间差_传统的SimpleDateFormat类
- OGC 开放地理信息系统协会
- oracle实现主键自增长及自动生成策略
- reactbootstrap php,什么是React-Bootstrap
- 驱动精灵等软件卸载后剩余文件的删除
- 【读书笔记】Vue.js 初次接触
- 【数据处理】正则匹配指定字符传后面的字符
- 福清龙华职业中专计算机应用学校什么,福建省福清龙华职业中专学校招生专业|福建省福清龙华职业中专学校有哪些专业...
- 利用触发器生成三分频
- input只能输入数字0-9(不含小数点)
- java文本写入方法(PrintStream,FileWriter,BufferedWriter)
- windows下安装ruby on rails
- Win10文件夹搜索功能失效怎么办?
- Chrome浏览器 v71.0.3578.99
热门文章
- 作者:周绮凤,女,博士,厦门大学自动化系副教授。
- 【软件测试】黑盒测试の场景测试法
- 【Python】Matplotlib利用楔形绘制圆环形饼图
- 【Java】基于Socket的C/S聊天程序
- Canvas 画占比图 解决canvas锯齿 bug
- UVa11549计算器谜题[floyd判圈]
- linux公司常用基础命令必知必会一
- 配置spring事务管理的几种方式(声明式事务)
- mysql 5.6 设置long_query_time的值无效的原因
- 同方挑战惠普 大打“惠民”牌