Javascript按引用调用

时间:2015-10-17 06:31:35

标签: javascript

我对一些我不理解的代码有一个简单的问题:

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

function log(a){
    console.log(a);
}

log(anonymousGreet);

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

3 个答案:

答案 0 :(得分:4)

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

  • 在Javascript中,所有内容都按值传递,从不使用引用
  • 然而,所有传递的值都是指针到对象

例如,当你写:

a = b + c;

你应该想象(在C ++中)

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

(请注意,但是,与C ++不同的Javascript提供了垃圾收集器,因此不需要显式的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

答案 1 :(得分:2)

是的,如果您检查=== anonymousGreet,结果为true。所有原始值都按值传递,但对象在Javascript中通过引用传递。



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

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

log(anonymousGreet);




答案 2 :(得分:2)

作为术语问题,为了避免混淆,我会避免使用“指针”这个词。使用“指针”一词时很容易混淆。有时“A指向B”可能意味着A是B的一种别名。或者B可以通过A修改。或者A可以指向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)时,a函数的参数log会设置为保存调用中参数的值,因此它现在保持anonymousGreet的值。它没有“指向”变量anonymousGreet,对它的任何更改都不会影响anonymousGreet的值,当然也不会影响该值所代表的函数。

  

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

不,这意味着日志中的变量/参数a包含anonymousGreet所持有的,这是匿名函数。

  

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

是的,但不是“指向”指向的东西,而是“保持anonymousGreet的值,其值为匿名函数。