原型是js中的難點加重點,也是前端面試官最愛問的問題之一,因為面試官可以通過被面試者對原型的理解、來判斷被面試者對js的熟悉程度。
原型的定義
Js所有的函數都有一個prototype屬性,這個屬性引用了一個對象,即原型對象,也簡稱原型。這個函數包括構造函數和普通函數,我們講的更多是構造函數的原型,但是也不能否定普通函數也有原型。
先看一下普通函數的原型
例如:
function animal(){ } //這個函數就有原型屬性,引用的對象就是object
今天看了一個視頻,那位老師講的很清晰,在此感謝自學網的燕18老師!
接下來,我們通過一個構造函數的例子來了解原型。
function animal(){ this.name = function(){ document.write("我有名字<br/>"); } } function cat(){ this.climb = function(){ document.write("我會爬樹<br/>"); } } function tiger(){ this.type = function(){ document.write("我是一直虎<br/>"); } } cat.prototype = new animal();//這里就是繼承 tiger.prototype = new cat(); var smtiger = new tiger(); smtiger.climb();//這里輸出“我會爬樹”
smtiger.name(); //這里輸出“我有名字”
我們new了一個對象小虎smtiger對象,而且在tiger的構造函數中只有一個type,它不會爬樹,也沒有名字;
但是!!!通過原型,tiger繼承了cat,cat又繼承了animal,所以:小虎會爬樹,也有了名字。
js雖然沒有類,但是卻是面向對象的一門腳本語言,就是因為它可以通過prototype來實現繼承
這樣只看表面很不切實際,也很難理解,接下來分析一下具體的prototype和_proto_的關系
1、tiger()構造函數new一個tiger對象--》這個對象的_proto_指向cat對象,tiger()構造函數的prototype指向cat對象;
2、cat()構造函數new一個cat對象--》這個對象的_proto_指向animal對象,cat()構造函數的prototype指向animal對象;
3、animal()構造函數new一個animal對象--》這個對象的_proto_指向一個普通的object(也就是js的object“個人理解”),animal()構造函數的prototype指向普通的object對象,這個object對象有constructor的構造函數,指向animal(),所以anima其實是轉了一圈又回來指向自己,表現為aniaml;
4、object()new一個obj對象--》這個對象的_proto_指向系統的object(應該就是window“個人理解”),object()的prototype指向系統的object對象;
5、系統的object對象指向null。