Javascript函数指针赋值

nia*_*her 47 javascript function-pointers

考虑这个javascript代码:

var bar = function () { alert("A"); }
var foo = bar;
bar = function () { alert("B"); };
foo();
Run Code Online (Sandbox Code Playgroud)

运行此代码时,我得到"A".这种行为是javascript规范的一部分吗?我可以依赖它吗?

小智 63

在其他示例中,没有任何值按值传递; 一切都通过参考传递.

bar和foo是两个指针

javascript中NON原始对象的所有变量/句柄都是指针; 指针是javascript原生的,它们是默认的.

var bar = function () { alert("A"); } //bar is a pointer to function1
var foo = bar;  //pointer copied; foo is now also a pointer to function1
bar = function () { alert("B"); };  //bar points to function2
foo();  //foo is still a pointer to function1
Run Code Online (Sandbox Code Playgroud)

如果您认为它们是副本,您将遇到隐藏的错误和错误.特别是如果你使用复杂的对象.例如

function person(name){this.name = name}
var john = new person("john")
var backup = john
backup.name //john
john.name = "jack"
backup.name //jack, NOT john
Run Code Online (Sandbox Code Playgroud)

要真正复制javascript中的非原语需要更多的工作而不仅仅是a = b.例如:

function person(name){  this.name = name}
var john = new person("john")
var backup = new Object()
backup = JSON.parse(JSON.stringify(john))
backup.__proto__ = john.__proto__   //useful in some cases
john.name = "jack"
backup.name //john
Run Code Online (Sandbox Code Playgroud)

  • 谢谢你澄清这一点,我很困惑在网上搜索,当我被告知他们不是"函数"是原始的. (2认同)
  • 这个答案应该证明为什么我们应该学习更多的计算机科学和更少的编程...... (2认同)

cle*_*tus 38

是的,这是预期的和设计的.

你的问题基本上是:做foo参考bar在另一种语言的指针或引用会吗?

答案是否定的:在价值bar,在分配的时间分配给foo.

  • 只是为了澄清这个答案的最后一句话,请记住'bar的值'是'指向函数的指针',而不是函数本身.因此,在`foo = bar`之后,foo接收该指针的copy -by值,因此foo和bar都指向独立的函数对象. (3认同)

Bob*_*Bob 19

我在这里有点晚了,但我想我会给出一个答案,然后把一些东西拿出去.

在处理规范时讨论JavaScript(或ECMAScript)的内部时,最好不要考虑指针和内存引用.变量是内部的环境记录,由名称而不是内存地址存储和引用.您的赋值语句在内部和设计上正在查找环境记录名称("foo"或"bar")并将值分配给该记录.

所以,

var bar = function () { alert("A"); }
Run Code Online (Sandbox Code Playgroud)

正在为环境记录"bar"分配值(匿名函数).

var foo = bar;
Run Code Online (Sandbox Code Playgroud)

在内部调用GetValue("bar"),它检索与记录"bar"相关联的值,然后将该值与记录"foo"相关联.因此,之后bar的原始值仍然可以使用,因为它现在与foo相关联.

因为字符串而不是内存地址的JavaScript引用正是您可以执行以下操作的原因:

someObject["someProperty"]
Run Code Online (Sandbox Code Playgroud)

这是根据属性名称查找值.


pol*_*nts 5

是的,变量指的是函数没有什么特别之处,没有涉及的别名.

var bar = 1;
var foo = bar;
bar = "something entirely different";
// foo is still 1
Run Code Online (Sandbox Code Playgroud)


Mic*_*Mic 5

您将匿名函数的值分配给变量而不是指针.
如果要使用指针,可以使用通过引用传递的对象,而不是复制.

这里有些例子:

"obj2"是"obj1"的引用,您更改"obj2",并更改"obj1".它会警觉 false.

var obj1 = {prop:true},
    obj2 = obj1;
obj2.prop = false;
alert(obj1.prop);
Run Code Online (Sandbox Code Playgroud)

"prop"指向不是对象的属性,"prop"不是指向此对象的指针,而是指向副本.如果更改"prop",则"obj1"不会更改.它会警觉true

var obj1 = {prop:true},
    prop = obj1.prop;
prop = false;
alert(obj1.prop);
Run Code Online (Sandbox Code Playgroud)

"obj2"是对"obj1"的"subObj"属性的引用.如果"obj2"改变,则"obj1"改变.它会警觉false.

var obj1 = {subObj:{prop:true}},
    obj2 = obj1.subObj;
obj2.prop = false;
alert(obj1.subObj.prop);
Run Code Online (Sandbox Code Playgroud)