原型
我們都知道,函數創建時瀏覽器會在內存中創建一個對象。很多人在這里都感覺很難理解里面的關系
函數創建的時候,瀏覽器會在內存中創建一個由prototype指向的對象。其實只有當你要將函數作為構造函數使用的時候,創建出來的對象才會發揮作用。
例如:
var obj=new People();
的時候,obj對象就不僅僅使用自己的屬性和方法,它也可以使用People函數創建時生成prototype對象的方法。
而且,Prople的prototype的屬性和方法可以通過 Prople.prototype.屬性名或者方法名創建。
那么也就是說用這種方法可以是對象所使用的屬性和方法更多。
還有一個好處就是減少代碼的重復。當多個對象的屬性或方法相同時,那么讓他們都new一下構造函數。則可以不用每個對象都加上this.屬性。
原型鏈,繼承
原型鏈
字面理解就是有原型形成的鏈,讓一個函數的原型等於另一個函數,那么這個函數就另一個函數通過原型串在一起,形成鏈。這樣的方法就可以把n個函數串在一起。
繼承
函數1——>prototype=函數2——>prototype=函數3——>prototype........
按照這樣的鏈,函數1可以通過鏈訪問函數2,函數3等等N個函數,這樣就是繼承。
作用域鏈
要連接作用域鏈,先要知道什么是執行環境。執行環境通俗來講就是代碼要執行的環境,也就是告訴你,環境了有什么,變量,方法之類的,可是使用的對象。最簡單的例子就是全局執行環境,也就是window,所有寫在js的方法,都在window執行環境里。
而每一個函數也有自己的執行環境。
而作用域鏈,可以看做是起作用的鏈,每個函數在創建的時候,都有執行環境,而眾多的函數形成的執行環境會存儲在作用域鏈中,因此作用域鏈就是存儲函數執行環境的。
函數要使用對象的時候,是在作用域鏈中查找的。查找的順序是頂層開始的。
存入的時候都是全局執行環境在頂層的,但是,但函數調用執行的時候,會先提前到頂層,執行完在釋放。所以可以理解為函數的查找是在自身,當沒找到則完上層查找,直到找到為止。
閉包
就是有權訪問另一函數作用域的變量的函數就是閉包。當然了,訪問window的作用域變量是不算的。(函數嵌套肯定就是閉包了,因為里面的函數肯定可以訪問外面函數作用域的變量)。
閉包的經典問題
先看看這段代碼:
var li=document.querySelectorAll('li');
function a(){
for(var i=0;i<li.length;i++){
li[i].onclick=function(){
console.log(i);
}
}
}
輸出結果為點擊出現的全是li.length。要的效果是點擊第一個li出現0...
第一種方法:
var li=document.querySelectorAll('li');
function a(){
for(var i=0;i<li.length;i++){
li[i].index=i;
li[i].onclick=function(){
console.log(li[i].index);
}
}
}
第二種方法:
var li=document.querySelectorAll('li');
function a(){
for(var i=0;i<li.length;i++){
li[i].onclick=(function(i){
return function(){
console.log(i);
}
})(i)
}
}
第三種方法:
var li=document.querySelectorAll('li');
function a(){
for(let i=0;i<li.length;i++){
li[i].onclick=function(){
console.log(i);
}
}
}
本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系我们删除。