1

我已经尽力解决这个问题,现在我被卡住了,为什么第四个警报返回未定义?

function buttonClick()
{
  var myTest = function()
  {
    var _setDirectlyInside = "So far so good...";
    var _setInFunctionCalledInside;
    var _setInFunctionCalledFromOutside;

    (function(){
      _setInFunctionCalledInside = "This would indicate scope isn't the problem?";
    })();

    return {
      basic : "Easy stuff",
      setDirectlyInside : _setDirectlyInside,
      setInFunctionCalledInside : _setInFunctionCalledInside,
      functionCallFromOutside : function(){
        _setInFunctionCalledFromOutside = "Why does this come back as undefined?";
      },
      setInFunctionCalledFromOutside : _setInFunctionCalledFromOutside
    }
  };

  var test = myTest();

  alert(test.basic); // Returns "Easy stuff"
  alert(test.setDirectlyInside); // Returns "So far so good..."
  alert(test.setInFunctionCalledInside); // Returns "This would indicate scope isn't the problem?"

  test.functionCallFromOutside();
  alert(test.setInFunctionCalledFromOutside); // Broken, returns undefined
}

解析度:

setInFunctionCalledFromOutside : _setInFunctionCalledFromOutside, // Won't work
setInFunctionCalledFromOutsideGetter : function(){
    return _setInFunctionCalledFromOutside; // Will work
}

...

alert(test.setInFunctionCalledFromOutside); // Broken, returns undefined
alert(test.setInFunctionCalledFromOutsideGetter()); // Now works
4

3 回答 3

2

这:

return {
  basic : "Easy stuff",
  setDirectlyInside : _setDirectlyInside,
  setInFunctionCalledInside : _setInFunctionCalledInside,
  functionCallFromOutside : function(){
    _setInFunctionCalledFromOutside = "Why does this come back as undefined?";
  },
  setInFunctionCalledFromOutside : _setInFunctionCalledFromOutside
}

...不会导致setInFunctionCalledFromOutside总是返回相同的_setInFunctionCalledFromOutside. 相反,_setInFunctionCalledFromOutside将在return语句执行时进行评估,其值将放在setInFunctionCalledFromOutside. 因此,functionCallFromOutside()对 没有影响setInFunctionCalledFromOutside

于 2012-11-10T00:26:19.593 回答
1

@nnnnnn 说得最好,但他删除了他的答案。 setInFunctionCalledFromOutside不是指向. _ _ _setInFunctionCalledFromOutside在创建返回的对象时,setInFunctionCalledFromOutside被分配了具有的值_setInFunctionCalledFromOutside。由于尚未分配任何值,因此值为undefined。改变一个的值,不会改变另一个的值。

一个更简单的例子说明了相同的原理:

var i = 0;
var n = i;
i++;
alert(i);  // 1
alert(n);  // still 0
于 2012-11-10T00:39:23.247 回答
1

添加到其他 - 作为参考,JS 按值传递字符串和数字。它通过引用传递/分配对象、数组和函数。

这不是您遇到的障碍(因为您的内部变量是undefined在您将其分配给外部变量时),但即使您确实修复了第一部分:

var internal = "string";
return {
    external : internal,
    setInternal : function (val) { internal = val; }
};

这仍然不能解决问题,因为obj.external将始终继续是“字符串”。
为什么?
因为您设置external为与赋值时相同的值internal,而不是等于 a referenceof internal(即:指向它的指针)。

如果您正在寻找一个指针,然后创建internal一个对象:

var internal = { string : "my string" };
return {
    external : internal,
    setInternal : function (val) { internal.string = val; }
};

obj.external.string;  // "my string"
obj.setInternal("Bob was here");
obj.external.string;  // "bob was here"

为什么它现在有效?
因为 internal 是一个对象,当你分配external's 的值时,你给它一个指向对象的指针,该对象internal也有一个指向的对象。
当您更改 的属性时internal,例如internal.string,因为external指向同一个对象,external.string所以具有相同的值。

如果您设置internal为完全不同的东西,那么您将指向internal其他东西(例如internal = null;),因此external当您修改 时将不再改变internal,因为internal不再指向它曾经是的对象。

于 2012-11-10T00:53:33.637 回答