鉴于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
答案 0 :(得分:2)
var func = function() { alert(1); };
这里创建了一个新函数,并将对它的引用复制到func
var func_alias = func;
存储的函数引用func
被分配给另一个变量func_alias
var func = function() { alert(2); };
创建另一个新函数,并将其引用分配给func
。存储在func
中的第一个函数的引用将丢失。但是,由于您在覆盖func_alias
之前将其保存在func
中,因此仍然可以调用它。
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_alias
的值以及obj
的值仍然相同,因为您还没有覆盖它们。它们都包含对步骤1中创建的对象的引用。
编辑#2
这可以用 C 术语来解释。
当您通过var obj = {prop: 'val'};
创建对象时 - 假设该对象存储在内存中的地址0x0001处。即obj的实际值是0x0001
当您将其分配给obj_alias
时,obj_alias
也会获得值0x0001 - 现在两个变量都指向存储在地址0x0001的内容
当您执行obj.x = y
时,您不会覆盖obj
的值,而只会使用obj
来访问存储在0x0001中的对象并修改其中一个属性
答案 1 :(得分:1)
区别在于
在第一段代码中,您让变量引用另一个对象。
在第二段代码中,你改变了对象的属性,这两个变量是指同一个对象。
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
答案 2 :(得分:0)
如果您认为您的程序代码是一个允许您存储和使用对象的大型仓库
然后您的代码执行以下操作:
第1行 - 让我们存储函数SOMEWHERE和I(第一个变量)将记住它[你不能(也不能)指定特定位置]。
第2行 - 让其他人记住函数的存储位置。
第3行 - 让我们存储另一个函数SOMEWHERE和我(第一个变量)会记住它[你不能(也不能)在这里指定特定位置]。
第4行 - 向第2行的那个人询问我的职能。
您的预期结果是什么?