一剔猿、作用域初探
function test() {
var a = 123;
}
function demo() {
var b = 234;
document.write(a);
}
兩個相鄰的作用域
互相不可以訪問變量
demo里不可以訪問test里的a
function test() {
var a = 123;
document.write(b);
function demo() {
var b = 234;
document.write(a);
}
}
兩個嵌套的作用域
外層的不可以訪問里層的變量
里層的可以訪問外層的變量
二脑慧、JS運行三部曲
1.語法分析 即通篇掃描一遍看有沒有語法錯誤
2.預(yù)編譯
3.解釋執(zhí)行
三、預(yù)編譯
1.預(yù)編譯中的提前規(guī)則
(1)舉例
function test() {
console.log('a');
}
test();
test();
function test() {
console.log('a');
}
均可打印a
var a = 123;
console.log(a);
輸出123
console.log(a);
var a = 123;
輸出undefined
console.log(a);
報錯 變量未聲明
(2)規(guī)則
a. 函數(shù)聲明 整體提升
函數(shù)不管聲明在哪系統(tǒng)都會把他提升到邏輯的最前面
b. 變量 聲明提升
var a = 123;??????????????變量聲明并賦值
系統(tǒng)把語句拆成????????var a; 聲明變量
?????????????????????????????????a =123; 變量賦值
然后把聲明語句放在邏輯最前面
賦值語句不動
所以輸出undefined未賦值而不報錯
2.預(yù)編譯前奏
(1)inply global 暗示全局變量
即任何變量绰垂,如果變量未經(jīng)聲明就賦值他巨,此變量就為全局對象window所有符相。
eg:a = 123; 不報錯
a = 123; ===> window.a = 123;
(2)一切聲明的全局變量,全是window的屬性
eg:var b = 123; ===> window.b = 123;
(3)window就是全局的域
var a = 123;=====>window { a : 123 ; }
在全局上訪問 a 就是訪問 window.a
function test() {
var a = b = 123;
// 連續(xù)賦值
// 1.b = 123 先把123賦值給未聲明的b
// 2.var a; 再聲明a
// 3.a = b; 把b賦給a
}
test();
訪問 window.a 打印undefined
訪問 window.b 打印123
3.函數(shù)體系的預(yù)編譯
1111111.預(yù)編譯發(fā)生在函數(shù)執(zhí)行的前一刻
eg
function fn(a) {
console.log(a);
var a = 123;
console.log(a);
function a () {}
console.log(a);
var b = function () {}
console.log(b)
function d () {}
}
fn(1);
過程分析及總結(jié)
(1)創(chuàng)建AO對象 Activation Object(作用域 執(zhí)行期上下文)
AO{}
(2)找形參和變量聲明褒链,將變量和形參名作為AO屬性名唁情,值為undefined
AO{
a : undefined,
b : undefined,
}
(3)將實參值和形參統(tǒng)一
AO{
a : 1,
b : undefined,
}
(4)在函數(shù)體里面找函數(shù)聲明,值賦予函數(shù)體
AO{
a : function a () {}甫匹,
b : undefined,
d : function d () {}
}
2222222.從AO域里取東西執(zhí)行函數(shù)及過程
function fn(a) {
console.log(a); 打印 function a () {}
var a = 123; var a;預(yù)編譯時被提升不用再看
執(zhí)行 a = 123;
AO{
a : 123甸鸟,
b : undefined,
d : function d () {}
}
console.log(a); 打印 123
function a () {} 預(yù)編譯時已經(jīng)提升不用再看
console.log(a); 打印 123
var b = function () {} var b;預(yù)編譯時被提升不用再看
執(zhí)行 b = function () {};
AO{
a : 123,
b : function () {},
d : function d () {}
}
console.log(b) 打印 function () {}
function d () {} 預(yù)編譯時已經(jīng)提升不用再看
}
fn(1);
打印結(jié)果:
function a () {}
123
123
function () {}
4.全局預(yù)編譯
全局預(yù)編譯發(fā)生在全局執(zhí)行的前一刻
所以先生成GO再生成AO
console.log(a)
var a = 123;
function a() {}
全局預(yù)編譯 打印function a() {}
GO {
a : undefined,
}
var a = 123;
funcation a () {}
GO {
a : funcation () {},
}
GO 就是 window
即為任何全局變量都是window上的屬性
eg1:題 + 執(zhí)行順序
(1) 生成GO對象 GO{}(global object) 這個GO就是window
GO{}
(2)將全局的變量聲明(的名)儲存一GO對象中兵迅,value為undefinde
GO{
test : undefined
}
(3) 將全局的函數(shù)聲明的函數(shù)名作為GO對象中的key,函數(shù)整體內(nèi)容為value儲存到go對象中
GO{
test : function () {
...
}
}
console.log(test);
function test(test) {
console.log(test);
var test = 234;
console.log(test);
function test() {}
}
(4)執(zhí)行函數(shù)前創(chuàng)建AO
AO變化過程
AO{
test : undefined,
}
AO{
test : 1,
}
AO{
test : function () {},
}
AO{
test : 234,
}
(5)執(zhí)行函數(shù)
test(1);
var test = 123;
eg2:題 + 執(zhí)行順序
(1)GO{
a : 10,
c : 234
}
(2)function test () {
console.log(b); // 輸出結(jié)果undefined
if(a) {
var b = 100;
}
console.log(b); // 輸出結(jié)果undefined
c = 234;
console.log(c); // 輸出結(jié)果234
}
var a;
AO{
b : undefined,
}
a = 10;
test();
console.log(c); // 輸出結(jié)果234
最終輸出:
undefined
undefined
234
234