js运行三步曲
- (一).语法分析
通篇扫描,检查是否有语法错误
- (二).预编译(发生在函数执行的前一刻)
- 预编译四步曲
1.创建AO对象(执行期上下文)
2.找形参和变量声明,将变量和形参名作为AO属性名,值为undefined`AO {}`
3.将形参和实参统一`AO{ a: undefined, b: undefined }`
4.在函数体里面找函数声明,值赋予函数体 (var b = function () { } 不是函数声明)`AO{ a: 1, b: undefined }`
`AO{ a: function a() { }, b: undefined, d: function d() { } } `
- 预编译四步曲
- (三).解释执行
function fn(a) { console.log(a) // function a() { } var a = 123; console.log(a) // 123 function a() { } console.log(a) // 123 var b = function () { } console.log(b) // function () { } function d() { } } fn(1)
练习
- 练习01:
function test(a,b){ console.log(a); // 1 c = 0; var c; a = 3; b = 2; console.log(b); // 2 function b(){ } function d(){ } console.log(b); // 2 } test(1); // AO{ // a: 3, // b: 2, // c: 0, // d: function d(){} // }
- 练习02:
function test(a,b){ console.log(a); // function a(){} console.log(b); // undefined var b = 234; console.log(b); // 234 a = 123; console.log(a); // 123 function a(){ } var a; b = 456; var b = function(){ } console.log(a); // 123 console.log(b); // function(){} } test(1); // AO{ // a: function a(){} // b: undefined // } // AO{ // a: 123 // b: function(){} // }
未经声明就赋值的变量归GO(window)所有
// 练习01: console.log(b); // b is not defined. console.log(window.b); // undefined function test() { console.log(a); // undefined // console.log(b); // b is not defined. console.log(window.b); // undefined var a = b = 123; console.log(a, window.a); // 123 undefined console.log(b, window.b); // 123 123 } test() // GO{ // b: undefined // } // AO{ // a: undefined // }
// 练习02: console.log(test); // function test(test) { /* CODE */} function test(test) { console.log(test); // function test() { } var test = 123; console.log(test); // 123 function test() { } } test(1); var test = 123; // GO{ // test: function test(test) { /* CODE */} // } // 1.test -> AO{} // 2.test -> AO{ // test: undefined // } // 3.test -> AO{ // test: 1 // } // 4.test -> AO{ // test: function test() { } // } // 三、解释执行
// 练习03: global = 100; function fn(){ console.log(global); // AO里的 undefined global = 200; // 不是未声明 console.log(global); // AO里的 200 var global = 300; console.log(global); // AO里的 300 } fn(); var global; // GO{ // global: 100, // fn: function fn(){ /* CODE */} // } // AO{ // global: 300 // }
// 练习04: // 第一步.生成GO{ // a: undefined // test: function test(){ /* CODE */} // } // 第三步.执行函数改变GO{ // a: undefined // test: function test(){ /* CODE */}, // c: 123 // } // 第四步.执行函数改变GO{ // a: undefined // test: function test(){ /* CODE */}, // c: 123 // } function test() { console.log(a); // undefined console.log(b); // undefined if (a) { console.log(b); // undefined var b = 100; console.log(b); // 100 } console.log(b); // undefined c = 123; // 第三步 console.log(c); // 123 } var a; console.log(c); // c is not defined. test(); // 第二步.生成AO{ // b: undefined // } console.log(c); // 123
// 练习05: function bar(){ return foo; foo = 10; function foo(){ } var foo = 11; } console.log(bar()); // function foo(){} // AO{ // foo: function foo(){} // }
// 练习06: console.log(bar()); // 11 function bar(){ console.log(foo); // function foo(){} foo = 10; console.log(foo); // 10 function foo(){ } console.log(foo); // 10 var foo = 11; console.log(foo); // 11 return foo; } // AO{ // foo: function foo(){} // } // AO{ // foo: 10 // } // AO{ // foo: 11 // }
// 练习07: // GO{ // a: undefined, // demo: function demo(e){ /* CODE */} // } // 执行变化GO{ // a: undefined -> 100, // demo: function demo(e){ /* CODE */}, // -> f: 123 // } a = 100; function demo(e){ function e(){ } arguments[0] = 2; console.log(e); // 2 if(a){ var b = 123; function c(){ } // 在判断中定义函数相当于 c = function c(){} } var c; a = 10; var a; console.log(b); // undefined f = 123; console.log(c); // undefined console.log(a); // 10 } var a; demo(1); // AO{ // c: undefined, // a: undefined, // b: undefined, // e: undefined // } // AO{ // c: undefined, // a: undefined, // b: undefined, // e: 1 // } // AO{ // c: undefined, // a: undefined, // b: undefined, // e: function e(){} // } // 执行变化 -> AO{ // c: undefined, // a: undefined -> 10, // b: undefined, // e: function e(){} -> 2 // } console.log(a); // 100 console.log(f); // 123 // 最终结果:2 undefined undefined 10 100 123