JavaScript原型、閉包、繼承和原型鏈等等總結
幾年之前學習過Javascript,當時學得比較淺顯,現在又開始學了,發現Javascript其實挺難的,有些地方還是得花時間去理解的,於是看了很多的視訊和部落格,自己在這裡小小的總結下。。。
1.一切(引用型別)都是物件,物件是屬性的集合。
undefined, number, string, boolean屬於簡單的值型別,通過typeof來判斷;函式、陣列、物件、null都是引用型別,通過instanceof來判斷。物件裡面的一切都是屬性,只有屬性,沒有方法,它的屬性表示為鍵值對的形式。一切引用型別都是物件,物件都是通過函式來建立的。
2.prototype原型
每一個函式都有一個屬性叫做prototype,每一個物件(注也包括函式)
上圖中f1是由Foo()建立的物件,f1._proto_指向Foo.prototype,Foo()函式的_proto_指向Object.prototype,同理,Object()函式建立的o1物件的_proto_指向Object.prototype,而Object.prototype通過_proto_指向的為null。
現在,注意區分function()和Function()。函式也不是從石頭縫裡蹦出來的,函式也是被創建出來的。誰建立了函式呢?——Function——注意這個大寫的“F”。直接上圖吧:
Function.prototype它的__proto__也指向Object.prototype
其實圖看起來亂,但真正自己畫起來不難,而且會特別有成就感的。
3。理解instanceof
上一節說過,引用型別通過instanceof來判斷。先看例題
function Foo() {}
var f1=new Foo();
console.log(f1 instanceof Foo); //true
console.log(f1 instance Object); //true
根據上面程式碼畫出左邊的圖
Instanceof的判斷規則是:沿著A的__proto__這條線來找,同時沿著B的prototype這條線來找,如果兩條線能找到同一個引用,即同一個物件,那麼就返回true。如果找到終點還未重合,則返回false。
最後,咱們可以把所有的這些圖聯合成一個整體:
4.原型鏈和繼承
訪問一個物件的屬性時,先在基本屬性中查詢,如果沒有,再沿著__proto__這條鏈向上找,這就是原型鏈。根據原型鏈可以確定繼承關係。由於所有的物件的原型鏈都會找到Object.prototype,因此所有的物件都會有Object.prototype的方法。這就是所謂的“繼承”。
實際應用中如何區分一個屬性到底是基本的還是從原型中找到的呢?大家可能知道答案——hasOwnProperty,特別是在for…in…迴圈中,一定要注意。
5。執行上下文。
“執行上下問”也叫坐“執行上下文環境”;
在一段js程式碼拿過來真正一句一句執行之前,瀏覽器已經做了一些“準備工作”,其中就包括對變數的宣告,而不是賦值。變數賦值是在賦值語句執行的時候進行的。總結下在“準備工作”中完成了哪些工作:
- 變數、函式表示式——變數宣告,預設賦值為undefined;
- this——賦值;
- 函式宣告——賦值;
如果在函式中,除了以上資料之外,還會有其他資料。先看以下程式碼:
以上程式碼展示了在函式體的語句執行之前,arguments變數和函式的引數都已經被賦值。從這裡可以看出,函式每被呼叫一次,都會產生一個新的執行上下文環境。因為不同的呼叫可能就會有不同的引數。且另外一點不同在於,函式在定義的時候(不是呼叫的時候),就已經確定了函式體內部自由變數的作用域。
全域性程式碼的上下文環境資料內容為:
普通變數(包括函式表示式), 如: var a = 10; |
宣告(預設賦值為undefined) |
函式宣告, 如: function fn() { } |
賦值 |
this |
賦值 |
如果程式碼段是函式體,那麼在此基礎上需要附加:
引數 |
賦值 |
arguments |
賦值 |
自由變數的取值作用域 |
賦值 |
給執行上下文環境下一個通俗的定義——在執行程式碼之前,把將要用到的所有的變數都事先拿出來,有的直接賦值了,有的先用undefined佔個空。
寫了這麼多,其實圖我都會手畫,但是畫在電腦上太花時間了,所以用來下一位博主的圖,此博主寫得超級好。我基本上是按此博主文章系列來寫的。下面附上鍊接
http://www.cnblogs.com/wangfupeng1988/p/4001284.html