JavaScript 的继承机制----对象冒充

继承机制,说到继承,就要想到从基类开始,但是JavaScript中的类有两大类:一,内嵌的;二,用户自定义;一般前者不会被用来做基类,原因是为了保障js的安全。但是我们可以通过prototype来对基类进行扩充,增加我们想要的属性和方法。以下是自己对继承的几种方式的理解。

1>  对象冒充,是JavaScript 和 ECMAScript实现继承的方法,在学习对象冒充实现继承前我们的先了解关键字 this 的使用,例如:

          view plaincopy to clipboardprint?
function  classA(color){  
  this.color = color;  
  this.show = function(){alert(this.color);}  
}  
/* 
   Note: 
     1> this 代表的是classA函数所构建的对象,而非函数classA对象本身这样说主要是为了避免(function is object)的影响; 
     2> 在构建classA对象时,是通过this来初始化的属性和方法的,如果用classB的this去冒充classA的this,那么就实现了简单的继承了 
*/ 
function  classA(color){
  this.color = color;
  this.show = function(){alert(this.color);}
}
/*
   Note:
     1> this 代表的是classA函数所构建的对象,而非函数classA对象本身这样说主要是为了避免(function is object)的影响;
     2> 在构建classA对象时,是通过this来初始化的属性和方法的,如果用classB的this去冒充classA的this,那么就实现了简单的继承了
*/

2>继承机制的实现方式:

    NO1:对象冒充

         对象冒充的原理:函数classA通过this来初始化属性和方法,如果用函数classB的this冒充classA的this去执行,则就会使classB具有classA的属性和方法。例如

         view plaincopy to clipboardprint?
function classA(sColor){  
   this.sColor = sColor;  
   this.show = function(){alert(this.sColor);}  
}  
 
function classB(sColor,sName){  
  this.new = classA;  
  this.new(sColor);  
  delete this.new;  
  /* 
    Note 
      必须释放classA的引用,那样对于classA是安全的。可是再执行一段以上代码,实现多重继承。 
     this.new = classC; 
    this.new(arguments); 
    delete this.new; 
  */ 
  this.sName = sName;   
  this.say = function(){alert(this.sName);}  
}  
 
var a = new classA("blue");  
var b = new classB("red","BMW");  
a.show(); // blue  
b.say(); //BMW  
b.show(); // red 
function classA(sColor){
   this.sColor = sColor;
   this.show = function(){alert(this.sColor);}
}

function classB(sColor,sName){
  this.new = classA;
  this.new(sColor);
  delete this.new;
  /*
    Note
      必须释放classA的引用,那样对于classA是安全的。可是再执行一段以上代码,实现多重继承。
     this.new = classC;
    this.new(arguments);
    delete this.new;
  */
  this.sName = sName;
  this.say = function(){alert(this.sName);}
}

var a = new classA("blue");
var b = new classB("red","BMW");
a.show(); // blue
b.say(); //BMW
b.show(); // red

        注意:对象冒充是所有继承的前提,冒充只能使子类继承基类中的属性和方法,对基类prototype中的属性和方法是不可见的。也可以实现多重继承。

    NO2:原型链

         原型链,是继承的另一种方式,它不是通过对象冒充来实现的,而是改变prototype指针的指向来实现的。不过在运行时也参杂着对象冒充,例如:

         view plaincopy to clipboardprint?
function classA(){}  
classA.prototype.sColor = "red";  
classA.prototype.show = function(){  
   alert(this.sColor);  
}  
 
function classB(){}  
classB.prototype = new classA(); //no arguments  
/* 
  Note: 
      classB.prototype 开始指向一块命名空间,执行上行语句后,classB.prototype的命名空间则是classA的以一个对象,所有在执行此方法前不可以向classB增加属性和方法,不然会发生覆盖。 
*/ 
classB.prototype.name = "BMW";  
classB.prototype.say = function(){  
 alert(this.name);  
}  
 
var a = new classA();  
a.show(); // red  
var b = new classB();  
b.show(); // red  
b.say(); //BMW 
function classA(){}
classA.prototype.sColor = "red";
classA.prototype.show = function(){
   alert(this.sColor);
}

function classB(){}
classB.prototype = new classA(); //no arguments
/*
  Note:
      classB.prototype 开始指向一块命名空间,执行上行语句后,classB.prototype的命名空间则是classA的以一个对象,所有在执行此方法前不可以向classB增加属性和方法,不然会发生覆盖。
*/
classB.prototype.name = "BMW";
classB.prototype.say = function(){
 alert(this.name);
}

