JS筆記1——建構函式、原型鏈
技術標籤:網站開發知識jsjavascript
說明
我基礎比較差,所以嘛,最近也在複習一些概念。可能我本身做小程式開發的,對這些用的也比較少。但是知識不復習是會忘記的,特地複習了一遍,然後再做個筆記鞏固一些。
什麼是建構函式
顧名思義建構函式那肯定就是一個函式,區別在於呼叫的方式上。
// 這是一個普通的函式
function myFun(){
console.log("myFun")
}
// 呼叫這個函式,那麼就會輸出 “myFun”
myFun();
而建構函式與普通函式的區別有兩點,第一點就是函式名稱首字母一般是大寫的,第二點就是函式呼叫方式是使用“new”。沒有錯,“new”的確是一種呼叫函式的方式,除此之外還有5種函式的呼叫方式,這邊就不詳細說明。我們先來看一下程式碼。
// 這是一個建構函式
function MyFun(){
console.log("MyFun")
}
// 呼叫這個函式,那麼就會輸出 “MyFun”
new MyFun();
那麼從呼叫結果來看,兩者似乎沒有區別。對的建構函式也是和普通的函式一樣,函式有的功能他都有,唯一區別在於返回值。使用new呼叫函式會返回一個該函式的例項,也就是一個物件。我們可以把兩個返回值輸出一下
console.log(myFun());
console.log(new MyFun());
結果如下:
這樣我們就會得出一個結論,直接呼叫一個函式是不會有返回值的,而使用new呼叫一個函式則會返回一個該函式的例項,也就是物件。那我們就可以根據這個特性,實現面向物件的變成,可以在建構函式中新增屬性和方法,每個通過new建立的例項都可以呼叫建構函式中的屬性和方法。
使用建構函式
先寫一個建構函式,實現建立時能夠有姓名和年齡的屬性,以及一個輸出自己姓名和年齡的方法
function People(name,age){
this.name = name;
this.age = age;
this.speak = function(){
console.log("我的姓名叫:"+this.name+",年齡:"+this.age);
}
}
// 建立一個例項
let zs = new People("張三",20);
// 我們把它輸出一下
console.log(zs);
// 再嘗試呼叫一下例項中的方法
zs.speak();
結果如下:
這樣我們就實現了能夠動態建立有自己名字和年齡和方法的建構函式,但是這樣也是有缺點的。當我們的方法非常多,且不是每個例項都需要用到這些方法,那麼就會造成記憶體的浪費。此時我們就需要引入 prototype 這個方法了。
原型鏈 prototype方法
什麼是prototype?我們簡單來說,就是用來向物件新增屬性和方法的方法。通過 建構函式.prototype.函式名 的方式,我們可以把函式掛載到建構函式上,但是卻不會佔用例項的記憶體,我們稱之為借用。
可以看到在以下程式碼中,我們將speak方法使用prototype方法去掛載到People中,而不直接書寫在People中。
function People(name, age) {
this.name = name;
this.age = age;
}
// 將speak方法掛載到People函式上
People.prototype.speak = function() {
console.log("我的姓名叫:" + this.name + ",年齡:" + this.age);
}
// 建立一個例項
let zs = new People("張三", 20);
// 我們把它輸出一下
console.log(zs);
// 再嘗試呼叫一下例項中的方法
zs.speak();
結果:
你會發現,屬性還在物件裡面,而方法卻不在了,而且依然可以呼叫。那麼此時我們怎麼檢視掛載的方法呢?檢視物件的_proto_屬性,你就會看到,speak方法就在裡面。
總結:
- 任意的建構函式,天生就擁有一個prototype屬性,指向一個物件。可以通過prototype.方法往裡面新增方法。
- 例項建立以後擁有_proto_屬性,可以向prototype中的物件借用方法。
- _proto_屬性中的constructor屬性則會指向創造這個例項的建構函式