js变量的作用域详解

JavaScript中的变量作用域问题对一些初学前端的人来说可能是一个很头疼的问题,但是我相信,等你看完这篇文章之后你会有一个相对明确的理解

首先,我们来看看下面的两段代码输出结果分别是什么。

代码一:

var a = 1;
function func(){
    var a;
    alert(a);
    a = 2;
     alert(a);
}
func();

代码二:

var a = 1;
function func(){
    alert(a);
    a = 2;
    alert(a);
}
func();

这里就涉及到了全局变量以及局部变量的问题,代码一func()中的a只是执行了声明操作,并未赋值,所以第一次弹出的是undefined,紧接着它就对a进行了赋值操作,将2赋值给a,因此代码一的输出结果是undefined 2,代码二中因为func()这个局部作用域中在第一个alert之前是没有对a进行声明赋值操作的,所以调用的还是外部全局作用域中的a的值,所以代码二的输出结果是1 2;

我们再来看下面这段代码:

var a =1;
function func(){
    alert(a);
    var a = 2;
    alert(a);
}
func();
alert(a);

它的输出值又是多少呢?1 2 1?No,并不是,结果是undefined 2 1,为什么呢?这里其实涉及到了变量的预解析。上述代码其实就相当于下面这段代码:

var a =1;
function func(){
    var a;      //预解析
    alert(a);
    var a = 2;
    alert(a);
}
func();
alert(a);

以上是作用域的黄金守则第一条:  变量的查找是就近原则,去寻找var定义的变量,当就近没有找到的时候就去查找外层。



我们来看下面的代码:

 var a = 10;
 function funcA(){//step-4
    alert(a);//step-5->执行alert,此时只能找到外面的a=10故弹框10
 }
 function funcB(){//step-2
     var a = 20;
     funcA();//step-3
 }
 //定义了函数没啥用,调用才是真格的所以这里是step-1
bbb();//step-1

弹出的结果是10;

接下来看这段代码:

function funcA(){
    var a=b=10;
}
funcA();
alert(a);   //直接报错,a is not defined
alert(b);

而当我把alert(a)注释的时候:

function funcA(){
    var a=b=10;
}
funcA();
//alert(a);
alert(b);    //弹出10

这是为什么呢?var a=b=10这种写法在函数内,b其实是全局变量,a当然是局部变量,执行完funcA(),在全局范围内alert(a),当然是undefined,alert(b)是10。

以上是作用域黄金守则第二条: js没有块级作用域(你可以自己闭包或其他方法实现),只有函数级作用域,函数外面的变量函数里面可以找到,函数里面的变量外面找不到。


var a=10;
function funcA(){
    alert(a);
    var a=20;
}
funcA();    //弹出10

还有:传参时,基本类型传值,引用类型传引用。(但是重新赋值之后就不是这样了喔):

var a = 5;
var b = a;
b +=3;
alert(a);//5
var a = [1,2,3];
var b=a;
b.push(4);
alert(a);//[1,2,3,4];

上面代码没有问题,但是下面就不一样啦。

var a=[1,2,3,];
vae b=a;
b=[1,2,3,4];
alert(a); //[1,2,3]

因为b被重新赋值了,不指向a了。

此外,参数与变量的作用域是相似的:

var a=10;
function func(a){
    a += 3;
}
func(a);
alert(a); //10

对比上下这两个:

var a=10;
function func(a){
    a += 3;
    alert(a);
}
func(a); //13

上面是参数是基本类型,只传了值进去,下面的传个引用类型:(同样也包含重新赋值的情况)

var a=[1,2,3];
function func(a){
    a = [1,2,3,4];
}
func(a);
alert(a); //[1,2,3]
var a=[1,2,3];
function func(a){
    a.push(4);
}
func(a);
alert(a); //[1,2,3,4]

以上是作用域黄金守则第三条: 当参数跟局部变量重名时,优先级是等同的。

