JavaScript作用域和this关键字


1.JS的作用域分为全局作用域和函数作用域

全局作用域内定义的变量可以在全局和函数体内访问,函数作用域内定义的变量只能在自己的函数作用域内访问。如果变量前没有加var,无论在哪定义都会成为全局变量。

 1 //全局作用域
 2 var globalVal = "global";  //全局变量
 3 
 4 (function func (){
 5     //函数作用域
 6     var localVal = "local";
 7     globalVal2 = "global too";
 8     
 9     alert(globalVal);        //global
10     
11 })();
12 
13 alert(localVal);             //localVal is not defined
14 alert(globalVal2);           //global too 

上面代码中的函数为立即执行函数,不经过调用就会自己执行,方便看测试结果,另一个重要作用稍后解释。

另外,13行处报错not defined和JS的undefined类型是完全不同的两个概念。前者表示这个变量没有声明过,是不存在的或者不在可访问的作用域内,程序会产生运行时错误并终止运行;后者是JS的基本数据类型,表示此变量声明过,但未被定义,或被赋值为undefined,这个值可以显示、比较、运算,不会报错。

 

2.JS没有块级作用域

C++、Java等语言都有块级作用域,如for循环while循环等,JS却是没有块级作用域的!

1 for(var i=0;i<3;i++)
2 {    
3     alert(i);  //0,1,2 
4 } 
5 alert(i);      //3

上面5行代码处i的值是3,也就是说 var i; 写在for的里面和外面效果是一样的。C++之所以无法在for结束之后访问到i,是因为在一个块级作用域执行完它的垃圾回收机制就启动了,把块级作用域内不用的变量释放了。

 

3.构造函数创建函数的作用域是全局

 1 var globalVal = "global"; 
 2 
 3 (function func (){
 4     //函数作用域
 5     var localVal = "local";
 6     
 7     var func2 = new Function("alert(globalVal)");
 8     var func3 = new Function("alert(localVal)");  
 9     func2();    //global
10     func3();    //localVal is not defined
11 })();
12 
13 func2();        //func2 is not defined

上面代码显示,由构造函数创建的函数可以访问到全局变量globalVal,但访问不到局部变量localVal。第13行可能产生误解,new Function创建的函数作用域是全局的,把它赋值给局部变量func2,外部访问func2时未定义是正常的。

 

4.使用立即执行函数创建函数作用域

如1节所示,使用立即执行函数很大的用处是创建函数作用域,避免产生全局变量,因为全局变量重名可能产生覆盖等一些难以排查的问题。

立即执行函数的4种写法:

 1                 (function func(a){
 2                     var i = a;
 3                     console.log(i); 
 4                 })(1);
 5 
 6                 (function func(a){
 7                     var i = a;
 8                     console.log(i); 
 9                 }(2));
10 
11                 !function func(a){
12                     var i = a;
13                     console.log(i); 
14                 }(3);
15 
16                 void function func(a){
17                     var i = a;
18                     console.log(i); 
19                 }(4);

 

5.this关键字

this是一个总指向调用者的指针。以下是this指向的不同情况:

  1. 作为对象方法调用,this是对象 :point.move()
  2. 作为函数调用(包括立即执行函数),this是window :move()
  3. 作为内部函数,即声明在函数中的函数,this是window that=this
  4. 作为构造函数调用,即用new,this指向新生成的对象

 node.js中没有window对象,这种情况都指向null。

 

6.ES6箭头函数中的this

this总是指向被调用者,再也不需写var that=this这类代码。

 

posted @ 2016-02-17 11:52  海绵小猪  阅读(2195)  评论(0编辑  收藏  举报