標籤:ima 調試 意思 targe .com cti tool 哈哈 rip
其實呢,“函數function”和“對象object”之間還有這麼一句話:對象是通過函數來建立的,而函數卻又是一種對象。
這個函數是一種對象,上節中“Javascript之一切皆為對象1”也清楚的闡述了。
但這個對象又是通過函數來建立的,咳咳,似乎在平時代碼中也是哈。
請看下面代碼
function Fn(){}var fn =new Fn();
你可能會說,哥們,不對吧,不是我們也曾寫過如下代碼嗎!!
var obj = {};
哈,是的哈。
但是,還記得嗎?
以上代碼,其本質是這樣的:
var obj = new Object();
咦,好吧,我承認是這樣的,但是它為什麼會這麼設定呢?
prototype。
prototype?
對,還記得大明湖畔的原型鏈麼。。。
每個函數都有一個prototype屬性,且prototype是一個對象。
當我們通過函數function,(new)建立一個對象時,建立的對象的隱指標__proto__,就指向這個函數的prototype對象。
?!!在說什麼。見:
中,中間是函數Fn,函數Fn有一個prototype對象,prototype對象中,又必須有,且內建一個constructor屬性,它又是指向函數Fn本身的,“其他屬性”的意思是你自己可以通過prototype對象擴充屬性,當函數Fn構建好後,你可以通過new這個函數Fn,建立對象,如中左邊的fn、fn1,建立的對象,內建一個隱指標__proto__,它是指向函數Fn中的prototype,所以建立的所有對象的__proto__,是同時指向建立它的函數Fn的prototype對象啦。
有點沒看懂?
麼關係,我們一起來寫個demo,一步步理解。
首先,我們一起編寫一個函數Fn,並給這個函數Fn的prototype分配兩個屬性name和age,具體代碼如下:
<!DOCTYPE html> <head> <title>ttt</title> <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/> </head> <body> <script> function Fn(){ } Fn.prototype.name = ‘monkey‘; Fn.prototype.age = 24; console.log(Fn.prototype); </script> </body></html>
通過chrome調試器,可得下結果圖
大家可以看見我利用console.log(Fn.prototype),是輸出了age和name,但還有constructor和__proto__,我代碼中是沒有寫的,所以是prototype內建的。
constructor倒好理解了,但它怎麼會有個__proto__呢?
你上面不是說每個對象才有__proto__嗎?
是的,這個prototype也是對象哦,不要忘啦。
prototype的__proto__從可知,是指向Object,修改上面的流程圖,可得
接下來,我們再通過函數Fn,來建立兩個對象fn和fn1,代碼如下
<!DOCTYPE html> <head> <title>ttt</title> <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/> </head> <body> <script> function Fn(){ } Fn.prototype.name = ‘monkey‘; Fn.prototype.age = 24; var fn = new Fn(); var fn1 = new Fn(); console.log( fn.prototype ); console.log( fn1.prototype ); </script> </body></html>
通過chrome調試器,如下
咦,怎麼是undefined呢?!!
哈哈哈,仔細看我上面的代碼,我console的是對象fn和fn1的prototype哦!只有函數才有prototype,對象只有隱指標__proto__哦,它是指向函數Fn的prototype的哈。
修改代碼,通過chrome調試器的如下:
它們的__proto__都是指向建立它們的Fn的prototype的哈,且是同一個。這也就好理解了,為什麼它們是共用Fn的prototype了哈。
javascript之一切皆為對象2