js中对象的继承

//js中对象的继承
//1.对象冒充(js中没有访问修饰符的概念)_可以实现多继承(但会出现干扰,如果父类a和父类b中都定义了同名的属性或方法,后面的继承就会把前面的给替换掉了)不推荐

function Parent(username){
       this.username=username;
       this.sayHello=function(){
              alert(this.username);
       }
}
function Child(username,password){//间接地实现了this的传递
       //下面三行代码是最关键的
       this.method=Parent;//将method属性指向父对象
       this.method(username);//这就相当于在对象自己身上调用Parent函数,Parent的this指向了Child ******
       //调用父对象的构造方法并传入username进去,此时Child中的this也传进去了,在Parent中定义属性时所用的this对象就是在Child中传进去的,所以Parent中的this不再指向Parent,而是指向Child,在Parent对象中定义的属性直接为Child定义了(this.username变成了Child(对象).username)
       //js中的this与java中的this不一样
       delete this.method;//将method属性从Child中删除掉,因为没有用了不需要再指向Parent对象了(不删也可以)
       //上面的改为Parent(username);   --此时this没有值
       //new Parent(username);         --此时this是Parent对象
       //除了username属性,父类中的其他的属性和方法都继承过来了----因为父类中的this是子类中传进去的,所以this指向子类的对象
       this.password=password;
       this.sayWorld=function(){
              alert(this.username+", "+this.password);
       }
}
var parent=new Parent("lisi");
parent.sayHello();
var child=new Child("zhangsan","12322");
child.sayHello();//继承过来的方法
child.sayWorld();

//理解:

理解这儿需要的知识是 成员方法中this的指代 this定义成员 直接给对象添加成员
function ClassB(sColor)//把此函数看作构造函数
{
  this.newMethod = ClassA; //字面意思,定义成员方法,把函数ClassA作为成员方法
  this.newMethod(sColor); //执行成员方法,成员方法里面this指代类的实例,该方法给该实例添加了color,sayColor两个成员,不是你想的得到了ClassA的成员 
  delete this.newMethod; //此方法已经执行,删不删都一样,不影响属性的添加,区别只在构造出的对象中是否存在该方法,如果不删除,还可以在实例中调用该方法,修改那两个成员的值
}


下面的写法能有同样效果,可以帮助你理解:
function ClassB(sColor)//把此函数看作构造函数
{
  this.newMethod = ClassA; //字面意思,定义成员方法,把函数ClassA作为成员方法
}
var objB=new ClassB();
objB.newMethod("red");//在对象中调用该方法,同样可以给对象添加那两个成员,原写法在构造函数中调用只是调用时间的区别,实质是相同的,能理解么?
alert(objB.color);

引自:   wzs_xyz的回答: http://bbs.csdn.net/topics/380244195

//2.call方法方式,call方法是定义在Function对象中的方法,因此我们定义的每一个函数都拥有call方法,可以通过函数名里调用call方法,call方法的第一个参数会被传递给函数中的this从第二个参数开始,逐一赋值给函数中的参数
function test(str,str2){
       alert(this.name+", "+str+", "+str2);
}
//var object=new Object();
//object.name="zhangsan";
//object.method=test;
//object.method("lisi");
//delete object.method;//使用实例对象也可以实现对象冒充(不仅仅是在对象的定义中,可以动态的让一个对象继承另一个对象)


var object =new Object();
object.name="zhangsan";
test.call(object,"shengsiyuan","hello");//将object赋给了test对象中的this--第一个参数永远会传给this对象

//call方式继承(用的比较多)
function Parent(username){
       this.username=username;
       this.sayHello=function(){
              alert(this.username);
       }
}
function Child(username,password){
       Parent.call(this,username);//把this(child)对象传给Parent--在Child中调用Parent的call方法
       this.password=password;
       this.sayWorld=function(){
              alert(this.password);
       }
}
var parent=new Parent("zhangsan");
var child=new Child("lisi","123");
parent.sayHello();
child.sayHello();
child.sayWorld();

//3.apply方法方式,也是Function对象的方法
function Parent(username){
       this.username=username;
       this.sayHello=function(){
              alert(this.username);
       }
}
function Child(username,password){
       Parent.apply(this,new Array(username));//第一个参数跟call的第一个参数是一模一样的含义,表示将第一个参数传递给Parent对象中的this对象;第二个参数有差异:以数组的形式将参数传递给Parent
       this.password=password;
       this.sayWorld=function(){
              alert(this.password);
       }
}
var parent=new Parent("zhangsan");
var child=new Child("lisi","123");
parent.sayHello();
child.sayHello();
child.sayWorld();

//4.原型链(prototype chain)方式实现对象的继承,缺点:无法给构造函数传入参数为属性赋值
function Parent(){

}
Parent.prototype.username="zhangsan";
Parent.prototype.sayHello=function(){
       alert(this.username);
}
function Child(){

}
Child.prototype=new Parent();//让子类的prototype指向父类的对象
Child.prototype.password="123";
Child.prototype.sayWorld=function(){
       alert(this.password);
}
var child=new Child();
child.username="lisi";
child.password="123";
child.sayHello();
child.sayWorld();

//5.混合方式(推荐)--对于每一个对象都有各自的属性,各个对象的属性之间不会相互干扰;每个对象共享同一个方法

function Parent(hello){
       this.hello=hello;
}
Parent.prototype.sayHello=function(){
       alert(this.hello);
}
function Child(hello,world){
       Parent.call(this,hello);//因为Parent对象的sayHello方法不是通过this对象定义的,所以只能继承属性
       this.world=world;
}
//var parent=new Parent();
//Child.prototype=parent.prototype;//---这样不可以实现,只能为Child的prototype赋Parent对象
Child.prototype=new Parent();
Child.prototype.sayWorld=function(){
       alert(this.world);
}

var child=new Child("zhangsan","293472");
child.sayHello();

child.sayWorld();


发布了38 篇原创文章 · 获赞 6 · 访问量 11万+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章