当一个变量传递给一个函数时,实际传递了什么?

时间:2012-09-22 01:20:31

标签: javascript function arguments

另一个线程告诉我,在函数退出后,从函数内对其操作数进行的任何修改都将持续存在。我一直认为它是传递给它的所有值的临时副本,然后唯一坚持的是返回值和隐式更广泛的已修改的范围变量。

我想回想一下我已经达到顶峰的所有jquery插件,他们都使用了构造:

(function($){
  $.fn.foo = function(){ console.log('foo'); };
})(jQuery);

这意味着即使是内部作用域jQuery标识符对$对象的修改在函数退出后仍然存在,或者jQuery插件不起作用。因此,这可以像上面的代码片段那样工作:

var x = {n:0};

(function addOneTo(p) {
  p.n = p.n + 1;
})(x);

console.log(x);

但是这个:

var x = 0;

(function addOneTo(p) {
  p = p + 1;
})(x);

console.log(x);

不会,x未修改,其值为0

有人可以解释一下参数传递的工作原理吗?我以为我知道它是怎么做的,但我想我不知道。感谢

3 个答案:

答案 0 :(得分:1)

当你有:

p.n = p.n + 1;

您正在做的是修改在{strong>引用对象n中的p属性到p。换句话说,p = p + 1; 可以看作是指向对象的指针,也就是说,它将引用保存到原始对象,该对象的参考值已传递给函数。另一方面,当你有:

p

您只需替换 p + 1所持有的对象参考值,并评估表达式p的结果。您修改{{1}}对象的任何属性。

答案 1 :(得分:1)

实际上非常简单:Javascript中的每个名称都指向内存中的一个对象(即使你没有以面向对象的方式思考它) - 它是内存中的一个位置,其中该元素的数据结构“是。

因此,如果传递的值是一个像数组的对象,或者其他具有属性和名称的元素,那么你在函数中得到的就是同一个对象。如果你改变了它的属性(比如上面的p.n = p.n + 1例子),因为“p”对象在内部是相同的而且在函数之外。

现在,执行:p = p + 1时,名称为p引用的原始对象将替换为另一个对象 - 在表达式中创建的对象,其值为{{ 1}}。函数内部的名称p + 1指向另一个对象,完全位于另一个内存位置,原始的一个传递给函数,而名称为p的引用则保持不变。

这种机制与Python语言完全相同,例如。

答案 2 :(得分:1)

实际上在你的第一个例子中

var x = {n:0};
(function addOneTo(p) {
    p.n = p.n + 1;
})(x);
console.log(x);

x是一个对象,当你使用p.n = p.n + 1;时,它修改了原始对象的属性,因为它作为引用传递(p是与x相同的对象),但是在你的第二个例子中

var x = 0;
(function addOneTo(p) {
    p = p + 1;
})(x);
console.log(x);

x通过值传递给函数,p = p + 1;此处p是该函数内的新私有变量,它只有函数范围。