js---10作用域链
<html> <head> <title>scope basic</title> </head> <body> <script type="text/javascript"> //作用域:成员,函数,变量可以被访问的范围。块作用域,函数作用域,动态作用域,词法作用域(静态作用域或者闭包) //js不是块作用域 alert(a);//undifiend alert(b);//undifiend alert(c);//报错 alert(d);//报错 var a = 1;//全局window成员 if(false){//预处理阶段,if语句当成不存在一样,所以会把b加入全局window对象 var b = 2; }else { c = 3;//不是全局window成员,没有var声明, } function f () {//f是window全局成员 var d = 4;//d属于f的成员,外部访问不了, } -------------------------------------------------------- //块作用域:大括号括起来的代码 for(var i =0; i < 3 ; i++){ } alert(i); //弹出3,说明js没有块作用域. //js也没有函数作用域 ------------------------------------------------------ //动态作用域,变量的值在执行的时候有值,所以js没有动态作用域 //静态作用域:在函数创建的时候,函数有一个成员scope。他的值是创建这个函数的环境(window对象或者其他) function f () {//scope == window alert(x);//函数f调用的时候,会首先在函数自己的词法环境中找x,找不到就去他的scope中找,scope是window,也没有x就报错。 } function f1 () { var x = 5; f(); //弹出5,实际报错,x未定义 } function f2 () { var x = 6; f();//弹出6,实际报错,x未定义 } f1();f2(); --------------------------------------------------- //静态作用域:在函数创建的时候,函数有一个成员scope。他的值是创建这个函数的环境(window对象或者其他) //作用域链:f.scope = window ,f调用的时候会创建自己的词法环境le(函数局部作用域),并且跟scope关联起来,f.le = f.scope,f的词法环境le(函数局部作用域)中有le{x : 100 ; g :指向函数引用},创建函数g时候g.scope = f.le,g函数调用时候会创建自己的词法环境(g的函数局部作用域)le,并且跟自己的scope关联, function f () { //f.scope == window //f.le{x =100} ->f. scope var x = 100; function g () { //g. scope ==f.le //g.le ->g. scope } g(); } //函数他自己的环境 --> 他自己的scope --> 指向创建他的环境, // g.le ->g. scope ->f.le ->f. scope ==winow //f.le ---> f.scope ---> 创建他的环境 //如果函数作用域找不到变量,就是创建这个函数的作用域去找变量 ------------------------------------------------------- //函数创建方式 function f(){} var f = function(){}//匿名函数 var f1 = function x(){}//这种方式创建函数很少,x永远访问不到 var f2 = new Function('参数',函数体) //每创建一个函数就形成一个新的作用域,跟父的作用域形成一个链条,作用域链:函数自己的作用域(大括号范围)找不到就去父级的作用域去找。new Function创建的作用域永远是全局作用域 function f () { var x = 100; var g = function () { alert(x); } g();//100 } f(); function f () { var x = 100; //g.[[scope ]]=window var g = new Function("","alert(x)");//只会去window作用范围去找 g(); } f(); -------------------------------------------- (function(){ var a = 5; var b = 6; function f(){ alert(a); } window.f = f; })(); f(); </script> </body> </html>
作用域链:函数自己的作用域(大括号范围)找不到就去父级(父函数)的作用域去找。
<html> 每个函数有2个属性,一个是谁创建了这个函数(函数定义写在哪里面谁就是创建他的那个谁),一个是函数的作用域(函数题的局部作用域中有哪些属性和函数)。 <script> var x=6; function f () { //f.le={x:未定义},f.scope=window(window创建的f函数不是f1的作用于创建的函数) alert(x); } function f1 () { var x = 5; f(); //6,f.le={x:未定义},f.scope=window(window创建的f函数不是f1的作用于创建的函数) function f2(){ alert(x); }; f2();//5,f2的作用域f2.le={x:未定义},f2的创建他自己这个函数的变量f2.scope=f1.le,因为是f1的作用域创建了f2函数。 } f1(); (function(){ var a = 1; var b = 2; function f3(){ alert(a); } window.f3 = f3; })(); f3();//1 </script> </html>