首页 > javascript 中 为什么一个函数的参数 也属于局部变量

javascript 中 为什么一个函数的参数 也属于局部变量

ex:
// 全局变量

var foo = 1;
var bar = 2;
var i = 2;

function test(i) {
    // 函数 test 内的局部作用域
    i = 5;

    var foo = 3;
    bar = 4;
}
test(10);

foo 和 i 是函数 test 内的局部变量,而对 bar 的赋值将会覆盖全局作用域内的同名变量。

为什么i属于局部变量 但是i 没有显示var 声明不应该是全局变量?


var i=9;//定义了一个全局变量i
  function foo(i){ //这里的i是参数
      i =5;  // 这里的i首先肯定不是局部变量,如果要定义局部变量的话,需要加个var 如果不加的话,定义的是全局变量。
  //但这里的情况不是这样的,因为i是参数,所以,这里实际上你是把参数重新赋值了。这在实际中是肯定不会这样写的。
  

    console.log(i);
   }
   
   foo(7);//结果是5

这里实际上涉及到了"JS词法分析"的知识,楼主可以搜索“JS词法分析"了解更多。

补充:
楼主修改了问题:为什么i属于局部变量 但是i 没有显示var 声明不应该是全局变量?

i其实是函数的参数,函数的参数作用域当然只能在函数内部。


表示看问题没看懂问啥呢,看答案才看懂,感情是在纠结函数参数和全局变量问题,别看它们都叫i,你得就近啊……


你说的很对
这个没有为什么,就是这么规定的。

具体的可以参考我的博客:
http://zonxin.github.io/post/2015/10/javascript-hoisting/


题设不知所云。

什么迹象表明它是你所认为的局部变量,你倒是说呀!


var foo = 1;//声明全局变量foo
var bar = 2;//声明全局变量bar
var i = 2;//声明全局变量i
//声明函数一个带1个形参的函数test
function test(i) {
    i = 5;
    var foo = 3;//申明函数内部变量foo
    bar = 4;
}
test(10);
console.log(foo);//1
console.log(bar);//4
console.log(i);//2

上面的代码在声明解析阶段,再全局环境的作用域下注册声明变量foo/bar/i及函数对象test
在函数test作用域下注册声明foo/i,并引用bar这个全局作用域下的变量bar,此时i为函数的参数变量而非全局变量i,只是just名字相同而已~~~,foo通过var关键字声明为函数内部变量

是不是和闭包的行为很类似啊,对了JS全局环境就是一个大的闭包~~~~
在JS代码在声明解析阶段是不执行代码的

在test函数执行阶段,传入参数10,将其赋值给参数变量i,此时i=10;
i再被重新赋值为5,foo被赋值为3,bar被赋值为4

全局变量bar就被赋值为4,为变量foo和i随着函数的执行完毕,被从执行栈中清除掉了,外部不可再被访问到~~~

和下面的代码一样一样的~~~

var foo = 1;
var bar = 2;
var i = 2;
//声明函数一个带1个形参的函数test
function test(k) {
    k = 5;
    var foo = 3;
    bar = 4;
}
test(10);
console.log(foo);//1
console.log(bar);//4
console.log(i);//2
console.log(k);//ReferenceError: k is not defined

我觉得你的逻辑有点诡异

var i=9;
function foo(i){
i =5;  // i 为函数声明时的参数啊,为什么还需要再用var声明一次
console.log(i);    //因为i经过赋值,所以输出5
}

而且我觉得你需要理解一下javascript的参数:

每个函数function都的原型都是function.prototype函数原型。
而函数原型有一个属性为arguments,是个数组。
每次function(a,b,c,...)将abc参数赋值给function执行时。
就相当于把a,b,c,...这些参数赋值给arguments数组。
你可以试一试,你看看下面的函数

var i=9;
function foo(i){
arguments[0] =5;  
console.log(i);
}
foo(i)    //输出5,和你题目中的函数输出的一样;

这样扭回头来看:
arguments数组函数原型的属性
是每一个函数里的变量
自然你在函数内部对它进行赋值
log出来肯定是赋值后的值

如果还有什么不明白的,推荐《javascript高级程序设计》


题主,我终于帮你找到了根本原因。下面这段话引自ECMAScript 5.1的10.5节:

10.5 Declaration Binding Instantiation
Every execution context has an associated VariableEnvironment. Variables and functions declared in ECMAScript code evaluated in an execution context are added as bindings in that VariableEnvironment‘s Environment Record. For function code, parameters are also added as bindings to that Environment Record.

这段话说明了:不论是在函数中用var声明的变量,还是函数的参数,都是绑定到执行上下文中的变量环境中的环境记录项的。换句话说,JS引擎对它们的处理方式是没有区别的,都是作为局部变量。要说区别的话,只是它们的初始化方式不一样。

还是那句话:有问题就找规范。

最后,纠正一下几个回答中的错误:题主说的没错,那个i = 5中的i就是局部变量,这个i跟函数的参数i是同一个东西。说i是全局变量的同学们,都去面壁吧 :)


一个靠谱的答案都没没有,最后只能强记了!

【热门文章】
【热门文章】