上一章讲到用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);
//输出了【修改命令】
现在如果我对queryCommand 进行方法重载,会是啥结果呢:
QueryCommand.prototype.execute=function(){
alert("发送查询请求");
}
QueryCommand.prototype=new UpdateCommand();
var queryCommand = new QueryCommand("/test.jsp");
queryCommand.execute();
//输出结果是【发送请求2】 并没有输出 【发送查询请求】
但如果我们把这俩句话
QueryCommand.prototype.execute=function(){
alert("发送查询请求");
}
QueryCommand.prototype=new UpdateCommand();
执行顺序变更下呢?
QueryCommand.prototype=new UpdateCommand();
QueryCommand.prototype.execute=function(){
alert("发送查询请求");
}
var queryCommand = new QueryCommand("/test.jsp");
queryCommand.execute();
//输出结果是【发送查询请求】 并没有输出 【发送请求2】
从这可以看出,我们在写方法重载的时候一定要注意到代码的顺序,如果顺序不对的话,执行结果会出乎意料
为了进步验证,执行下面的代码
//定义一个查询command函数
function QueryCommand(path) {
UpdateCommand.call(this,path);
}
QueryCommand.prototype.execute=function(){
alert("发送查询请求");
}
var queryCommand = new QueryCommand("/test.jsp");
alert(queryCommand.constructor ===QueryCommand);
//输出结果为true
如果实现原型继承后的执行结果
function QueryCommand(path) {
UpdateCommand.call(this,path);
}
QueryCommand.prototype.execute=function(){
alert("发送查询请求");
}
QueryCommand.prototype=new UpdateCommand();
var queryCommand = new QueryCommand("/test.jsp");
alert(queryCommand.constructor ===QueryCommand);
//输出结果为false
从上面分析可以看出,采用以上的继承方式来实现存在以下毛病:
- 在创建queryCommand构造函数和原型(以后简称类)时,就对UpdateCommand进行了实例化,这是不合适的。
- 方法重载需要考虑代码顺序,容易出错
- 实现中有constructor属性的指向错误
js继承封装(三)讲解解决方法