javascript
关于javascript的原型和原型链,看我就够了(二)
溫故
創建對象的三種方式
- 通過對象直接量
- 通過new創建對象
- 通過Object.create()
js中對象分為兩種
- 函數對象
- 普通對象 仔細觀察如下代碼
綜合以上,得出結論==>普通對象都是通過函數創建的
prototype
每一個函數對象都有一個prototype屬性,但是普通對象是沒有的;
遺留問題
昨天留下了一些知識點,今天重點討論
- constructor
- _proto_
知新
constructor構造函數
我們昨天說創建對象的三種方式,第二種是通過new創建對象,
var obj = new Object()//創建一個空對象等同于 var obj = {} console.log(obj.constructor===Object)//true 復制代碼Object就是一個構造函數,是js內置的構造函數,上面的例子中Object就是obj的構造函數,這個例子似乎不太明顯,我們繼續看
function Foo(name){this.name = name } var foo = new Foo("陌上寒") console.log(foo.constructor===Foo)//true 復制代碼我們自定義了一個構造函數Foo,Foo是foo的構造函數,foo的構造函數就是Foo 構造函數與其他函數的唯一區別,就在于調用它們的方式不同。不過,構造函數畢竟也是函數,不存在定義構造函數的特殊語法。任何函數,只要通過 new 操作符來調用,那它就可以作為構造函數;而任何函數,如果不通過 new 操作符來調用,那它跟普通函數也不會有什么兩樣。 構造函數在創建時有一個約定,如果是構造函數,那么首字母要大寫,普通函數首字母小寫
constructor和prototype
constructor和我們昨天討論的prototype有什么聯系嗎? 觀察如下代碼的輸出
function Foo(name) {this.name = name; } var foo = new Foo('陌上寒'); console.log(Foo.prototype) 復制代碼通過昨天的討論我們得知只有函數對象才存在prototype 輸出
Foo.prototype是Foo的原型對象 繼續觀察 function Foo(name) {this.name = name; } var foo = new Foo('陌上寒');console.log(Foo.prototype.constructor===Foo)//true 復制代碼在默認情況下,所有原型對象都會自動獲得一個 constructor(構造函數)屬性,這個屬性包含一個指向 prototype 屬性所在函數的指針。就拿前面的例子來說,Foo.prototype.constructor 指向 Foo。 我們得出以下結論 原型對象中的constructor屬性,指向該原型對象對應的構造函數 也就是說上面的例子,Foo的原型對象是Foo.prototype,原型對象(Foo.prototype)中有一個constructor屬性,這個constructor屬性指向原型對象(Foo.prototype)對應的構造函數Foo,用一行代碼概括
console.log(Foo.prototype.constructor===Foo)//true 復制代碼以上就是constructor和prototype的關系 我們注意到原型對象(Foo.prototype)中還存在一個屬性_proto_,這又是什么?它和prototype,constructor又有什么關聯呢?
隱式原型(_proto_)
那么__proto__是什么?每個對象都會在其內部初始化一個屬性,就是_proto_。 Firefox、Safari 和 Chrome 的每個對象上都有這個屬性 ,而在其他瀏覽器中是完全不可見的(為了確保瀏覽器兼容性問題,不要直接使用 _proto_ 屬性,此處只為演示)。我們繼續看代碼
var arr = new Array() console.log(arr.__proto__===Array.prototype);//true var str = new String() console.log(str.__proto__===String.prototype);//true var Fun = new Function() console.log(Fun.__proto__===Function.prototype);//true var bool = new Boolean console.log(bool.__proto__===Boolean.prototype);//true var obj = new Object() console.log(obj.__proto__===Object.prototype);//true function MyFun() {console.log("我是陌上寒"); } var myfoo = new MyFun() console.log(myfoo.__proto__===MyFun.prototype);//true 復制代碼再重復一次:Array,String,Function,Boolean,Object都是js內置的構造函數,MyFun是自定義的構造函數 只有函數對象才存在prototype 所有對象(除了Object.prototype)都存在_proto_ 剛才我們討論過,普通對象都是通過函數創建的 根據以上我們得出結論: 普通對象__proto__指向當前函數對象的原型, 你可能發現了,有一個矛盾的地方,所有對象都存在_proto_,只有普通對象的__proto__指向當前函數對象的原型,那函數對象的__proto__指向哪里呢?繼續看代碼
function MyFun() {console.log("我是陌上寒"); } console.log(Boolean.__proto__);//? () { [native code] } console.log(Function.__proto__);//? () { [native code] } console.log(String.__proto__);//? () { [native code] } console.log(Array.__proto__);//? () { [native code] } console.log(Object.__proto__);//? () { [native code] } console.log(MyFun.__proto__);//? () { [native code] } 復制代碼函數對象的__proto__輸出的都是? () { [native code] } 函數內部是[native code],也就是系統編譯好的二進制代碼函數,我們不對此做研究 上面說到,所有對象都有_proto_,原型對象也是對象, 我們得出結論 原型對象也存在_proto_ 結合以上我門又一次得出結論 原型對象的__proto__指向當前函數對象的原型, 還是繼續看代碼,便于理解*
console.log('陌上寒'.__proto__===String.prototype);//true console.log(String.prototype.__proto__===Object.prototype);//true //等量代換,得出一下結論 console.log('陌上寒'.__proto__.__proto__===Object.prototype);//true //自此形成了一條鏈,===>原型鏈 復制代碼解釋一下如上代碼, '陌上寒'是字符串類型,'陌上寒'的構造函數是String(), 所以'陌上寒'的__proto__指向String的原型 String()是js的內置構造函數,繼承自Object,也就是說Object是頂端,是原型鏈的頂端,既然是頂端,所以:
console.log(Object.prototype.__proto__)//null 復制代碼Object的原型對象是不存在__proto__的
總結
所有對象(不包括Object.prototype)有__proto__屬性,函數對象有prototype屬性; 對象由函數生成; 生成對象時,對象的__proto__屬性指向當前函數的prototype屬性。 Object.prototyp處于原型鏈的頂端,不存在原型,不繼承任何屬性,其他原型對象都是普通對象,普通對象都具有原型,所有的內置構造函數(以及大部分自定義構造函數)都具有一個繼承自Object.prototype的原型,例如Date.prototype的 屬性繼承自Object.prototype,因此有new Date()創建的Date對象的屬性同時繼承自Date.prototype和Object.prototype,這一系列的原型對象就是所謂的原型鏈。
原文鏈接
關于javascript的原型和原型鏈,看我就夠了(一)
參考鏈接 《JavaScript 闖關記》之原型及原型鏈
JavaScript之原型與原型鏈
一篇文章帶你理解原型和原型鏈
徹底理解JavaScript原型鏈(一)—__proto__的默認指向
圖解prototype、proto和constructor的三角關系
Object.prototype 原型和原型鏈
三張圖搞懂JavaScript的原型對象與原型鏈
創作挑戰賽新人創作獎勵來咯,堅持創作打卡瓜分現金大獎總結
以上是生活随笔為你收集整理的关于javascript的原型和原型链,看我就够了(二)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 多线程基础(一)
- 下一篇: linux解决病毒系列之一,删除十字符l