【问题标题】:Javascript if only works outside functionJavascript 如果只在函数外工作
【发布时间】:2013-04-18 02:18:43
【问题描述】:

我的 javascript 函数无法正常工作。

if (!cHp) { cHp = 200 };

像魅力一样工作,但是

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

根本不工作。

我做错了什么?

【问题讨论】:

  • 你好像少了一个 ;我说的对吗?
  • 您没有提供足够的代码让我们确定问题所在。
  • 没有比这更多的代码了..
  • @ZheX,最后你错过了;。但是,这不是您的代码不起作用的原因。如果没有更多代码,那就是您的答案。必须调用一个函数。
  • 确实调用了它。 Pointy 修复了它,javascript 无法按照我的意愿进行操作。

标签: javascript html scripting


【解决方案1】:

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

因此,

checkNull(b, 2 + 17);

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

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

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

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 = {};

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

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值被隐式复制回调用中的源变量环境。 (该方案还要求实际参数是左值,例如按引用调用。)

【讨论】:

  • 这适用于基元,但以数组或对象为例,请参阅我的小提琴jsfiddle.net/Xotic750/pGcgy
  • 谢谢尖头。我该怎么做才能让它分配给我使用输入的变量呢?
  • @ZheX 在 JavaScript 中无法做到这一点。您可以从函数返回一个值,并在调用环境中显式地进行(重新)赋值。
  • Javascript 主要是 cal-by-reference,字符串和数字除外 - 或原语。
  • @Xotic750 数组和对象也是传值的;所涉及的“价值”是对象的引用。在讨论编程语言语义时,术语“引用调用”具有特定含义,而通过传递引用修改对象的能力则没有这个含义。
【解决方案2】:

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

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

【讨论】:

  • 当然,checkNull 函数命名错误,因为它实际上并不是测试 x 是否为 null,而是测试 x 的真实性。
猜你喜欢
  • 2018-04-27
  • 1970-01-01
  • 1970-01-01
  • 2023-02-04
  • 2015-09-01
  • 1970-01-01
  • 1970-01-01
  • 2020-11-21
  • 1970-01-01
相关资源
最近更新 更多