变量与参数范围和分配值

时间:2014-01-14 19:35:15

标签: javascript

我一直在观看Douglas Crockford的视频系列节目。关于将变量赋值为将变量赋值为全局变量的参数的关系,我有点困惑,让我演示一下。

var bob = 22; //global scope
function funky(parameter){
    parameter = null; //sets the var passed in to null
    bob = 44; //sets the bob 
}

var hello = [];
funky(hello); // hello still has the value of an empty array even after the function is invoked.
bob; // value is 44

因此,当调用funky()时,'var bob'被赋值44。这个bob将新值保存在函数范围之外。

var hello作为参数传递,而在funky中,它的值为null,在全局空间中调用hello时,它保存一个空数组的值。

这只是我要记住的东西吗?如果全局范围中定义的变量作为参数传递,它只会在函数范围内保存它的新指定值吗?我是否在一个更广泛的范围内错过了一个参数如何在函数中传递和分配?

这是在函数/全局范围内外都有console.log输出的代码的repl.it。

http://repl.it/NgN

4 个答案:

答案 0 :(得分:3)

因为这行

parameter = null;

仅设置函数参数的值,而不是传入的变量的值。但是,函数内的bob被解释为对全局变量,因此它确实修改了外部值。

但请注意,对象是引用,所以如果你这样写:

function funky(parameter){
    parameter.hello = null;
}

然后调用funky会直接修改参数引用的对象。

var x = { hello: [] };
funky(x); // x => { hello: null }
  

这只是我要记住的事情吗?

是的,了解参数的传递方式非常重要。

  

如果全局范围中定义的变量作为参数传递,它只会在函数范围内保留它的新指定值吗?

参数仅在函数范围内保存其值。全局变量是全局变量,因此如果在函数内部修改它们,它们会将该值保留在函数之外。

另外,请注意隐藏 - 如果参数与全局变量同名,则该参数会将该变量隐藏在该函数的范围内。

答案 1 :(得分:1)

关于这个:

  

var hello作为参数传递,而在funky中,它的值为null,在全局空间中调用hello时,它保存一个空数组的值。

不要将parameter视为hello别名。它们是不同的变量。他们可以自由地指出不同的事情。在null <{1}}中为parameter 分配值hellohello 无效。在该行之后,全局变量parameter仍指向空数组。只有funky(hello)指向null。

此外,hellofunky传递给var arr = []; function addElements(arr) { arr.push(5); arr.push(77); } 函数。请考虑以下事项:

arr

addElements执行后,全局arr仍为空。函数内的arr与全局范围中的arr不同。 (我应该注意,每个{{1}}的内容可能指向相同的对象,但这是一个单独的问题。)

(另请注意some languages do allow the sort of aliasing you seem to expect,但这不是JavaScript中传递参数的方式。)

答案 2 :(得分:1)

JavaScript假定如果为变量赋值,则它在全局范围内 - 除非该变量是使用var声明的。例如,这个:

var bob = 22; //global scope
function funky(parameter){
    parameter = null; //sets the var passed in to null
    var bob = 44; //sets the bob 
}
var hello = [];
funky(hello); // hello still has the value of an empty array even after the function is invoked.
bob; // value is 22

由于函数的bob变量是使用var声明的,因此它由函数的本地范围所有,并且对函数范围外声明的bob没有影响。< / p>

关于对象在传递给函数时如何与基元不同,请查看Jonathan Snook的文章http://snook.ca/archives/javascript/javascript_pass以及来自@ p.s.w.g的有用评论。

答案 3 :(得分:1)

好的,所以下面的例子会让你更加困惑。

var a = {'a':'A'};

function foo(param){param.a ='B';}

FOO的(a);

//现在打印一个 {'a':'B'}

这是一个重要的概念:

  

基元按值传递,对象通过“引用副本”传递。

至于更多信息,您可以查看以下答案: Does Javascript pass by reference?