您现在的位置是:首页 > 电脑技术查询 > web开发

JavaScript 的沿袭机制

编辑:chaxungu时间:2022-10-10 23:24:35分类:web开发

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


view plainfunction  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 plainfunction 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 plainfunction 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 plainfunction 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 plainfunction 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 plainfunction 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这两个类。