iT邦幫忙

2019 iT 邦幫忙鐵人賽

DAY 6
1
Modern Web

一步一腳印-紮紮實實學es6系列 第 6

javascript 一定得懂的物件概念 (4)constructor,prototype,__proto__ 的糾葛

文章被我玩到全沒了 …已哭

下次要記得先存草稿><

var Paul=new Person('Paul','36');
console.log(Person.__proto__===Function.constructor.__proto__);
console.log(Paul.__proto__====Person.prototype);
console.log(Person.__proto__===Paul.constructor.constructor.__proto__);

今天來解決最後一個問題

一堆constructor 看得霧裡看花

我們先拿 window 裡面的建構函式來玩玩看

我們的 Array Function Object
大寫開頭的可都是建構函式
我們使用的function 雖然沒有用new 但是卻都是他們的孩子
我們可以老老實實的用用看
https://ithelp.ithome.com.tw/upload/images/20181006/20110579PcdfnuMDsO.png

欸你說,明明console.dir(Object)
他就說是個 Object 阿!? 哪裡是函式?
騙肖哦?
兄弟…你看看他回應的是不是 有一個藍藍的f ,後面帶著小括弧呢?
「對欸!」
那就是函式啦!
點進去看,還能看到 prototype 對咪?
「對欸!」
那就是建構函式啦

好了,有了基本的共識之後

我們就new 一個array 來玩玩

var arrayA=new Array();

這邊來用一個js 好用的工具,instanceof !
他可以讓我們來檢驗我是誰生的

arrayA instanceof Array; //魔鏡阿魔鏡,arrayA 是不是Array 的實例呢?

https://ithelp.ithome.com.tw/upload/images/20181007/20110579LINdF7g2cF.png
果然是true !
Array此時熱淚盈眶,終於找到失散多年的親人了

但其實我們根本就js 神好嗎,不需要這個工具也能透視他們的dna!
讓我們來扒開這個arrayA!
捨摩你說要扒開要先裝葉克膜?我又不是要活摘器官!$%^&^&

讓我們看看裡面的內容,並注意一下裡面的 __proto__
https://ithelp.ithome.com.tw/upload/images/20181006/20110579q8qMT6H363.png

看到沒有,裡面有個昨天介紹的constructor!
constructor 說 他的爸爸是Array!
好那讓我們來把這2個人抓出來實驗一下
https://ithelp.ithome.com.tw/upload/images/20181006/20110579rY00E6W3w6.png
嗯~ 果然沒錯!
所以我們用 constructor就可以找到爸爸是誰嘍

咦,我好像想到什麼?!
來看看兩者的prototype 是否也相同呢?
https://ithelp.ithome.com.tw/upload/images/20181006/20110579biNP7SfhIT.png
非常好!
那麼跟昨天的內容做連結!
https://ithelp.ithome.com.tw/upload/images/20181006/20110579Svf9iw212Y.png
你發現什麼了嗎?
仔細瞧瞧這些程式

arrayA.constructor.prototype===Array.prototype;
arrayA.__proto__===Array.prototype;

領悟到什麼了嗎!!
https://ithelp.ithome.com.tw/upload/images/20181006/20110579Q53vUA2M2p.png

聰明的你是否發現 黃色標的部份可以相等!!

https://ithelp.ithome.com.tw/upload/images/20181006/20110579VFPmCQHxKH.png
沒有錯其實 __proto__ 就是 constuctor.prototype 哦
他們2個所指的位址是一樣的

所以用 __proto__
可以指向爸爸的prototype!
但我們通常不去操作__proto__ 一般這通常是瀏覽器去控制的

咦,那有人好奇我為什麼打文章打到一半
全部消失嗎?
好,沒有人好奇,但我還是要說一下
我們來操作一下 Array 爸爸的 protoype
昨天有說爸爸放在 prototype 的遺產 就是兒子都可以用的對吧
所以我們來修改看看 Array.prototype..

Array.prototype.push=null;

很好,大家趕快去打一下,相信你如果在打文章的話,很快就掛了
所以鐵人幫幫忙有用到push XDD
(先來存檔再來截圖)
https://ithelp.ithome.com.tw/upload/images/20181007/20110579yvxXSW17eK.png

這次學聰明了,用firefox 來操作 XDDD
所以我們不要去修改內建的建構函式哦!! 除非你想搞你的同事

====
總合今天所學

有辦法解出開頭講的例子嗎?

console.log(Person.__proto__===Paul.constructor.constructor.__proto__); //這到底3小

考驗觀念的時候到了!
不排除當面試題

讓我們來拆解一下

//先創建物件
var Person=function(){}
var Paul=new Person();


//檢驗一下Paul.constructor
Paul.constructor===Person
//true
//咦既然這步等,那下一個constructor也會相等嘍
Paul.constructor.constructor===Person.constructor 
//true
Paul.constructor.constructor.__proto__===Person.constructor.__proto__
//true 你說這不就是廢話嗎
//沒錯,所以我們把問題簡化成 我們要找一下Person.constructor.__proto__ 到底是什麼呢?
//我們知道 Person 是由 Function創建出來的一個實例
Person.constructor===Function
//true
Person.constructor.prototype===Function.prototype
//true  
//矮由 ,好像越湊越像了,那我們又知道  實例的.constructor.prototype=建構期式的prototype
Person.__proto__===Function.prototype
//true 湊出來啦 原來就是你這滑頭 Function.prototype
Paul.constructor.constructor.__proto__===Function.prototype
true
//故得證
Person.__proto__===Paul.constructor.constructor.__proto__

好啦 通常沒人會這麼無聊去操作constructor.constructor
不過相信證的出來的你,這邊就已經打通原型鏈的概念嘍
接下來我們得討論一下this ,才方便後面的學習

畢竟javascript 全部都是物件嘛
說明完this 之後,再讓我們來學習es6 的物件導向是怎麼做的
class 是語法糖? 怎麼個糖法呢?
讓我們拭目以待!


上一篇
javascript 一定得懂的物件概念(3) 原型鏈
下一篇
this (1)入門
系列文
一步一腳印-紮紮實實學es630
0
神Q超人
iT邦新手 2 級 ‧ 2018-10-07 00:04:02

全沒的痛苦我懂/images/emoticon/emoticon02.gif
期待完整版的文章!

0
Paul.Ciou
iT邦新手 5 級 ‧ 2018-10-07 01:00:31

你懂的 /images/emoticon/emoticon02.gif

0
Luis-Chen
iT邦新手 4 級 ‧ 2018-10-07 13:34:59

最近剛好也想研究JS比較底層的觀念,還請多多指教了

0
史帝夫
iT邦新手 5 級 ‧ 2018-10-08 11:24:46

總算揭開這層神祕面紗 XD
/images/emoticon/emoticon12.gif

arrayA.__proto__===Array.prototpe;//少了y, prototpe => prototype

感恩你!! 已更正/images/emoticon/emoticon07.gif

我要留言

立即登入留言