js继承封装(一)

对于该话题网上一搜一大把,在这也为自己的一些心得做个小小总结吧:
继承方式一:网上常说的采用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继承封装(二)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值