javascript OOP(下)(九)
一、javascript模拟重载
java中根据参数类型和数量的区别来实现重载,javascript弱类型,没有直接的机制实现重载,javascript中参数类型不确定和参数个数任意,通过判断实际传入的参数的个数来实现重载。
<script>
function Person() {
var args = arguments;
if (typeof args[0] === 'object' && args[0]) { //判断第一个参数是否为对象,进行相应操作。传参为空时typeof null也是object,所以要同时判断args[0]不为空
if (args[0].name) {
this.name = args[0].name;
}
if (args[0].age) {
this.age = args[0].age;
} } else {
if (args[0]) {
this.name = args[0];
}
if (args[1]) {
this.age = args[1];
}
}
}
//toString继承自Object,一般的对象toString会显示"[object Object]",没有什么意义,所以可以重新一下,方便输出
Person.prototype.toString = function() {
return 'name=' + this.name + ',age=' + this.age;
} var bosn = new Person('Bosn', 27);
bosn.toString(); //name=Bosn,age=27 var lxy = new Person({
name: 'lxy',
age: 25
});
lxy.toString(); //name=lxy,age=25
</script>
二、调用基类方法
1、调用基类的方法进行初始化
基类人Person
学生Student
初始化Student的时候,初始化了className后需要初始化Person部分,可以通过
Person.call(this,name);调用基类的方法和属性。
<script>
function Person(name){
this.name=name;
}
function Student(name,className){
this.className=className;
Person.call(this,name); //调用基类的构造器
} var bosn=new Student('Bosn','Network064');
console.log(bosn);
</script>

