js預編譯歷程

先科普:

1.javaScript是詮釋型言語,就是編譯一行,實行一行…..
2.javaScript沒有塊級及作用域……
3.javaScript具有變量和函數聲明提拔功用…..
4.AO對象和GO對象….
5.預編譯就是處理代碼實行遞次題目,與java言語相似(jvm)….

比方:

(function(a){
console.log(a);
var a = 12;
console.log(a);
function a(){...}
console.log(a);
var b = function(){...}
console.log(b);
function d(){...}
})(1);

1.起首建立一個GO對象,和AO對象….[由於該馬上實行函數是在全局作用域中實行的,馬上實行函數實行時建立AO對象]

GO{
   AO{
       
   } 
}

2.找形參和變量聲明,將變量和形參名作為AO屬性名,值為undefined….【變量聲明找到了a和b,實在形參也是一種變量聲明,相似於function(a,b){var a,b;},這裏的形參和函數里的變量聲明a重名了,那末后一個變量聲明會被疏忽…】

GO{
    AO{
       a: undefined,
       b: undefined 
    }
}

3.將實參和形參一致……【實參值賦值給形參】

GO{
    AO{
        a: 1,
        b: undefined
    }
}

4.在函數體內里找函數聲明,值給予函數體….【記着,一定是變量聲明在前,函數聲明在後。所以變量聲明提拔和函數聲明提拔會湧現一個先後遞次】

GO{
    AO{
        a: function(){...},
        b: undefined,
        d: function(){...}
    }
}

預編譯歷程完畢。

然後最先實行:

1.實行第一行:輸出function(){…}
2.實行第二行賦值:

GO{
    AO{
        a: 12,
        b: undefined,
        d: function(){...}
    }
}

3.實行第三行:輸出12
4.第四行是函數聲明,預編譯已實行了,跳過,實行第五行,輸出:12
5.實行第六行賦值:

GO{
    AO{
        a: 12,
        b: function(){...},
        d: function(){...}
    }
}

6.實行第七行:輸出:function(){…}
7.第八行是函數聲明,跳過,實行完成…接下來燒毀AO,再燒毀GO【這裡是一個js渣滓清算曆程,無關本話題】

比方:
作用域鏈……
本身本身屬性找不到就會去查找上一級的作用域中的屬性…層層迭代查詢
直到查到為止….
js是依據一個叫[[scope]]的屬性查找的,[[scope]]是任何函數(作用域都存在)都默許自帶的屬性,它保留了一個數組值,長度是父級的總長度(作用域包裹的層級,長度最少為1),直到window為止,假如查不到,彈出毛病…
起首[[scope]][0]保留本身預編譯AO,先查找[[scope]][0],保留了該AO或許GO….
不存在時查找[[scope]][1]…

注重:[[scope]]屬性不可枚舉,沒法訪問…

比方:
call和apply擴大了作用域….
apply要領能夠‘借用’其他對象中的要領(簡稱A)完成屬於本身的使命,A只是臨時用於本身,其本身照樣他人的,你不能夠去修正A中的代碼,也沒法修正…
在你挪用A時,apply中this指向了本身,能夠如許明白:我使用了你的要領,要領里的this指向了我,我的屬性(要領)增加了一項(擴大了我的作用域),然則一旦退出apply時(實行完成后),要領依舊要還給你,this指向照樣你,我的作用域回歸原樣….

    原文作者:spike
    原文地址: https://segmentfault.com/a/1190000014539851
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