趁着昨天剛看完JavaScript原型鏈,來擼一發知識點。
首先,對象是函數創建的。
<script type="text/javascript">
var obj = new Object();
alert(typeof obj);//1、彈出object
alert(typeof Object);//2、彈出function
alert(Object instanceof Object);//3、彈出true
</script>
根據以上代碼,我們可以知道obj是Object創建的實例,那麼Object是啥呢,通過typeof我們可以發現Object是function,那麼我們可以得出結論,obj作爲一個對象,是函數創建的。
那麼3是什麼意思呢,instanceof不是前面是實例後面是對象麼,你剛剛不是說Object的type是function麼,對,Object它是function,它也是對象,爲啥?首先,對象是啥,Js裏的對象不像C\C++\Java中的類和對象定義的那麼嚴格,Js中的對象是十分靈活的,Js中的對象總結的來說就是屬性的結合。那麼我們剛剛說Object是對象,你有啥依據呢,我們看看下面這段代碼
<script type="text/javascript">
Object.a = "I am content of a";
Object.b = "I am content of b";
alert(Object.a+"\n"+Object.b);//會彈出I am content of a
// I am content of b
</script>
看到沒有,我把Object當對象來使,然後給它搞了倆個屬性a和b,然後分別還賦了值,然後alert彈出發現確實彈出了,由此可以斷定Object它也是一種對象。
寫到這,想起很多Js大神說起過,Js中一切皆對象。
下面開始談Js對象裏有一個默認屬性,是的,Js的對象都有默認屬性__proto__,我們剛剛也說了函數也是對象,那麼創建對象的函數也都有默認屬性prototype,那麼對象的__proto__和函數的prototype有啥關係呢?
對象的__proto__指向創建該對象的函數的prototype,拿上面的代碼舉例就是說obj.__proto__ === Object.prototype
這個就是原型鏈的最爲基本的原則,對象的__proto__指向創建該對象的prototype,我們可以把它想象成一條鏈,以後這條鏈將幫助我們尋找變量
再舉個例子:
<script type="text/javascript">
var obj = new Object();//創建obj對象
obj.a = "value of a";
obj.b = "value of b";
alert(obj.c);//彈出undefined
Object.prototype.c = "value of c";
alert(obj.c);//彈出"value of c"
</script>
顯然第一次彈出undefined是因爲沒有給obj添加屬性c,調用obj的c那肯定是會出現undefined
但是後來,Object.protype也是個對象,我給它添加了一個屬性c,然後再彈出obj,c卻彈出了創建它的函數的原型的屬性c的值(Object函數的prototype的屬性c的value值),這是爲啥呢?obj對象中不是沒有屬性c麼?
問題的答案就在上文提到的這條鏈:對象obj的__proto__指向創建它的函Object數的prototype,那麼當我們調用obj對象的屬性c不存在的時候,Js引擎就會循着obj的這條原型鏈找到Object的prototype,prototype裏有這個屬性c,然後拿過來用,嗯,原理就這樣。