1

我无法让我的 javascript 函数工作。

if (!cHp) { cHp = 200 };

像魅力一样工作,但是

function checkNull(x, y) {
if (!x) { x = y; }
}

根本不起作用。

我究竟做错了什么?

4

2 回答 2

7

它确实有效,但对您没有任何好处,因为 JavaScript 纯粹是按值调用。这意味着在您的函数中,参数“x”和“y”包含调用环境中存在的值的副本

因此,

checkNull(b, 2 + 17);

导致将变量“b”的值和数字 19 的副本传递给函数。该函数可以对“x”和“y”做任何它想做的事情,但这对调用上下文中的变量“b”没有影响。

编辑- 可以扩展这个话题并切断过长的评论线程,让我们谈谈“按值调用”(以及,相比之下,“按引用调用”)的含义。在按值调用参数传递方案中,调用环境中的实际参数值被复制到被调用函数的参数变量中。在按引用调用方案中,对调用环境中某种变量的引用被传递给被调用函数。这两者有什么不同?

在按值调用方案中,会发生以下情况:

var a = 1;
function change(b) {
  b = 2;
}

change(a);
alert(a); // still 1

然而,在按引用调用的方案中,这是真的:

// FANTASY CODE - NOT REAL JAVASCRIPT
var a = 1;
function change(b) {
  b = 2;
}

change(a);
alert(a); // it is 2 in this fantasy call-by-reference code

请注意,引用调用方案的一个含义是调用环境中的实际参数必须是变量或对象属性或其他东西;也就是说,它必须是编程语言术语中所谓的“左值”。另一种说法是它必须是可以出现在赋值表达式左侧的东西。

由于 JavaScript 中的变量将对象作为它们的“值”,事情变得有点混乱。当您将对象分配给变量时:

var myObj = {};

您实际上是在分配对该对象的引用。这在 JavaScript 中是完全透明的,你真的不需要考虑它。处理对象值就像 JavaScript 中的原始值一样简单。然而,这意味着当一个对象值被传递给一个函数时,变量的实际值是对该对象的引用这一事实意味着 JavaScript 的按值调用语义看起来类似于 call-by -参考方案:

var a = { property: 1 };
function change(b) {
  b.property = 2;
}

change(a);
alert(a.property); // it's 2!! OMG call-by-reference! (not)

是的,函数可以修改作为参数传递的对象的属性值。那是引用调用吗? ,不是,至少如果您关心“引用调用”一词的含义,则不是。即使那个函数可以改变“property”属性的值,它仍然不能改变“a”本身的值! 这就是引用调用的意思。

现在还有其他很少见的参数传递方案。一种令人着迷的是 ALGOL 60 中的“按名称调用”。该方案所做的是将实际参数排序视为隐式函数,这样在被调用函数中对参数的引用将重新-评估参数表达式。还有“call-by-value/result”,表示实际参数是按值传递的,但是当函数返回时,函数中参数的then-current值被隐式复制回调用中的源变量环境。(该方案还要求实际参数是左值,如引用调用。)

于 2013-04-24T13:43:26.473 回答
0

您需要做的是让函数返回一个值并将返回值分配给一个变量。尝试这样的事情:

var checkNull = function (x, y) {
        if (!x) {
            return y;
        }
        return x;
    },
    cHp,
    testVar;

cHp = checkNull(testVar, 200);  // will return 200 since testVar is undefined

testVar = 100;

cHp = checkNull(testVar, 200);  // will return 100 since testVar is defined
于 2013-04-24T14:13:51.277 回答