首先來(lái)了解一段代碼
function Person(name,age){
this.name = name;
this.age = age;
this.sayHello = function(){
console.log(this.name +"say hello");
}
}
var boy = new Person("bella",23);
boy.sayHello(); // bella say hello
什么是構(gòu)造函數(shù)炊豪?
var sum3=new Function('n1','n2','return n1+n2')
console.log(sum3(2,3));//5
構(gòu)造函數(shù)的特點(diǎn):
a:構(gòu)造函數(shù)的首字母必須大寫(xiě),用來(lái)區(qū)分于普通函數(shù)
b:內(nèi)部使用的this對(duì)象牵舱,來(lái)指向即將要生成的實(shí)例對(duì)象
c:使用New來(lái)生成實(shí)例對(duì)象
構(gòu)造函數(shù)的缺點(diǎn):
所有的實(shí)例對(duì)象都可以繼承構(gòu)造器函數(shù)中的屬性和方法缺虐。但是,同一個(gè)對(duì)象實(shí)例之間,無(wú)法共享屬性
解決思路:
a:所有實(shí)例都會(huì)通過(guò)原型鏈引用到prototype
b:prototype相當(dāng)于特定類(lèi)型所有實(shí)例都可以訪問(wèn)到的一個(gè)公共容器
c:那么我們就將重復(fù)的東西放到公共容易就好了
function Person(name,age){
this.name = name;
this.age = age;
this.sayHello = function(){
console.log(this.name + "say hello");
}
}
var girl = new Person("bella",23);
var boy = new Person("alex",23);
console.log(girl.name); //bella
console.log(boy.name); //alex
console.log(girl.sayHello === boy.sayHello); //false
一個(gè)構(gòu)造函數(shù)Person生成了兩個(gè)對(duì)象實(shí)例girl和boy,并且有兩個(gè)屬性和一個(gè)方法顷牌。但是sayHello方法是不一樣的塞淹。如上圖(圖畫(huà)得很丑)。也就是說(shuō)當(dāng)New一個(gè)實(shí)例對(duì)象的時(shí)候运挫,都會(huì)去創(chuàng)建一個(gè)sayHello方法套耕,這就浪費(fèi)了內(nèi)存資源谁帕,因?yàn)閟ayHello方法使一樣的行為的冯袍,完全可以被兩個(gè)實(shí)例對(duì)象共享。
所以儡循,缺點(diǎn)就是:同一個(gè)構(gòu)造函數(shù)的對(duì)象實(shí)例之間無(wú)法共享屬性和方法征冷。
為了解決構(gòu)造函數(shù)的這個(gè)缺點(diǎn),js提供了prototype屬相來(lái)解決該問(wèn)題资盅。
propotype屬性的作用
js中每個(gè)數(shù)據(jù)類(lèi)型都是對(duì)象踊赠,除了null 和 undefined,而每個(gè)對(duì)象都是繼承自一個(gè)原型對(duì)象,只有null除外今穿,它沒(méi)有自己的原型對(duì)象伦籍,最終的Object的原型為null
eg3
function Person(name,age){
this.name = name;
this.age = age;
}
Person.propotype.sayHello = function(){
console.log(this.name + "say hello");
}
var girl = new Person("bella",23);
var boy = new Person("alex",23);
console.log(girl.name); //bella
console.log(boy.name); //alex
console.log(girl.sayHello === boy.sayHello); //true
由上圖可以看出,propotype是構(gòu)造函數(shù)的屬性帖鸦,而consructor則是構(gòu)造函數(shù)的prototype屬性所指向的那個(gè)對(duì)象,也就是說(shuō)constuctor是原型對(duì)象的屬性洛二。
constructor屬性是定義在原型對(duì)象上面,意味著也可以被實(shí)例對(duì)象繼承
function Person(name,age){
this.name = name;
this.age = age;
}
Person.propotype.sayHello = function(){
console.log(this.name + "say hello");
}
var girl = new Person("bella",23);
console.log(girl.construcotr); //Person()
console.log(girl.construcotr == Person.propotype.construcotr); //true
constructor屬性的作用
a:分辨原型對(duì)象到底是哪個(gè)構(gòu)造函數(shù)
function Person(){};
var person1 = new Person();
console.log(person1.construcotr === Person); //true
b:從實(shí)例新建另一個(gè)實(shí)例
function Person(){};
var person1 = new Person();
var person2 = new person1.construcotr();
console.log(person2 instanceof Person); //true
c:由于constructor屬性是一種原型對(duì)象和構(gòu)造函數(shù)的關(guān)系妓雾,所以在修改原型對(duì)象的時(shí)候垒迂,一定 要注意construtor的指向問(wèn)題械姻,避免instanceof失真机断,關(guān)于這一點(diǎn),會(huì)在繼承中講到唯竹。
原型(prototype)
了解了構(gòu)造器苦丁,我們來(lái)看下原型prototype
JS中萬(wàn)物都是對(duì)象,但是對(duì)象也分為:普通對(duì)象和函數(shù)對(duì)象旺拉,也就是Object 和 Function.
那么怎么區(qū)分普通對(duì)象和函數(shù)對(duì)象呢? ---凡是通過(guò)New Function()創(chuàng)建的對(duì)象都是函數(shù)對(duì)象晋涣,其他的都是普通對(duì)象.
var sum3=new Function('n1','n2','return n1+n2')
console.log(sum3(2,3));//5
需要注意的是:普通對(duì)象沒(méi)有propotype(prototype即是屬性也是對(duì)象)沉桌,但是有proto屬性谢鹊。
js創(chuàng)建對(duì)象的時(shí)候都有一個(gè)propo內(nèi)置屬性留凭,用于指向創(chuàng)建它的函數(shù)對(duì)象的原型對(duì)象prototype。
我們還是來(lái)根據(jù)eg3的代碼來(lái)分析原型鏈
console.log(girl.proto === Person.protype);//true
console.log(Persion.propotype.proto === Object.propotype);//true
console.log(Object.porpotype.proto); //null
通過(guò)proto串起來(lái)直到Object.propotype.proto為null的鏈叫做原型鏈(矩形表示函數(shù)對(duì)象兼耀,橢圓形表示普通對(duì)象)
也許看到這個(gè)圖會(huì)有幾個(gè)疑問(wèn)
a:為什么Object.proto指向Function.prototype?
Object是函數(shù)對(duì)象求冷,是通過(guò)new Function()創(chuàng)建的,所以...
b:Function.proto === Function.prototype //true
Function也是對(duì)象函數(shù)拯坟,通過(guò)new Function()創(chuàng)建韭山,所以...
轉(zhuǎn)載于快餓死的魚(yú)