js做用域和做用域链

做用域

首先要知道一点,js跟python都是同样的,先编译后执行前端

惟一的区别在于,js对于只声明,未定义的变量,报错是未定义,后面代码会有这个例子python

编译的过程只有赋值和开辟空间的过程函数

只有函数,类才有做用域this

若是,单写一个变量,例如python代码 x , js代码 <script>x</script>都会报错,没有定义,可是换成字符串就不会报错spa

全局做用域(Global Scope)

在代码中任何地方都能访问到的对象拥有全局做用域,通常来讲一下几种情形拥有全局做用域:code

(1)最外层函数和在最外层函数外面定义的变量拥有全局做用域对象

 1 var name="yuan";  # 全局定义
 2 
 3     function foo(){
 4         var age=23;  # 局部定义
 5         function inner(){。# 局部函数
 6             console.log(age); # //age 23
 7         }
 8 
 9         inner();
10     }
11 
12     console.log(name);    // yuan
13     //console.log(age);   // Uncaught ReferenceError: age is not defined,在外部没有这个变量
14     foo();                // 内嵌函数的打印23
15     inner();              // Uncaught ReferenceError: inner is not defined 由于内嵌函数,找不到这个函数

 (2)全部末定义直接赋值的变量自动声明为拥有全局做用域,例如:blog

 1 var name="yuan";
 2 
 3     function foo(){
 4         age=23;   # 全局定义
 5 
 6         var sex="male"  # 局部定义
 7     }
 8     foo();
 9     console.log(age);   //  23
10     console.log(sex);   // sex is not defined

 (3)全部window对象的属性拥有全局做用域ip

通常状况下,window对象的内置属性都都拥有全局做用域,例如window.alert()、window.location、window.top等等。作用域

查找过程:

内往外-局部,全局,内置

外往内-全-内置

局部做用域(Local Scope)

和全局做用域相反,局部做用域通常只在固定的代码片断内可访问到,最多见的例如函数内部,全部在一些地方也会看到有人把这种做用域成为函数做用域.

做用域链(Scope Chain)

在JavaScript中,函数也是对象,实际上,JavaScript里一切都是对象。函数对象和其它对象同样,拥有能够经过代码访问的属性和一系列仅供JavaScript引擎访问的内部属性。其中一个内部属性是[[Scope]],由ECMA-262标准第三版定义,该内部属性包含了函数被建立的做用域中对象的集合,这个集合被称为函数的做用域链,它决定了哪些数据能被函数访问。、

1.1 实例js代码:

 1 //-----**********************例1*********************************
 2 
 3 var s=12;
 4 function f(){
 5     var s=12;          
 6     console.log(s)
 7 }
 8 f();
 9 结果打印的是未定义
10 // if s=12,打印12,由于是修改了全局
11 
12 //-----**********************例2*********************************
13 
14 var s=10;
15 function foo(){
16     console.log(s);   # 打印函数
17     var s=5;
18     console.log(s);   # 打印5 ,局部变量的赋值
19     function s(){console.log("ok")}// 函数的定义或声明是在词法分析时完成的,执行时已再也不有任何操做
20     console.log(s);  # 打印5
21 }
22 foo();
23 
24 //-----***********************例3********************************
25 
26 function bar(age) {
27     console.log(age);   # 打印函数
28     var age = 99;
29     console.log(age);  # 99
30     function age() {
31         alert(123)
32     };
33     console.log(age);  # 99
34 }
35 
36 result=bar(5);

 1.2 实例解析例2

当一个函数建立后,它的做用域链会被建立此函数的做用域中可访问的数据对象填充。在函数bar建立时,它的做用域链中会填入一个全局对象,该全局对象包含了全部全局变量,以下图所示:

解析到函数调用时,即bar(5),会生成一个active object的对象,该对象包含了函数的全部局部变量、命名参数、参数集合以及this,而后此对象会被推入做用域链的前端,当运行期上下文被销毁,活动对象也随之销毁。新的做用域链以下图所示:

 

当建立函数后,做用域链的部分是0指向全局的Go,

当函数引入的时候,做用域链的部分是0,1。0数的局部Ao,1 指向全局的Go,

若是函数嵌套函数,做用域链的部分是0,1,2。0指向嵌套函数的局部Ao,1指向函数的局部Ao,2指向全局的Go,

 

 

js的 函数传参

 1 <script>
 2 
 3     // 函数传的参数,位置参数传递跟python不同,不对等不报错
 4     function a(x) {
 5         console.log(x)
 6     }
 7     a(1);
 8     function b(x,y) {
 9         console.log(x,y) // 打印1
10     }
11     b(1);
12     function c(x) {
13         console.log(x) // 打印1
14     }
15     c(1,2);
16 
17 
18     //arguments 能够打印传来的全部参数,包含在一个序列里面   # 也就是说能够对这个进行循环 for(var i=0;i<arguments.length;i++){console.log(arguments[i])}
19     function d() {
20        console.log(arguments)
21         //Arguments(3) [1, 2, 3, callee: ƒ, Symbol(Symbol.iterator): ƒ]0: 11: 22: 3callee: ƒ a()length: 3Symbol(Symbol.iterator): ƒ values()__proto__: Object
22     }
23     d(1,2,3);
24     function e(x,y) {
25        console.log(arguments)
26     }
27     e(1,2,3)
28 
29 </script>
相关文章
相关标签/搜索