原型:每一個函數(構造器)都有一個prototype屬性,prototype自己又是一個對象,prototype對象有一個constructor屬性,constructor屬性又是函數的函數指針,所以指向函數,所以函數和prototype之間相互引用。java
原型鏈:app
每一個由構造器實例化的對象都有一個__proto__屬性,該屬性指向構造器的prototype屬性,所以經過原型模擬了java中的類。函數
prototype對象也有一個__proto__屬性,指向父類的prototype對象,下面的例子父類的prototype對象即爲object prototype。this
function a(name, psd){
this.name = name;
this.psd = psd;
}
a.prototype = {
qq: '123456'
}
var obj = new a('ly', '123');prototype
console.log(obj.name); //ly
console.log(obj.psd);//123
console.log(obj.qq);//123456指針
obj的__proto__指向prototype對象,而a prototype對象的constructor屬性又指向構造器a,a prototype對象的__proto__ 屬 性又指向Object對象的prototype對象即object prototype。對象
當咱們訪問一個實例對象的屬性是,編譯器尋找屬性的順序是:繼承
一、找自身的屬性 二、尋找對象原型的屬性 三、尋找父類對象原型的屬性 四、直到Object對象原型的屬性 五、找不到,返回undefined原型鏈
注意:每一個實例化對象有自身私有的屬性,也有公用屬性即__proto__ 原型
繼承的方式:
一、構造繼承法
function a(name, psd){
this.name = name;
this.psd = psd;
}
function b(name, psd, qq){
a.apply(this,arguments);
//a.call(this, name, psd, qq)
this.qq = qq;
}
a.prototype = {
constructor: a,
day: 1
}
var obj = new b('ly','123','123456');
console.log(obj.name); //ly
onsole.log(obj.psd);//123
onsole.log(obj.qq);//123456
ole.log(obj.day);//undefined
二、原型繼承法
經過複製已經存在的原型對象來實現行爲重用,讓實例對象共享原型對象的屬性。這裏是公有的。
function a(name, psd){
this.name = name;
this.psd = psd;
}
a.prototype.qq = '123456';
function b(){
}
b.prototype = new a('ly', '123');
var obj = new b();
console.log(obj.name); //ly
console.log(obj.psd); //123
console.log(obj.qq); //123456
三、拷貝繼承法
function a(){
this.num=123;
this.say=function(){
alert("happy new year!");
}
}
function b(){
this.extends=function(obj){
for(each in obj){
this[each]=obj[each];
}
}
}
var oB=new b();
oB.extends(new a());
alert(oB instanceof a); // false
alert(oB.num); // 123
oB.say(); // happy new year
四、臨時變量法
function a(){ this.num=123; } function b(){ this.temp = a; this.temp(); } var obj = new b(); console.log(obj.num)//123