var a = new classA();
a.show(); // red
var b = new classB();
b.show(); // red
b.say(); //BMW
   

        注意:原型链不可以实现多重继承,且在实例化新的命名空间的时候不可以带参数。

    NO3:call方法

        call(this,argument),此方法是函数对象的方法(classA.call),且两个参数:参数一,this代表的是当前对象;参数二,是实例化的参数,只能是单个的。

        view plaincopy to clipboardprint?
function classA(sColor){  
  this.sColor = sColor;  
  this.show = function(){alert(this.sColor);}  
}  
 
classA.prototype.say = function(){  
  alert("hello");  
}  
 
function classB(sColor,sName){  
  classA.call(this,sColor);  
  this.sName = sName;  
  this.showName = function(){  
    alert(this.sName);  
  }  
}  
 
var a = new classA("blue");  
a.show();//blue  
a.say();//hello  
var b = new classB("red","BMW");  
b.show();//red  
b.say();//error : no this function  
b.showName();// BMW 
function classA(sColor){
  this.sColor = sColor;
  this.show = function(){alert(this.sColor);}
}

classA.prototype.say = function(){
  alert("hello");
}

function classB(sColor,sName){
  classA.call(this,sColor);
  this.sName = sName;
  this.showName = function(){
    alert(this.sName);
  }
}

var a = new classA("blue");
a.show();//blue
a.say();//hello
var b = new classB("red","BMW");
b.show();//red
b.say();//error : no this function
b.showName();// BMW

       注意:之所以会报错主要以因为prototype中的属性和方法通过call方法是继承不下来的,apply方法也一样,唯一的区别就是参数二的类型不同

    NO4:apply方法

        与call方法类似,具体如:

        view plaincopy to clipboardprint?
function classA(sColor){  
  this.sColor = sColor;  
  this.show = function(){alert(this.sColor);}  
}  
classA.prototype.say = function(){  
  alert("hello..");  
}  
 
function classB(sColor,sName){  
  classA.apply(this,new Array(sColor));  
 
  this.sName = sName;  
  this.showName = function(){  
    alert(this.sName);  
  }  
}  
 
var a = new classA("blue");  
a.show();// output: blue  
a.say();// output: hello..  
var b = new classB("red","BMW");  
b.show(); //output red  
b.say();// error,no this function  
b.showName();//output BMW 
function classA(sColor){
  this.sColor = sColor;
  this.show = function(){alert(this.sColor);}
}
classA.prototype.say = function(){
  alert("hello..");
}

function classB(sColor,sName){
  classA.apply(this,new Array(sColor));

  this.sName = sName;
  this.showName = function(){
    alert(this.sName);
  }
}

var a = new classA("blue");
a.show();// output: blue
a.say();// output: hello..
var b = new classB("red","BMW");
b.show(); //output red
b.say();// error,no this function
b.showName();//output BMW

 NO5:原型链 && 对象冒充

      这种模式是原型链和对象冒充的结合,同构对象冒充来继承函数对象中的属性和方法,函数原型中的属性和方法则用原型链来实现。看起来非常清楚,但是值得注意的是,原型链在构建对象时是不带参数的,具体如:

      view plaincopy to clipboardprint?
function classA(sColor){  
  this.sColor = sColor;  
  this.show = function(){alert(this.sColor);}  
}  
 
classA.prototype.say = function(){  
  alert("hello ..");  
}  
 
function classB(sColor,sName){  
  classA.call(this,sColor);  
  this.sName = sName;  
}  
 
classB.prototype = new classA();  
//note: no arguments and classB is a classA  
//只有此行后才可以给classB增加自己的属性和方法,否则会发生覆盖  
classB.prototype.showName = function(){  
  alert(this.sName);  
}  
var a = new classA("blue");  
a.show();//output blue  
a.say(); // output hello..  
var b = new classB("red","BMW");  
b.show(); // output red  
b.say(); //output hello..  
b.showName();//output BMW 
function classA(sColor){
  this.sColor = sColor;
  this.show = function(){alert(this.sColor);}
}

classA.prototype.say = function(){
  alert("hello ..");
}

function classB(sColor,sName){
  classA.call(this,sColor);
  this.sName = sName;
}

classB.prototype = new classA();
//note: no arguments and classB is a classA
//只有此行后才可以给classB增加自己的属性和方法,否则会发生覆盖
classB.prototype.showName = function(){
  alert(this.sName);
}
var a = new classA("blue");
a.show();//output blue
a.say(); // output hello..
var b = new classB("red","BMW");
b.show(); // output red
b.say(); //output hello..
b.showName();//output BMW

总结:通过以上几种方式多可以实现在Javascript中的继承,只有原型链这种方式不然实现多继承,但其优点在于classB的任何对象多属于classA,classB这两个类。

     

 

本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/gaozliang2009/archive/2009/09/23/4583405.aspx

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值