Javascript 调用引用

Javascript Call By Reference

本文关键字:引用 调用 Javascript      更新时间:2023-09-26

我对一些我不理解的代码有一个快速的问题:

var anonymousGreet = function(){
    console.log('Hi');
}
function log(a){
    console.log(a);
}
log(anonymousGreet);

在上面的代码中,当我调用函数日志并传入函数表达式 anonymousGreet 作为要记录的参数时。这是否意味着日志中的变量"a"指向变量匿名问候,然后指向函数对象。还是直接指向 anonymousGreet 指向的函数对象?如果第一个指向变量匿名问候,或者它直接指向匿名问候指向的函数对象,我有点困惑。抱歉,如果这令人困惑,但任何帮助将不胜感激!谢谢!

如果你来自C++背景,那么一个简单的合理化是

  • 在Javascript中,一切都按值传递,从不使用引用
  • 但是,所有传递的值都是指向对象的指针

例如,当您编写:

a = b + c;

你应该想象(C++(类似的东西

Object *a, *b, *c;
a = new Number(b->numericValue() + c->numericValue());

(请注意,Javascript与C++不同,它提供了一个垃圾收集器,因此不需要显式delete(。

当然,这只是对可观察行为的简单描述(它可能是第一个Javascript引擎的实现(。今天,幕后真正发生的事情要复杂得多,包括机器代码(JIT(的运行时生成。

例如,这是原因

function foo(x) {
   x[0] = 1;
}
var a = [0];
foo(a); // Will change the content of a[0]

function bar(x) {
    x = 9;
}
var b = 0;
bar(b); // Will *NOT* change the content of b

是的,如果你勾选a===anonymousGreet,结果是真的。所有基元值都是按值传递的,但在 Javascript 中,对象是通过引用传递的。

var anonymousGreet = function(){
    console.log('Hi');
}
function log(a){
    console.log(a === anonymousGreet); //true
    console.log(a);
}
log(anonymousGreet);

作为一个术语问题,为了避免混淆,我会避免使用"指针"这个词。使用"指针"一词时很容易混淆。有时"A 指向 B"可能意味着 A 是 B 的一种别名。或者 B 可以通过 A 进行修改。或者 A 可以指向指向 B 的 B,而 B 指向 C;那是什么意思?

IMO 使用术语更清楚,即在 JavaScript 中变量保存一个值。就是这样。它有一个价值。它不指向任何东西,它不引用任何东西,它有一个价值。

但是,两个变量可能保存相同的值,例如空数组[]

var a = [];
var b = a;

ab 都保存相同的值,即特定的空数组。我们可以通过检查 a === b 看到它们具有相同的值。由于它们具有相同的值,因此可以通过任何一个来操纵该值; a.push(1)b.push(1)做完全相同的事情,因为他们都在操纵各自持有的共同价值。重新分配给a只会更改a持有的值;它不会也不能影响b,反之亦然。 b不是指向a的"指针",也不是指向a的别名;它是一个变量,恰好与a具有相同的值。

换句话说,a = b并没有a"指向"b。它也不会复制b的值并将其分配给a。它给a b的值,所以ab现在保持相同的值。

可以将函数参数传递机制视为一种特定类型的赋值。它使函数定义中的形式参数假定或保持调用中指定的参数的值。当我定义一个函数时

function foo(x) { console.log(x); }

然后调用它

var y = 42;
foo(y);

变量/参数x被分配在函数调用中传递的参数的值。换句话说,x开始拥有y的价值。 x没有"指向"y,也不是y的副本。它y 具有相同的值,在本例中为 42

让我们以您的具体示例为例:

var anonymousGreet = function(){
  console.log('Hi');
}
function log(a){
  console.log(a);
}
log(anonymousGreet);

在这种情况下,anonymousGreet是一个变量,由于赋值,它的值是特定的匿名函数。当您调用 log(anonymousGreet) 时,log函数a参数设置为在调用中保存参数的值,因此它现在保存 anonymousGreet 的值。它不会"指向"变量anonymousGreet,对它的任何更改都不会影响anonymousGreet的值,当然也不会影响该值所代表的函数。

这是否意味着 log 中的变量a指向变量anonymousGreet然后指向函数对象?

不,这意味着日志中a变量/参数保存由 anonymousGreet 持有的值,这是匿名函数。

还是a直接指向anonymousGreet指向的函数对象?

是的,但不是"指向指向的东西",而是"持有anonymousGreet的值,它持有匿名函数作为其值。