網路上很多關于JS原型的理解,寫了很多,我也看了很多,但總是云里霧里,很多文章一上來就說Object是一切物件的根物件,這句話非常誤匯入的思維,后來自己在控制臺,自己分析出來了比較好理解的方式,下面我來詳細屢屢關于js原型的正確理解方式,
主要是理解js中的物件,函式,函式物件,函式實體
首先我們來聊聊這四個概念
物件
物件是什么呢,物件就是使用json格式表示的代碼塊,用這種方式表示js中的物件如下:
{ "name":"runoob", "alexa":10000, "site":null }
JSON 物件使用在大括號 {...} 中書寫,
物件可以包含多個 key/value(鍵/值)對,
key 必須是字串,value 可以是合法的 JSON 資料型別(字串, 數字, 物件, 陣列, 布林值或 null),
key 和 value 中使用冒號 : 分割,
每個 key/value 對使用逗號 , 分割,
函式
函式就是function關鍵字定義的一段代碼塊,就是自己定義的看得到的那一塊代碼,稱之為函式,js中內置了一些基礎函式比如(Object,Date等等),其實質就是帶有構造器constructor的物件,js中可以將一個帶有構造器constructor的物件表示為為函式,函式是json物件的變體表現形式
(注意:永遠不要忘記js中的物件就是json格式的代碼塊,函式是這個json格式物件的變體)
如下為Object函式的原型Object.prototype,也是一個json鍵值對物件:
{ {constructor: ?, __defineGetter__: ?, __defineSetter__: ?, hasOwnProperty: ?, __lookupGetter__: ?, …} constructor: ? Object() hasOwnProperty: ? hasOwnProperty() isPrototypeOf: ? isPrototypeOf() propertyIsEnumerable: ? propertyIsEnumerable() toLocaleString: ? toLocaleString() toString: ? toString() valueOf: ? valueOf() __defineGetter__: ? __defineGetter__() __defineSetter__: ? __defineSetter__() __lookupGetter__: ? __lookupGetter__() __lookupSetter__: ? __lookupSetter__() __proto__: null get __proto__: ? __proto__() set __proto__: ? __proto__() }
函式有兩種作用:一是執行特定功能的代碼塊,二是構造物件
函式物件
函式物件就是函式的原型,要與函式本身區分開來,比如Date函式的函式物件為Date.prototype,后面我在說特定函式物件的時候都會加上.prototype,因為這個函式原型才真正表述為函式物件
函式實體
函式實體就是通過函式構造器創造的物件,一個函式可以構造出多個不同的但相似的函式實體物件,例如:
function myFunction(a, b) { return a * b; } var x = myFunction (3, 3); var y = myFunction (4, 3); 從控制臺可以分析出函式實體x,y是函式物件Number的子物件,其_proto_屬性指向的是Number.prototype,而不是我們通常認為的x,y為myFunction.prototype的子物件 當然這里也不能絕對,因為函式實體的父物件是不確定的,如下實體 function myFunction2() { console.log('nihao'); } var z=myFunction2(); var m= new myFunction2();
VM360:3 nihao
undefined
z
undefined
函式實體z回傳的日志為undefined
函式實體m回傳的日志為myFunction2 {}
以上可知通過new關鍵字構造的新物件其父物件才指向其建構式物件
物件與函式的基本認識
物件的_proto_屬性指向的是當前物件的父物件
只有函式有constructor和prototype屬性
函式中的prototype屬性字面意思是原型,指的是當前函式的物件原型,函式只是這個物件原型的變體形式
按照我的理解是這樣的,創造js這門語言的時候是定義這是一個面向物件的語言,所有首要任務就是指定物件的格式,就有json物件表示法,然后就是構造執行代碼塊的結構,即函式 表示法,再就是物件與函式的關聯,想象js一切皆為物件,函式的定義本身也是在構造物件,即定義的函式可以表示為帶有constructor的物件,這就是函式原型,然后通過函式定義法著手定義根物件就是Object.prototype以及其他的一些內置物件
關于Object與Object.prototype的理解
js中所有的物件繼承自Object.prototype這個原型物件,這個原型物件用函式表示就是Object,所以很多文章都Object為根物件,這也沒錯,因為Object表示的就是根,只是這個根是以函式的形式表示出來,而這個函式的原型就是真正的根物件,即Object.prototype:{…}(這個里我省略了物件中的內容),這個Object.prototype派生了函式物件和普通物件(如Math,JSON等,因為這些物件中沒有構造器,可自行在控制臺查看),永遠不要忘記Object這個函式是通過函式構造器構造出來的函式模樣的一塊代碼,其本質是Object.prototype這個原型,這才是根物件,
Object是一個函式,其屬性指標_proto_指向的是函式根物件? () { [native code] },而函式根物件的_proto_則指向Object.prototype,應該有這樣的關系:Object._proto_._proto_===Object.prototype;
不過js在_proto_屬性后面就不讓指標跟蹤了,不過我們也可以通過變通的方式來查到,從這里可以看出來:
Object._proto_===Function.prototype //回傳值都為? () { [native code] };
Function.prototype.__proto__=== Object.prototype //回傳值為true
Object.prototype._proto_則為null,
以上可以看出,JS中的一切物件都是Object.prototype的子物件,函式根物件? () { [native code] }是Object.prototype的子物件,函式是函式根物件? () { [native code] }的子物件,Object函式也不列外,(注意Function函式是函式根物件的顯式函式宣告,代表著函式根物件,函式根物件? () { [native code] }是在js運行時已經定義好了的物件)
很多文章都說所有函式都派生自這個Function物件,準確的來說應該是所有函式物件派生自Function.prototype,而Function.prototype就是? () { [native code] },那么問題來了,Object也是函式,那它也是派生自這個物件嗎,是的,前面我已經說了,Object在js中寫的時候是個函式不是根物件,而這個函式的原型Object.prototype才是真正的根物件,其形式為:這個在函式概念那里已經表述出來了,可以回傳去鞏固鞏固,
關于JS Function函式理解
JS內置物件中,Function函式(注意我這里表述的是函式而不是函式物件,因為Function的函式物件準確來說應該為Function.prototype)較為特殊,這個理解起來就比較困難,因為Function.prototype===Function._proto_,很多人很疑惑為什么會等于,其實這里還缺少了一個重要的資訊,那就是? () { [native code] },這個才是根函式物件,這個根函式物件的父物件指向的是Object.prototype這個根物件,這是在js運行時中就已經定義好的,而Function.prototype這個函式物件原型恰好就是這個根函式物件? () { [native code] },而這個Function._proto_這個屬性指標恰好就指向了? () { [native code] },這都是在js運行時中定義好了, Function這個函式的作用就是為了創建函式實體的另外一種方法,其父類物件還是Object.Prototype,只是顯式定義函式的多一種選擇,
好了,文章結束,希望對各位有所幫助!
轉載請註明出處,本文鏈接:https://www.uj5u.com/qiye/519078.html
標籤:其他
上一篇:事件委托
下一篇:學習筆記——Vue
