zoukankan      html  css  js  c++  java
  • js中变量含(参数、数组)作用域传递问题

        js没有块级作用域(你可以自己闭包或其他方法实现),只有函数级作用域和全局作用域,函数外面的变量函数里面可以找到使用,函数里面的变量外面无法访问到。

    写这个是因为ES6中的一个例子开始的。首先看下例子

    var a = [];
    for (var i = 0; i < 10; i++) {
      a[i] = function () {
        console.log(i);
      };
    }
    a[6](); // 10

    var a = [];
    for (let i = 0; i < 10; i++) {
      a[i] = function () {
        console.log(i);
      };
    }
    a[6](); // 6
    这两个实例的区别在于定义i的时候,循环先执行完后,等待调用执行的时候,i才会被赋值给函数体内,等于是循环先给数组赋值完毕后。等待调用。而不是循环的时候就把i的值log出来!
    两个例子一个用了var 一个用let定义变量。 let是有块级作用域,因此每次循环体的i都是不同且独立的
    上面代码中,变量ivar命令声明的,在全局范围内都有效,所以全局只有一个变量i
    每一次循环,变量i的值都会发生改变,而循环内被赋给数组a的函数内部的console.log(i),里面的i指向的就是全局的i。也就是说,所有数组a的成员里面的i,指向的都是同一个i,不管是循环到第几次,导致运行时输出的都是最后一轮的i的值,也就是10。

    var a=10
    function aaa(a){
    alert(a);
    }
    function bbb(){
    var a=20;
    aaa();

    }
    bbb();

    //---结果输出10  执行函数bbb 里面会执行aaa() aaa里面的alert 里的a 寻找作用域,自身有局部变量的话输出自己,没有的话去aaa的作用域找 上层的var a=10便是。

    function aaa(){

    var a=b=10

    }

    // alert(a) //error 

    alert(b)// 10

    var a=b=10这种写法在函数内,b其实是全局变量,a当然是局部变量
    执行完aaa(),在全局域里alert(a),当然是undefined,alert(b),就会弹出10

     var a=10

    function aaa(){

    console.log(a)

    var a=20

    }

    aaa() //undefined 变量提升  这个函数执行时等于

    var a=10

    function aaa(){

    var a;

    console.log(a)

    var a=20

    }

    在看一个相似的

     var a=10

    function aaa(){

    console.log(a)

     a=20

    console.log(a)

    }

    aaa() //10  20

    这个吧,就验证了第二条,虽然是就近原则,但是是就近找var声明的变量,这个是因为没有var声明的变量是全局的,这里只是修改了a的值。所以上面就是因为在函数内没找到var的a,于是到外面去找了,一找就找到了,于是a就alert出10了;不过没错的是a=20后,a确实为20了,只不过alert的时候还没有执行到那~~

    var a=10

    function aaa(){

      bbb()

    alert(a)

    function bbb(){

     var a=20

    }

    }

    aaa()// 10

    这是因为在alert(a)的时候,bbb函数中的a确实为20 ,可是它对于这时的alert(a)这句话来说是局部的,alert(a)根本找不到bbb函数中的a,所以在aaa函数中它找不到a,于是乎去外面找,一找,就找到了10。

    var a=10
    function aaa(a){

    alert(a);
    var a=20

    }
    aaa(a)

    执行过程貌似应该是

    var a=10
    function aaa(a){
    var a;
    alert(a);
    var a=20
    //alert(a);
    }
    aaa(a)

    传递进来的10 赋给变量a alert(10) 之后var a=20 覆盖了之前的10 ,但是函数没有执行到这里就alert结束了。再后面alert(a) //20

    传参时,基本类型传值,引用类型传引用。

    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];

    变量a 将5这个值传给b  b 和a 没有关系了。

    数组是引用传递,把b的指针也指向了 同一个地址,所以b的改变 a也改变

    var a = [1,2,3];
    var b=a;

    b=[1,2,3,4]

    alert(a) //[1,2,3]

    b 被重新赋值后,指针会从新指向自己的内存地址,脱离a。

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

     var a=10;

    function aaa(a){

     a+=3

    }

    aaa(a)

    alert(a) //10

    对比:

     var a=10;

    function aaa(a){

     a+=3;

    alert(a) //13

    }

    aaa(a)

    参数传递进去的是值,里面的a是局部变量,不管怎么改都和外面的a 无关。因为不在同一个作用域上。类似:

    var a=10
    function aaa(a){
    alert(a+10)
    }
    aaa(30) //40
    alert(a)//10

    var a=[1,2,3]

    function aaa(a){

     var a=[1,2,3,4]

    }

    aaa(a)

    alert(a)// [1,2,3]  函数里面的a被重新赋值,和外层的a 不指向同一个a

    var a=[1,2,3]

    function aaa(a){

    a.push(4)

    }

    aaa(a)

    alert(a)// [1,2,3,4]

    引用改变添加元素后,指向同一个a,引用传递指针,值也变了。

    不积跬步无以至千里,不积小流无以成江海
  • 相关阅读:
    C#开发微信门户及应用(7)-微信多客服功能及开发集成
    C#开发微信门户及应用(6)--微信门户菜单的管理操作
    使用Json.NET来序列化所需的数据
    Winform开发框架里面使用事务操作的原理及介绍
    C#开发微信门户及应用(5)--用户分组信息管理
    C#开发微信门户及应用(4)--关注用户列表及详细信息管理
    基于MVC4+EasyUI的Web开发框架经验总结(3)- 使用Json实体类构建菜单数据
    基于MVC4+EasyUI的Web开发框架经验总结(2)- 使用EasyUI的树控件构建Web界面
    基于MVC4+EasyUI的Web开发框架经验总结(1)-利用jQuery Tags Input 插件显示选择记录
    如何在应用系统中实现数据权限的控制功能
  • 原文地址:https://www.cnblogs.com/ZGQ-VIP/p/11856568.html
Copyright © 2011-2022 走看看