1.原型對(duì)象與構(gòu)造函數(shù)
無(wú)論什么時(shí)候,創(chuàng)建了一個(gè)函數(shù)后。
1.函數(shù)擁有propertype屬性。值為這個(gè)函數(shù)的原型對(duì)象的指針。
2.同時(shí)對(duì)于原型對(duì)象,其擁有constructor就指向原來(lái)的函數(shù)(什么值類型的)
3.原型對(duì)象開始只獲得constructor屬性(默認(rèn)的)。
4.用構(gòu)造函數(shù)構(gòu)造對(duì)象,實(shí)例也會(huì)有prototype: 指向原型對(duì)象
function Person() {
}
//這里做了兩件事。PS中指向了一個(gè)原型對(duì)象prototype.而原型對(duì)象也GET到了constructor屬性和其他一堆屬性。
Person.prototype.name = '原型名'
Person.prototype.age = '原型年紀(jì)'
Person.prototype.job = '原型小白鼠'
Person.prototype.sayname = function () {
alert(this.name)
}
console.log(Person.prototype.isPrototypeOf(person1)) //返回true
var person1 = new Person();
//這里新建了一個(gè)person1對(duì)象,并且構(gòu)造函數(shù)作用域指向新對(duì)象,執(zhí)行構(gòu)造函數(shù)的代碼,返回新對(duì)象。
1.1為了簡(jiǎn)潔而重寫原型對(duì)象
function Person() {
}
//原型對(duì)象用字面量形式創(chuàng)建,實(shí)際上constructor就變成了Object.
Person.prototype ={
name : '原型名',
age : '原型年紀(jì)',
job : '原型小白鼠',
sayname : function(){
alert(this.name);
}
}
var person1 = new Person();
重寫之后要注意,在重寫之前新建的實(shí)例還是指向原來(lái)的原型對(duì)象的。
1.2原型對(duì)象的弊端
- 沒有傳參數(shù),創(chuàng)建出來(lái)的所有實(shí)例屬性都是共享的。
- 當(dāng)原型對(duì)象中屬性不是基本值,而是引用值得時(shí)候。我們?cè)趯?shí)例中訪問該屬性,然后指向了該引用,如果是賦值還好,會(huì)直接覆蓋。如果是對(duì)該引用指向的對(duì)象做操作,那么就會(huì)引起原型被更改,造成所有勢(shì)力屬性的變化。
1.3構(gòu)造與原型并用
- 構(gòu)造函數(shù)太復(fù)雜,復(fù)用性太差。
- 原型復(fù)用性高,但所有屬性全共享了。
為了解決以上的問題,我們兩種方法混用。
構(gòu)造函數(shù)中 寫入一些比較個(gè)性化的屬性。而在原型對(duì)象中保存一些共享的屬性和方法。
還有幾種構(gòu)造函數(shù)模式未總結(jié)
2. 繼承:原型鏈
基本思想是利用原型讓一個(gè)引用類型繼承另外一個(gè)引用類型的屬性和方法。
2.1原型鏈細(xì)節(jié)
例子:
- 建立一個(gè)超集函數(shù)(超集的原型),一個(gè)子集函數(shù),并且子集函數(shù)的實(shí)例(新對(duì)象)是通過new超集函數(shù)構(gòu)建起來(lái)的(意味著新對(duì)象的原型是超集的原型)。
function 超集函數(shù)(){
this.property = true;
this.age = '1';
}
超集函數(shù).prototype.getSuperValue = function(){
return this.property;
};
超集函數(shù).prototype.name = '我是超級(jí)原型函數(shù)對(duì)象'
function 子集函數(shù)(){
this.subproperty = false;
}
//inherit from 超集函數(shù)
子集函數(shù).prototype = new 超集函數(shù)();
子集函數(shù).prototype.name = '我是子集原型'
子集函數(shù).prototype.getSubValue = function (){
return this.subproperty;
};
console.log(子集函數(shù).prototype)
console.log((超集函數(shù).prototype))
console.log(超集函數(shù).prototype.isPrototypeOf(子集函數(shù).prototype)) //true.
3.練習(xí)題
function foo(){
foo.abc = function (){console.log('456')}
this.def = this.abc;
this.abc = function(){console.log('def')}
abc = function(){console.log('@@@@@')}
var abc = function () {console.log('$$$$$')}
}
foo.abc = function () {
console.log('123')
}
foo.prototype = {
abc : function (){console.log('abc')}
}
foo.abc();// 123
var f = new foo();
f.def();//abc
f.abc();//def
foo.abc()//456