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萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章