【详解JavaScript系列】JavaScript之变量
一 概述
本篇文章将讲解javascript中的变量,大致内容归结为:
1.变量定义
包括变量声明和变量初始化
2.变量种类
包括局部变量和全局变量
3.变量链式作用域及访问
二 内容
(一)变量定义
在javascript编程语言中,变量的定义是通过var关键字来定义的(若变量不通过var定义,则视为全局变量,但不推荐这么做,因为这样做,在某些条件下,会引发一些问题)
1.变量声明
1 var name;//变量声明
2.变量初始化
1 name = "alan_beijing";//变量初始化
当然,也像后端语言一样(如java,.net)一样,在声明变量的同时,给变量初始化。因此,如上两句代码可如下定义:
1 var name = "alan_beijing";//变量声明同时初始化
(二)变量种类
在javascript中,若按照变量作用域和变量生命周期来划分,可将变量分为全局变量和局部变量。
1.全局变量:从作用域角度,全局变量位于作用域链的最顶端;从变量生命周期角度,全局变量生存期为整个程序生命周期,即直到程序结束,全局变量才销毁。
1 var address = "shanghai";//全局变量 2 function getuserinfo() { 3 var username = "alan_beijing";//username局部变量 4 return username +"-"+ address; 5 } 6 console.log(getuserinfo());//alan_beijing-shanghai 7 console.log(address);//shanghai
2.局部变量:从作用域角度,局部变量位于特定的局部域,如特定的函数内部;从变量生命周期角度,局部变量声明周期只在其所处的特定作用域内,超出该作用域,就失效。如函数变量,直在函数内部有效。
1 function getuserinfo() { 2 var username = "alan_beijing"; 3 return username; 4 } 5 console.log(getuserinfo());//alan_beijing 6 console.log(username);//报错:username is not defined
(三)变量链式作用域及访问
js中的变量作用域是通过this指针,从当前的作用域开始,从当前作用域由内向外查找,直到找到位置,这里分为几个逻辑:
a.从当前作用域由内向外查找,若找到,就停止查找,否则,继续查找,直到查到window全局作用域为止,若任然未找到,则会出错,提示该变量未定义;
b.当内部作用域变量名与外部作用域变量名相同时,内部作用域的覆盖外部作用域。
看看下面例子:
1 var datetime='2018-09-16'; 2 function getuserinfo(){ 3 var age=120; 4 var name="alan_beijing"; 5 function say(){ 6 var name="老王"; 7 var address="shanghai"; 8 console.log(address+"-"+name+"-"+age+"-"+datetime);//shanghai-老王-2018-06-05 9 } 10 return say(); 11 } 12 13 14 getuserinfo();//shanghai-老王-120-2018-09-16
来分析一下变量及其作用域:
如上图,有4个作用域,当函数执行如下语句时,发生如下过程:
1 console.log(address+"-"+name+"-"+age+"-"+datetime);
a.js当前this环境作用域为4作用域;
b.this指针寻找变量:addresss,name,age,datetime,从当前作用域向外作用域逐层寻找,直到寻找到变量为止,若寻找到最外层作用域任然没找到,则会出错,提示该变量未声明;
c.当内外层变量相同时,内层变量覆盖外层变量,如4作用域的name覆盖3作用域的name;
(四)拓展
1.非规范化定义全局变量(不推荐)
定义全局变量的另一种方式,就是不使用关键字var
1 function globalparam() { 2 username = "alan_beijing"; 3 } 4 globalparam(); 5 console.log(username);//alan_beijing
如上,我们只需调用globalparam()函数一次,username变量就有了定义,就可以在函数外部访问它了。如下定义,是访问不了的。因为未调用函数globalparam(),从而变量username就没定义
1 function globalparam() { 2 username = "alan_beijing"; 3 } 4 console.log(username);//报错:username is not defined
尽管可以这样定义全局变量,但是不推荐这种方式。
(1)在局部作用域中定义的变量,很难维护
(2)由于变量必须先声明,再使用,若忽略var关键字,导致变量不会立刻有定义,而导致错误,如上代码即可证明
(3)在严格模式下,会出现错误referenceerror错误
(4)可能出现局部变量修改全局变量危险。看看如下例子
1 var scope = "global";//全局变量 2 function setparam() { 3 scope = "local";//局部变量(导致局部变量修改全局变量危险) 4 return scope; 5 } 6 console.log(scope);//global 7 8 setparam(); 9 console.log(scope); //local
2.javascript中没有块级作用域
在后端语言中,我们非常熟悉if和for语句,我们先来看看如下.net的for语句:
1 for (int i = 0; i < 2; i++) 2 { 3 int result = 0; 4 result =result+ i; 5 }
我们知道,在for语句中,定义了两个变量i和result,这两个变量只能在for语句有效,不能在for语句外访问。同样地,在if语句中的变量也只能在if内部访问,外部不能访问
1 if (true) 2 { 3 string username = "alan_beijing"; 4 }
不仅if和for语句,while,do...while,switch语句等,均是相同的,他们内部的变量,只能在其内部访问,不能在其外部访问,我们将其称之为“块级作用域”;
然而,在javascript中,是没有块级作用域的。
1 var maxnum = 100; 2 for (var i = 0; i < maxnum; i++) { 3 var sum = 0; 4 sum = sum + i; 5 } 6 console.log(sum);//99。因为javascript没有块级作用域,因此能在for语句外部访问变量sum
3.javascript中this指针
4.javascript链式作用域
(五)例子
请分析如下例子的结果。
1 var address = "shanghai";//全局变量 2 function getuserinfo() { 3 var username = "alan_beijing";//username局部变量 4 return username +"-"+ address; 5 } 6 console.log(getuserinfo());//alan_beijing-shanghai 7 console.log(address);//shanghai 8 console.log(window.address);//shanghai 9 console.log(window.username);//undefined 10 console.log(username);//报错:username is not defined
三 已发布文章
【01】javascript之变量
【02】javascript之流程语句
【03】javascript之函数(一)
推荐阅读
-
【详解JavaScript系列】JavaScript之变量
-
JavaScript中的变量提升
-
详解JavaScript的计时器和按钮效果设置
-
js delete 用法(删除对象属性及变量)_javascript技巧
-
JavaScript 变量,数据类型基础实例详解【变量、字符串、数组、对象等】
-
详解JavaScript修改注册表的方法
-
JavaScript 实现HTML DOM增删改查操作的常见方法详解
-
JavaScript ES6 Class类实现原理详解
-
javascript中caller和callee详解_javascript技巧
-
javascript中parentNode,childNodes,children的应用详解_javascript技巧