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

前言

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

而後回來迷迷糊糊睡了一會,竟然想起了週三的面試,有點小遺憾有點小觸動。閉包

此次回成都後,尚未正式找工做,我也在審視本身,想起了上次二面時候面試官問的一個問題:函數

你有神馬值得自豪的事情嗎?你有什麼能證實本身性格特色的事情嗎?學習

這個其實想讓我自我吹噓一番嘛,可是我出來工做後是有幾件出彩的事情,可是感受在他面前就說不來也不算事了,因而弱弱的說了一下本身堅持寫了3個月的博客了。ui

可是在他看來,3個月彷佛不算事。。。其實想想3個月確實不算什麼,轉瞬即逝。我還有不少不懂的東西,各個方面。this

因此下週我仍是應該找一個工做安定下來,認認真真作一兩個產品,而後堅持把今年的博客寫完先!但願下次被人問到這個問題時候我能夠自豪的說,我天天都堅持學習了2,3個小時,而且分享出來了博客,而且以此爲樂。spa

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

好了,廢話結束,進入咱們下午的學習吧,咱們此次又來看看咱們的prototype吧,面向對象我又來了,由於這個東西前面咱們就寫過代碼,這裏直接上重點。指針

原型鏈

咱們建立的每個函數都包含一個prototype(原型)屬性。
他是一個指針,指向一個對象,這個對象是包含能夠由特定類型的全部實例共享的屬性和方法。
通俗點:prototype就是一模板,新建立的模板就是對他的一個拷貝

每一個prototype對象又會包含一個constructor屬性,該屬性意義不大,並且常常被覆蓋,可是他是指向構造函數的,咱們在類型判斷的地方也許用獲得。code

建立新實例後,實例內部包含一個[[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:我暫時找不到好的題目了,若您有好的題目,請留下

結語

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

相關文章
相關標籤/搜索