【追尋javascript高手之路04】理解prototype

來源:互聯網
上載者:User
前言

中午時候我去藥店稱了下體重,好傢夥!我減肥成功了,足足比上個月瘦了10斤!於是想減肥就去鄭州吧。。。

然後回來迷迷糊糊睡了一會,居然想起了周三的面試,有點小遺憾有點小觸動。

這次回成都後,還沒有正式找工作,我也在審視自己,想起了上次二面時候面試官問的一個問題:

你有神馬值得自豪的事情嗎?你有什麼能證明自己性格特點的事情嗎?

這個其實想讓我自我吹噓一番嘛,但是我出來工作後是有幾件出彩的事情,但是感覺在他面前就說不來也不算事了,於是弱弱的說了一下自己堅持寫了3個月的部落格了。

但是在他看來,3個月似乎不算事。。。其實想一想3個月確實不算什麼,轉瞬即逝。我還有很多不懂的東西,各個方面。

所以下周我還是應該找一個工作安定下來,認認真真做一兩個產品,然後堅持把今年的部落格寫完先!希望下次被人問到這個問題時候我可以自豪的說,我每天都堅持學習了2,3個小時,並且分享出來了部落格,並且以此為樂。

PS:其實我在睡覺時候,主要想到的是,怎麼我的機票還沒給我報銷。。。賬上沒錢啊。。。:)

好了,廢話結束,進入我們下午的學習吧,我們這次又來看看我們的prototype吧,物件導向我又來了,因為這個東西前面我們就寫過代碼,這裡直接上重點。

原型鏈
我們建立的每一個函數都包含一個prototype(原型)屬性。他是一個指標,指向一個對象,這個對象是包含可以由特定類型的所有執行個體共用的屬性和方法。通俗點:prototype就是一模板,新建立的模板就是對他的一個拷貝

每個prototype對象又會包含一個constructor屬性,該屬性意義不大,而且經常被覆蓋,但是他是指向建構函式的,我們在類型判斷的地方也許用得到。

建立新執行個體後,執行個體內部包含一個[[Prototype]]的內部屬性(指標,__proto__),指向建構函式的prototype,這個關係是你搞不掉的,我們這裡有幾個方法需要各位記住:

我們通過isPrototypeOf來確定某個對象是不是我的原型
hasOwnPrototype 可以檢測一個屬性是存在執行個體中還是原型中意思是該屬性不能是原型屬性才返回true

說了這麼多,我們來上個圖吧:

1 var Person = function (name, age) {2     this.name = name;3     this.age = age;4 };5 Person.prototype.getName = function () {6     return this.name;7 };8 var y = new Person('葉小釵', 30);

我們一般是這樣乾的,但是name與age在外邊是可以訪問的喲。

1 var s1 = Person.prototype.isPrototypeOf(y); //true;2 var s2 = y.hasOwnProperty('name'); //true3 var s3 = y.hasOwnProperty('id'); //false4 var s4 = y.hasOwnProperty('getName');//false
繼承時原型鏈的關係

我們這裡直接了,因為我們的Person函數繼承自Object建構函式,說白了就是Person的prototype是object建構函式的一個執行個體:

由於之前寫過類似的文章,這裡就不多說了。

做兩道題吧第一題
1 var proto = { a: 1 };2 function cls() { };3 var obj1 = new cls();4 cls.prototype = proto;5 //obj1.a現在是什嗎?

這裡cls是作為建構函式使用的,obj1執行個體化後其內部屬性[[Prototype]]指向cls的原型對象(這裡相當於一個複製),後面改變了建構函式的原型指向

這道題其實在勾引我們,我們很有可能就會回答說1,其實答案是undefined。因為建構函式cls建立後,其原型對象已經形成,最後只是切斷了cls和其原型的聯絡,

obj1的__proto__([[Prototype]])依舊指向原來的那個原型,而不是proto。

第二題
1 function cls() { };2 var obj1 = new cls();3 cls.prototype.a = 1;4 //obj1.a現在是什嗎?5 alert(obj1.a);

這道題與上題有所不同,雖然事後更改了原型,但是都是更改的堆上的同一對象,所以答案是1

第三題

我找到了一個閉包的題目,順便拿出來吧

1 function build() {2     var i;3     return function () { alert(i++); }4 }5 var f1 = build();6 var f2 = build();7 var s1 = f1 == f2;8 var s = '';9 //請說明:f1和f2是否是同一函數,分別調用f1() f2()會產生什麼效果。

這道題有點意思哦,為了讓其運行正常,我們給i一個1吧。

若是這裡將函數傳回值去掉的話,f1與f2就是一樣的了,但是由於裡面產生了閉包,所以f1與f2各自維護著自己的環境與閉包。

我們來理一理這道題:

5行執行時候會建立一個執行環境,以及相關範圍鏈,然後初始化arguments以及this,最後與i、以及匿名函數一起初始化形成了使用中的物件(有問題請提出

5行結束後,執行環境以及範圍鏈被回收,但是使用中的物件被留了下來。

在第六行f2初始化時,又重新執行了一次這個過程。

所以其最後調用時候所使用的使用中的物件不一致,所以兩個函數不是一個函數啦。

錯誤:我剛剛吃飯時候想了下,這裡的使用中的物件應該不包括this

PS:我暫時找不到好的題目了,若您有好的題目,請留下

結語

今天做了一次回顧,下面點再學習其它知識吧,現在先去吃個飯吧。

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.