js中变量含(参数数组)作用域传递问题

Posted kathy+

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了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,引用传递指针,值也变了。












































以上是关于js中变量含(参数数组)作用域传递问题的主要内容,如果未能解决你的问题,请参考以下文章

变量作用域和内存问题

js 闭包

js 函数参数传递引用类型与基本类型

Bash的变量类型

post 传递参数中包含 html 代码解决办法,js加密,.net解密

JS作用域作用域链