【问题标题】:Javascript functions - copied by reference, but what's going on here?Javascript 函数 - 通过引用复制,但这里发生了什么?
【发布时间】:2012-08-11 13:34:29
【问题描述】:

JavaScript 中的给定函数是引用类型(通过引用复制,与简单类型不同),这里到底发生了什么?

var func = function() { alert(1); };
var func_alias = func;
var func = function() { alert(2); };
func_alias(); //1

如果func_alias 是对func 的引用,为什么它不更新?您不希望它的调用(第 4 行)返回 2 吗?

这是与其他引用示例不同的行为:

var obj = {prop: 'val'};
var obj_alias = obj;
obj.prop = 'updated val';
alert(obj_alias.prop); //updated val - not original one

func_alias 似乎保留了原始的副本,预覆盖func - 简而言之,它的行为似乎是按价值复制的。这当然被以下证据证明:

var func = function(){}
var func_alias = func;
func === func_alias; //true

【问题讨论】:

    标签: javascript function reference variable-assignment


    【解决方案1】:

    var func = function() { alert(1); };

    这里创建了一个新函数,并将对它的引用复制到func

    var func_alias = func;

    存储的函数引用是func,赋值给另一个变量func_alias

    var func = function() { alert(2); };

    创建了另一个新函数,并将对它的引用分配给func。对存储在func 中的第一个函数的引用丢失。但是由于你在覆盖func之前将它保存在func_alias中,所以仍然可以调用它。

    func_alias();

    func_alias 在步骤 2 中被分配了对第一个函数的引用(并且在那之后没有被覆盖)。所以第一个函数被调用了。


    编辑#1

    根据您使用对象的第二个示例:

    var obj = {prop: 'val'};
    

    在这里,创建了一个新对象并将对它的引用分配给obj

    var obj_alias = obj;
    

    引用被复制到另一个变量 obj_alias

    obj.prop = 'updated val';
    

    这里你并没有覆盖obj 的值,而只是覆盖了存储在obj 中的那个引用所指向的对象的一个​​属性。 obj 的值(即对第一步创建的对象的引用)保持不变。

    在您的函数示例中,您实际上是用新的函数引用覆盖了变量 func

    alert(obj_alias.prop);
    

    obj_aliasobj 的值仍然相同,因为您还没有覆盖它们。它们都持有对第 1 步中创建的对象的引用。


    编辑#2

    这可以用 C 术语很好地解释。

    • 当您通过var obj = {prop: 'val'}; 创建对象时 - 假设该对象存储在内存中的地址 0x0001 处。即obj的实际值为0x0001

    • 1234563
    • 当您执行obj.x = y 时,您不会覆盖obj 的值,而只是使用obj 访问存储在0x0001 的对象并修改其属性之一。

    【讨论】:

      【解决方案2】:

      区别是

      在第一段代码中,您让一个变量引用另一个对象。

      在第二段代码中,你改变了对象的属性,这两个变量是指同一个对象。

      var func = function() { alert(1); };
      var func_alias = func; // func_alias refer to the first function.
      var func = function() { alert(2); }; // let func refer to another function, but won't affect func_alias
      func_alias(); //1
      

      【讨论】:

        【解决方案3】:

        如果您认为您的程序代码是一个允许您存储和使用对象的大型仓库。
        然后您的代码执行以下操作:
        第 1 行 - 让我们存储函数 SOMEWHERE 并且我(第一个变量)会记住它的位置 [您没有(也不能)在此处指定特定位置]。
        第 2 行 - 让其他人也记住函数的存储位置。
        第 3 行 - 让我们在 SOMEWHERE 存储另一个函数,我(第一个变量)会记住它在哪里[您没有(也不能)在此处指定特定位置]。
        第 4 行 - 询问第 2 行的人我的职能在哪里。

        你期望的结果是什么?

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2020-03-12
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2018-04-02
          相关资源
          最近更新 更多