输出时能够正确的被初始化。
2、子类覆盖了基类的方法
Student的init覆盖了Person的init,初始化Student时需要初始化Person,通过Person.prototype.init.apply(this,arguments);
<script>
Person.prototype.init=function(){ }; Student.prototype.init=function(){
//do sth
Person.prototype.init.apply(this,arguments);
}
</script>
三、链式调用
类似jquery选择器链式调用。
关键要在ClassManager.prototype.addClass操作完成后return this。
<script>
function ClassManager(){//构造器
} ClassManager.prototype.addClass=function(str){ //在构造器上挂载一个方法,表示addClass
console.log('Class:'+str+' added.');
return this;// this总是指向ClassManager的实例,所以return就实现了链式调用
} var manager=new ClassManager();
manager.addClass('classA').addClass('classB').addClass('classC');
//Class:classA added.
//Class:classB added.
//Class:classC added. </script>
四、抽象类
没有机制,可以进行模拟。主要是用throw new Error()。
<script>
function DetectorBase(){
throw new Error('Abstract class can not be invoked directly!');
//在构造器里抛一个异常,防止抽象类被直接调用
}
DetectorBase.detect=function(){console.log('Detection starting...');}
DetectorBase.stop=function(){console.log('Detector stopped.');}
DetectorBase.init=function(){
throw new Error('Error');
//想要子类覆盖而不想被直接调用的方法,抛出异常
} function LinkDetector(){}
//通过Object.create实现继承
LinkDetector.prototype=Object.create(DetectorBase.prototype);
LinkDetector.prototype.constructor=LinkDetector;
</script>
五、definePrototype(ES5)
<script>
//ES5里面对于属性有一些getter setter方法,有一些标签
//configurable:能否delete
//enumberable:能否for in遍历
//writable:能否读写属性
//value:记录属性值,默认为undefine
//控制属性的访问情况 function Person(name){
//name可遍历,不可读写,不可删除
Object.defineProperty(this,'name',{value:name,enumerable:true});
}
//ARMS_NUM相当于定义了一个常量,可枚举,不可写,不可删除
Object.defineProperty(Person,'ARMS_NUM',{value:2,enumerable:true});
Object.seal(Person.prototype); //Person在初始化之后不想被扩展,不想被配置了,用seal方法
Object.seal(Person); function Student(name,className){
this.className=className;
Person.call(this,name);
}
Student.prototype=Object.create(Person.prototype);
Student.prototype.constructor=Student;
</script>
六、模块化
模块化工具或者说类库有有seajs,requirejs等。
模块化的一般形式是:一个定义了私有变量和函数的函数;利用闭包创建可以访问私有变量和函数的特权函数;最后返回这个特权函数,或者把它们保存到一个可访问到的地方。
1、通过返回一个对象实现简单模块化
<script>
var moduleA;//只需要把最核心的东西moduleA放到全局作用域
moduleA=function(){
var prop=1;
function func(){}
return{ //func和prop不会被泄露到全局作用域
func:func,
prop:prop
}
}() //moduleA用立即执行的匿名函数
</script>
2、通过返回this的方法实现简单模块化
通过new function(),通过设置this的值,我们知道通过new调用最后会返回this,除非你return的是一个对象。
<script>
//通过new默认返回this的方法
va moduleA;
moduleA=new function(){
var prop=1;
function func(){}
this.func=func;
this.prop=prop;
}
</script>
3、模块化应用【update20170307】
模块化可以摒弃全局变量的使用。促进了信息隐藏和其他优秀的设计实践。对于应用程序的封装,或者构造其他单例对象,模块模式非常有效。
模块模式也可以用来产生安全的对象。
例:构造一个用来产生序列号的对象。
<script>
var serial_maker=function(){
/*返回一个用来产生唯一字符串的对象。
唯一字符串由两部分组成:前缀+序列号。
该对象包含一个设置前缀的方法,一个设置序列号的方法和一个产生唯一字符串的gensym方法。
*/
var prefix='';
var seq=0;
return{
set_prefix:function(p){
prefix=String(p);
},
set_seq:function(s){
seq=s;
},
gensym:function(){
var result=prefix+seq;
seq+=1;
return result;
}
}
};
var seqer=serial_maker();
seqer.set_prefix('Q');
seqer.set_seq(1000);
var unique;
unique=seqer.gensym();
console.log(unique);//unique是"Q1000"
unique=seqer.gensym();
console.log(unique);//unique是"Q1001" </script>
seqer()的3个方法都没有用到this或者that,因此没有办法损害seqer。除非调用对应的方法,否则没法改变prefix或seq的值。
seqer对象是可变的,所以它的方法可能会被替换掉,但替换后的方法依然不能访问私有变量。
比如:
seqer.gensym=function(){
var result=prefix+seq;
seq+=3;
console.log(seq);
return result;
}
就会报错,因为替换后的方法不能访问私有变量。
seqer就是一组函数的集合,而且那些函数被授予特权,拥有使用或修改私有状态的能力。
如果我们把seqer.gensym作为一个值传递给第三方函数,那个函数能用它产生唯一字符串,却不能通过修改它来改变prefix或seq的值。
参考:
js模块化历程
http://www.cnblogs.com/lvdabao/p/js-modules-develop.html
写了十年JS却不知道模块化为何物?
https://blog.wilddog.com/?p=587
深入浅出ES6(十三):类 Class
http://www.infoq.com/cn/articles/es6-in-depth-classes/
本文作者starof,因知识本身在变化,作者也在不断学习成长,文章内容也不定时更新,为避免误导读者,方便追根溯源,请诸位转载注明出处:http://www.cnblogs.com/starof/p/4904929.html有问题欢迎与我讨论,共同进步。
javascript OOP(下)(九)的更多相关文章
- Javascript多线程引擎(九)
Javascript多线程引擎(九)--垃圾回收 垃圾回收这个话题对Programer来说是非常老旧的话题, 从手动的malloc/free 到半自动的 引用计数 再到全自动的 mark-sweep ...
- 使用JavaScript OOP特性搭建Web应用
最近,我面试了一个有五年 Web 应用程序开发经验的软件开发人员.四年半来她一直在从事 JavaScript 相关的工作,她自认为 JavaScript 技能非常好,但在不久之后我就发现实际上她对 J ...
- Arcgis for Javascript API下类似于百度搜索A、B、C、D marker的实现方式
原文:Arcgis for Javascript API下类似于百度搜索A.B.C.D marker的实现方式 多说无益,首先贴两张图让大家看看具体的效果: 图1.百度地图搜索结果 图2.Arcgis ...
- (JavaScript插件——下拉菜单)
前言 阅读之前您也可以到Bootstrap3.0入门学习系列导航中进行查看http://www.cnblogs.com/aehyok/p/3404867.html 本文主要来学习一下JavaScrip ...
- JavaScript OOP 之 this指向
今天给大家分享一个JavaScript OOP中关于分辨this指向对象的小技巧,很实用呦! 我们先来看一段代码: 大家能判断出func();和obj.func();这两句的this指向吗? 首先,我 ...
- JavaScript基础--内部类(九)
js的内部类javascript 中本身提供一些,可以直接使用的类,这种类就是内部类,主要有:ObjectArrayMathBooleanStringRegExpDateNumber 1.内部类分类从 ...
- JavaScript OOP(一)之构造函数与new命令
面向对象编程:Object Oriented Programming,简称OOP. 典型的oop语言,如hava.c++,存在着类的概念,类就是对象的模板 (类可以类比为人类:而实例化类后变为对象,对 ...
- JavaScript OOP 之「创建对象」
工厂模式 工厂模式是软件工程领域一种广为人知的设计模式,这种模式抽象了创建具体对象的过程.工厂模式虽然解决了创建多个相似对象的问题,但却没有解决对象识别的问题. function createPers ...
- 玩转JavaScript OOP[4]——实现继承的12种套路
概述 在之前的文章中,我们借助构造函数实现了"类",然后结合原型对象实现了"继承",并了解了JavaScript中原型链的概念. 理解这些内容,有助于我们更深入 ...
随机推荐
- Windows PowerShell 入門(5)-制御構文
Windows PowerShellにおける制御構文について学びます.数ある制御構文の中でもSwitch文は.他の言語に比べ豊富な機能が用意されています. 対象読者 Windows PowerShel ...
- MVC 当前上下文中不存在名称“Styles” “Scripts”
它们在程序集System.Web.Optimization下,只要全名引用即可 修改配置 在web项目的Views下的web.config修改如下即可,如果是Areas下,处理方法相同 <sys ...
- nc 搭建环境流程及问题
1 拷贝目录,包括eclipse及home两个文件夹 2 将jdk环境配置为home里的jdk,现在为1.5 3 在mde development 中设置数据库链接及应用服务及端口号 4 新建mde项 ...
- mybatis打印SQL日志
在配置的log4j输出时,不能打印SQL信息,在mybatis-config.xml中添加如下配置即可 <settings> <setting name="logImpl& ...
- cache、session、cookie的区别
session把数据保存在服务器端,每一个用户都有属于自己的Session,与别人的不冲突就是说,你登陆系统后,你的信息(如账号.密码等)就会被保存在服务器上一个单独的session中,当你退出系统后 ...
- MVC之基架
参考 ASP.NET MVC5 高级编程(第5版) 定义: 通过对话框生成视图及控制器的模版,这个过程叫做“基架”. 基架可以为应用程序的创建.读取.更新和删除(CRUB)功能生成所需的样板代码.基架 ...
- js 对象的循环
var car = {type:"Fiat", model:500, color:"white"}; var arr = array(); for(i in c ...
- 金9银10,分享几个重要的Android面试题
说一下java多态的理解,以及接继承,和接口的理解 于哥在这里只讲多态,其他自己上网体会 对于多态的定义不同类的对象对统一函数做出不同对的响应或者动作.作用主要是消除类之间的耦合性,灵活性比较强,利于 ...
- SoapUI、Jmeter、Postman三种接口测试工具的比较分析
前段时间忙于接口测试,也看了几款接口测试工具,简单从几个角度做了个比较,拿出来与诸位分享一下吧.各位如果要转载,请一定注明来源,最好在评论中告知博主一声,感谢.本报告从多个方面对接口测试的三款常用工具 ...
- Confluence 6 配置 XSRF 保护
Confluence 需要一个 XSRF 令牌才能创建一个评论,这个被用来保护用户不在评论区恶意发布内容.所有 Confluence 自定义的主题都被启用了这个功能,但是如果你使用自定义主题的话,可能 ...