您的位置:首页 > Web前端 > JavaScript

js继承封装(一)

2015-11-14 13:22 369 查看
对于该话题网上一搜一大把,在这也为自己的一些心得做个小小总结吧:

继承方式一:网上常说的采用call和apply来实现继承

//定义一个修改command函数
function UpdateCommand(path) {
this.name="修改命令";
this.path = path;
this.executeFun=function(){
alert("发送请求1");
}
}

UpdateCommand.prototype.execute = function () {
alert("发送请求2");
}
//定义一个查询command函数
function QueryCommand(path) {
UpdateCommand.call(this, path);
}

var queryCommand = new QueryCommand();
alert(queryCommand.name);
//这里输出了 修改命令 简单的实现了在QueryCommand里面取得了UpdateCommand里面的值,
queryCommand.executeFun();
//调用到了UpdateCommand的类方法。
queryCommand.execute();
//执行失败


这是因为excute方法是UpdateCommand的原型方法,而采有call和apply没法做到原型方法继承,只能做到类似继承。也就是继承了函数构造方法里面的所有属性而已。

这就牵扯一个问题,采用原型方式编写函数与采用类函数的优缺点问题:

//采用类方法编写一个函数
var Person=function(){
this.age=18;
this.name="张三";
this.getName=function(){
return this.name;
}
this.getAge=function(){
return this.age;
}
}

//采用原型继承的方式编写一个函数
var User=function(){
this.name="张三";
this.age="18";
}
User.prototype.getName=function(){
return this.name;
}
User.prototype.getAge=function(){
return this.age;
}

var per=new Person();
alert(per.getName());//输出张三
var us=new User();
alert(us.getName());//输出张三


其实从调用过程、输出结果来看,俩者也没有太大区别,类方法:每次实例化一个实例对象时,就要为其分配内存,当界面产生多个Person实例对象时,就会开辟多个类方法的内存。而原型方法是共享的,不会重复占有内存。所以从内存角度考虑的话推荐采用原型继承方式来扩展。

在最上面的测试queryCommand.execute();无法执行的,那我们可以采用原型继承的方式来扩展。

继承方式二:原型继承方式

//定义一个修改command函数
function UpdateCommand(path) {
this.name="修改命令";
this.path = path;
}

UpdateCommand.prototype.execute = function () {
alert("发送请求2");
}
//定义一个查询command函数
function QueryCommand(path) {
this.path=path;
}
QueryCommand.prototype=new UpdateCommand();
var queryCommand = new QueryCommand("/test.jsp");
queryCommand.execute();
//会输出 【发送请求2字样】 表示queryCommand拥有了UpdateCommand 的原型方法。
alert(queryCommand.name);
//但这里会输出 undifined 并没有输出【修改命令】四个字, 上面采用call继承能获取该属性,但采用原型继承则不行。


在此实现原型继承使用的

QueryCommand.prototype=new UpdateCommand();

的方式来实现的。在此基础上有人就会提出结合2者的优势来实现继承,这样就继承了原型方法,又继承了类属性、类方法。

继承方式三:call与原型继承的结合

//定义一个修改command函数
function UpdateCommand(path) {
this.name="修改命令";
this.path = path;
}

UpdateCommand.prototype.execute = function () {
alert("发送请求2");
}
//定义一个查询command函数
function QueryCommand(path) {
UpdateCommand.call(this,path);
}
QueryCommand.prototype=new UpdateCommand();
var queryCommand = new QueryCommand("/test.jsp");
queryCommand.execute();
//输出了【发送请求2】
alert(queryCommand.name);
//输出了【修改命令】


到此可能认为已经完美实现函数继承,但这种方式存在问题没呢?

function QueryCommand(path) {
UpdateCommand.call(this,path);
//这里会实例化一次UpdateCommand对象
}


**QueryCommand.prototype=new UpdateCommand();**
//这里又实例化一次UpdateCommand对象


也就是只要初始化一个queryCommand对象的同时,会实例化UpdateCommand对象2次。

当然在此UpdateCommand对象比较小,实例化几次对程序影响不大,但如果UpdateCommand比较庞大,而且使用频繁的时候,这可能就是个致命的问题。

为了解决这个问题请看 js继承封装(二)
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: