前言
中午時候我去葯店稱了下體重,好家伙!我減肥成功了,足足比上個月瘦了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'); //true 3 var s3 = y.hasOwnProperty('id'); //false 4 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:我暫時找不到好的題目了,若您有好的題目,請留下
結語
今天做了一次回顧,下面點再學習其它知識吧,現在先去吃個飯吧。