预编译 步骤
1.创建A0
2.找形参和var写入属性,值undefined
3.给形参赋值
4.找function定义,赋值的不算,找到用名字创建属性并赋值
function fn(a){ console.log(a); var a = 123; console.log(a); function a(){}; console.log(a); var b = function(){var a=1} //这个是赋值不是定义 console.log(b); function b(){} } /* 1.AO{} 2.找形参和var A0{ a:undefined, b:undefined } 3.给形参传值 A0{ a:1, b:undefined } 4.找定义的function A0{ a:function a(){}, b:function b(){} } */ fn(1) /* 执行 输出:function a(){} 123 123 function(){var a=1} */
a=100 function demo(e){ function e(){} arguments[0] = 2; console.log(e);//2 if(a){ var b=123; function c(){} } var c; a=10; var a; console.log(b);//undefined f=123; console.log(c);//fn console.log(a);//10 } var a; demo(1); GO{ a:100, demo:function(){...} f:123 } A0{ e:2, b:undefined, c:fn, a:10 } console.log(a);//100 console.log(f);//123
作用域 步骤
function a(){ function b(){ var b=234; } var a = 123; b(); } var glob =100; a(); /* 产生一个[[scope]]集合 [[scope]]里包括A0 GO 同时如果A0里还包括FN,那会包含FN b的AO,a的AO,GO 这里b里包含的a的A0是一个地址引用,和上一层的是同一个变量 */
function a(){ function b(){ function c(){ } c(); } b(); } a(); /* a defined a.[[scope]] --> 0:GO a doing a.[[scope]] --> 0:aAO 1:GO b defined b.[[scope]] --> 0:aAO 1:G0 b doing b.[[scope]] --> 0:bAO 1:aAO 2:GO c defined c[[scope]] --> 0:bAO 1:aAO 2:GO c doing c[[scope]] --> 0:cAO 1:bAO 2:aAO 3:GO */
闭包——里面的fn被return到外面
闭包作用
1.实现公有变量,eg函数累加器
2.可以做缓存(存储结构)
3.实现封装,属性私有化
4.模块化开发,防止污染全局变量
function a(){ function b(){ var bbb = 234; console.log(aaa) } var aaa = 123; return b; } var glob = 100; var demo = a(); demo();
示例
var a(){ var num = 100; function b(){ num++; console.log(num) } return b; } var demo = a(); demo();//101 demo();//102
function test(){ var num = 100; function a(){ num++; console.log(num); } function b(){ num--; console.log(num); } return [a,b] } var myArr = test(); myArr[0]();//101 myArr[1]();//100
function eater(){ var food = ""; var obj ={ eat:function(){ console.log("i am eating"+food); }, push:function(myFood){ food=myFood; } } return obj; } var eater1 = eater(); eater1.push('banana') eater1.eat();