(本文引用:https://www.cnblogs.com/skylar/p/3986087.html)

原文地址:https://www.cnblogs.com/cashin/p/8080853.html

时间: 2024-10-17 10:49:08

js变量的作用域详解的相关文章

详解js变量、作用域及内存

详解js变量.作用域及内存 来源:伯乐在线 作者:trigkit4 原文出处: trigkit4 基本类型值有:undefined,NUll,Boolean,Number和String,这些类型分别在内存中占有固定的大小空间,他们的值保存在栈空间,我们通过按值来访问的. JavaScript 1 2 (1)值类型:数值.布尔值.null.undefined. (2)引用类型:对象.数组.函数. 如果赋值的是引用类型的值,则必须在堆内存中为这个值分配空间.由于这种值的大小不固定(对象有很多属性和方

深入MySQL用户自定义变量:使用详解及其使用场景案例

一.前言 在前段工作中,曾几次收到超级话题积分漏记的用户反馈.通过源码的阅读分析后,发现问题出在高并发分布式场景下的计数器上.计数器的值会影响用户当前行为所获得积分的大小.比如,当用户在某超级话题下连续第n(n即计数器的值)次进行转发帖子时,将会获得与n相关的分数.然而,在第一次改进后问题依然存在.所以,这次在之前的基础上,通过使用MySQL变量的途径来解决该问题. 二.到底MySQL的变量分哪几类? MySQL变量一共分为两大类:用户自定义变量和系统变量.如下: 用户自定义变量 局部变量 会话

WebGL/Three.js深度学习课程详解

课程介绍:适用于对WebGL.Three.js等3D技术感兴趣,却不知道如何入门的同学, 课程带领大家深入理解WebGL的原理. 课程目录:├─01-基础部分│      01-WebGL与three.js的基础.与opengl的关系.mp4│      02-编写第一个three.js程序.mp4│      03-three.js程序框架,绘制一条直线.mp4│      04-三维世界的组成(点.线).mp4│      05-坐标系的秘密(世界坐标.本地坐标).mp4│      06-

PHP100-第三讲 PHP5.4 语法、常量、变量、数据类型详解

内容摘要: ①PHP5.4 的基本语法与写作格式 ②PHP5.4 的变量与变量数据类型 ③PHP5.4 的系统常量与自定义常量 PHP5.4 的基本语法与写作格式: 任何程序语言都有自己的语言风格,PHP语言也有自己独特的风格,虽然也继承了许多Perl和C的语言特色.但经过多年的发展PHP已经成为了一个成熟 的编程语言,所以我们还需要认真的学习PHP的独特语法.PHP一个很大的特色就是与HTML标签语言进行混编,这种模式是今后很长一段学习过程中所用到 的格式,因此我们先来通过一个例子来认识一下P

js中window对象详解以及页面跳转

js中window对象详解以及页面跳转 转自:http://www.makaidong.com/%E5%8D%9A%E5%AE%A2%E5%9B%AD%E6%90%9C/39219.shtml 1.window.top.window.location = "index.asp"; 2.window.top.location.href="index.asp" 3. window.top.location.replace("index.asp");

PHP5.4 语法、常量、变量、数据类型详解

1.php5.4的基本语法与写作格式 短标签模式的开启: ; short_open_tag php语句的分隔符: <?php $php=true; if($php){     echo "It is true";//分号介绍 }    //大括号结束: ?> 函数的使用格式: 1.返回值 函数名() 2.返回值 函数名(参数,参数...) 3.函数名 (参数,参数..,返回变量) 4.返回值 函数名(...)调用符 2.php5.4的变量与变量数据类型 变量用$开头,只能是

&quot;静态方法里只能调用静态变量和静态方法&quot;详解

静态方法里可以调用静态方法和静态变量,同时也能调用非静态方法和非静态变量. public class Test { public Test() {}; public Test(int i) {this.n = i;} public static int m = 5; public int n = 10; public void fun1() {System.out.println("非静态方法fun1");} public static void fun2() {System.out.

js变量及其作用域(附例子及讲解)

Javascript和Java.C这些语言不同,它是一种无类型.弱检测的语言.它对变量的定义并不需要声明变量类型,我们只要通过赋值的形式,可以将各种类型的数据赋值给同一个变量 工具/原料 Chrome 浏览器(以下代码测试均由Chrome调试) 方法/步骤 js变量的类型及申明方式等等,本文不再说明,读者可以参考相关官方文档 这里主要介绍js变量及其作用域 js变量作用域可分为:"全局变量"和"局部变量" "全局变量":申明在函数之外的变量 &q

oracle 游标变量ref cursor详解

oracle 游标变量ref cursor详解 分类: PL/SQL开发 2013-12-04 15:15 685人阅读 评论(0) 收藏 举报 oracleref cursor 一 介绍      像游标cursor一样,游标变量ref cursor指向指定查询结果集当前行.游标变量显得更加灵活因为其声明并不绑定指定查询. 其主要运用于PLSQL函数或存储过程以及其他编程语言java等程序之间作为参数传递.     不像游标的一点,游标变量没有参数.     游标变量具有以下属性:     (