在開發(fā)中:有可能構(gòu)造函數(shù)B要是用構(gòu)造函數(shù)A中的一些方法和屬性规哲。這個時候要使用繼承來拓展B
//創(chuàng)建一個構(gòu)造函數(shù)Obj
function Obj(){
this.country="中國";
this.state="廣東"
}
//創(chuàng)建一個人的構(gòu)造函數(shù)
function Person(name,age,sex){
this.name=name;
this.age=age;
this.sex=sex;
}
1:使用 call apply來實現(xiàn)
// function Person1(name,age,sex){
// Obj.call(this,arguments) //在這個Person的構(gòu)造函數(shù)中添加這一段代碼 這里有一個疑問是arguments
不寫的話也可以使用忱反,但是我這里創(chuàng)建的時候如果想修改 Obj里面的屬性怎么辦钠乏?比如我想修改一個國
家為加拿大的?
// this.name=name;
// this.age=age;
// this.sex=sex;
// }
// var oneman=new Person1('韓梅',20,'女');
// console.log(oneman); //Person1 {country: "中國", state: "廣東", name: "韓梅", age: 20, sex: "女"}
2:改寫prototype的指向
// Person.prototype=new Obj(); //這里把Person這個構(gòu)造函數(shù)的原型指向了一個Obj的實例吵血。(復(fù)雜數(shù)據(jù)
類型:內(nèi)存上的指針改變)Person上就帶有了Obj的屬性和方 法,但這個時候我
們要是new Person就相當(dāng)與new Obj 沒有name age sex這些屬性
// Person.prototype.constructor=Person;
// var aa=new Person('李磊',30,'男');
// console.log(aa); //Person {name: "李磊", age: 30, sex: "男"} 發(fā)現(xiàn)在屬性上并沒有 country和state
// console.log(aa.state); // 廣東 但是能打印出來。也就是說他是存在的~但是存在在原型鏈上坦弟,不暴露在
外面
3.接下來阮一峰又給了一個坑~
//從性能上來考慮country和state在Person上并不要求他做修改。那么也就不需要創(chuàng)建Obj的實例消耗內(nèi)存官地,
把它放到原型鏈上就可以
// function Obj(){};
// Obj.prototype.country="中國";
// Obj.prototype.state="廣東";
// console.log(Obj.prototype.constructor);
// Person.prototype=Obj.prototype;
// console.log(Person.prototype.constructor);
// Person.prototype.constructor=Person; //這里改變了原型的構(gòu)造函數(shù)指向酿傍,重新指向了Person
// var bb=new Person('趙洋',30,'男的');
// console.log(bb);
// console.log(Obj.prototype.constructor); //function Person(name,age,sex){} 為什么Obj的構(gòu)造函數(shù)成了Person?
答案:因為在復(fù)雜數(shù)據(jù)類型中 他們指向了同一個內(nèi)存地址驱入,Person重新設(shè)定constroctor后 同一個內(nèi)存地址的Obj.prototypr也發(fā)生了改變赤炒。 生活中的例子是這兩個人合租在一個房間里面,A改變了房間內(nèi)的布局亏较,B回來的時候看到的還是原來的房間布局么莺褒??雪情?
4.利用空對象做為容器遵岩、橋梁
function Objj(){ }
Objj.prototype.country="中國";
Objj.prototype.state="廣東";
// var F = function(){};
// F.prototype = Objj.prototype;
// Person.prototype = new F();
// Person.prototype.constructor = Person;
// console.log(Objj.prototype.constructor); // function Objj(){ }
// var aaa=new Person('ni',50,'boy')
// console.log(aaa.country);
//上面這段代碼的核心在于 如何讓兩個prototype不指向通一個內(nèi)存地址。那我們就在內(nèi)存里面開辟一個新的地址來作為中轉(zhuǎn)站巡通,不影響其他地址尘执。結(jié)果就是創(chuàng)建一個實例,因為實例對象開辟了新的內(nèi)存地址 相當(dāng)于第2個方法 下面開始把上面的代碼封裝一下
function extend (Child,Parent){
var F=function(){};
F.prototype=Parent.prototype;
Child.prototype=new F();
Child.prototype.constructor=Child;
Child.uber=Parent.prototype; //保存父級原型鏈上的屬性和方法 以便與后期在Child中進(jìn)行操作
}
//5.拷貝繼承 也就是遍歷以后重新賦值
function entend2(Child,Parent){
var a=Child.prototype;
var b=Parent.prototype;
for(var i in b){
a[i]=b[i]
}
}
//如果Child的原型鏈上有和Parent原型鏈上相同的屬性或者方法 會被Parent給替換掉
Person.prototype.state='正確';
entend2(Person,Objj);
var ccc=new Person('報告大王',100,'妖精');
console.log(ccc.state); //廣東