Javascript 函数指针赋值
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/2326072/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Javascript Function-Pointer Assignment
提问by niaher
Consider this javascript code:
考虑这个javascript代码:
var bar = function () { alert("A"); }
var foo = bar;
bar = function () { alert("B"); };
foo();
When running this code I get "A". Is this behavior a part of javascript specification and can I rely on it?
运行此代码时,我得到“A”。这种行为是 javascript 规范的一部分,我可以依赖它吗?
采纳答案by cletus
Yes that is expected and by design.
是的,这是预期的和设计的。
Your question is basically: does fooreference baras a pointer or reference would in another language?
您的问题基本上是:在另一种语言中是否将foo引用bar作为指针或引用?
The answer is no: the valueof barat the time of assignment is assigned to foo.
答案是否定的:在价值的bar,在分配的时间分配给foo。
回答by siingCoder
In other examples, nothing was passed by value; everything was passed by reference.
在其他示例中,没有按值传递;一切都是通过引用传递的。
bar and foo are BOTH pointers
bar 和 foo 都是指针
All vars/handles to NON primitive objects in javascript are pointers; pointers ARE native to javascript, they are the default.
javascript 中所有非原始对象的变量/句柄都是指针;指针是 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
You will run into hidden errors and bugs if you think they are copies. Especially so if you work with complex objects. For example
如果您认为它们是副本,则会遇到隐藏的错误和错误。如果您使用复杂的对象,尤其如此。例如
function person(name){this.name = name}
var john = new person("john")
var backup = john
backup.name //john
john.name = "Hyman"
backup.name //Hyman, NOT john
To really COPY a non-primitive in javascript takes more work than just a = b. For example:
要真正在 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 = "Hyman"
backup.name //john
回答by Bob
I'm a bit late here but I thought I'd give an answer anyways and flesh something out.
我在这里有点晚了,但我想无论如何我都会给出答案并充实一些东西。
It's best not to think in terms of pointers and memory references when discussing the internals of JavaScript (or ECMAScript) when dealing with the specifications. Variables are environment records internally and are stored and referenced by name, not memory address. What your assignment statement is doing, internally and by design, is looking up the environment record name (either "foo" or "bar") and assigning the value to that record.
在处理规范时讨论 JavaScript(或 ECMAScript)的内部结构时,最好不要考虑指针和内存引用。变量是内部环境记录,按名称存储和引用,而不是内存地址。您的赋值语句在内部和设计上所做的是查找环境记录名称(“foo”或“bar”)并将值分配给该记录。
So,
所以,
var bar = function () { alert("A"); }
is assigning the environment record "bar" the value (anonymous function).
正在为环境记录“bar”分配值(匿名函数)。
var foo = bar;
internally calls GetValue("bar") which retrieves the value associated with the record "bar" and then associates that value with the record "foo". Hence, afterwards the original value of bar can still be used as it's now associated with foo.
内部调用 GetValue("bar"),它检索与记录“bar”相关联的值,然后将该值与记录“foo”相关联。因此,之后仍然可以使用 bar 的原始值,因为它现在与 foo 相关联。
Because JavaScript references by string and not memory address is precisely why you can do things like this:
因为 JavaScript 通过字符串而不是内存地址引用正是您可以执行以下操作的原因:
someObject["someProperty"]
which is looking up the value based on the property name.
这是根据属性名称查找值。
回答by Mic
You are assigning the value of an anonymous function to a variable not a pointer.
If you want to play with pointers, you can use objects that are passed by reference, not copy.
您将匿名函数的值分配给变量而不是指针。
如果你想玩指针,你可以使用通过引用传递的对象,而不是复制。
Here are some examples:
这里有些例子:
"obj2" is a reference of "obj1", you change "obj2", and "obj1" is changed. It will alert false.
“obj2”是“obj1”的引用,你改变“obj2”,“obj1”就改变了。它会发出警报 false。
var obj1 = {prop:true},
obj2 = obj1;
obj2.prop = false;
alert(obj1.prop);
"prop" points to a property that is not an object, "prop" is not a pointer to this object but a copy. If you change "prop", "obj1" is not changed. It will alert true
“prop”指向一个不是对象的属性,“prop”不是指向这个对象的指针而是一个副本。如果更改“prop”,则“obj1”不会更改。它会提醒true
var obj1 = {prop:true},
prop = obj1.prop;
prop = false;
alert(obj1.prop);
"obj2" is a reference to the "subObj" property of "obj1". if "obj2" is changed, "obj1" is changed. It will alert false.
“obj2”是对“obj1”的“subObj”属性的引用。如果“obj2”改变,“obj1”也改变。它会发出警报false。
var obj1 = {subObj:{prop:true}},
obj2 = obj1.subObj;
obj2.prop = false;
alert(obj1.subObj.prop);
回答by polygenelubricants
Yes, there's nothing special about the fact that the variables are referring to functions, there's no aliasing involved.
是的,变量引用函数这一事实没有什么特别之处,不涉及别名。
var bar = 1;
var foo = bar;
bar = "something entirely different";
// foo is still 1
回答by Amarghosh
Yes, this is the correct behavior.
是的,这是正确的行为。
//create variable bar and assign a function to it
var bar = function () { alert("A"); }
//assign value of bar to the newly created variable foo
var foo = bar;
//assign a new function to the variable bar
//since foo and bar are not pointers, value of foo doesn't change
bar = function () { alert("B"); };
//call the function stored in foo
foo();
回答by kennytm
Those are not function pointers (and there are no pointers in JS natively). Functions in JS can be anonymous and are first class objects. Hence
这些不是函数指针(JS 本身没有指针)。JS 中的函数可以是匿名的,并且是一等对象。因此
function () { alert("A"); }
creates an anonymous function that alerts "A" on execution;
创建一个匿名函数,在执行时提醒“A”;
var bar = function () { alert("A"); };
assign that function to bar;
将该功能分配给 bar;
var foo = bar;
assign foo to bar, which is the function "A".
将 foo 分配给 bar,即函数“A”。
bar = function () { alert("B"); };
rebind bar to an anonymous function "B". This won't affect foo or the other function "A".
将 bar 重新绑定到匿名函数“B”。这不会影响 foo 或其他函数“A”。
foo();
Call the function stored in foo, which is the function "A".
调用foo中存储的函数,即函数“A”。
Actually in languages where there are function points e.g. C it won't affect fooeither. I don't know where you get the idea of getting "B" on reassignment.
实际上在有功能点的语言中,例如 C,它也不会影响foo。我不知道你从哪里得到重新分配“B”的想法。
void A(void) { printf("A\n"); }
void B(void) { printf("B\n"); }
typedef void(*fptr_t)(void);
fptr_t foo = A;
fptr_t bar = foo;
bar = B;
foo(); // should print "A"
回答by Svetlozar Angelov
This is assigning a variable to an unnamed function, not a pointer to a function
这是将变量分配给未命名的函数,而不是指向函数的指针
回答by David Morton
Yes, you've created a pointer to the original "A" function. When you reassign bar, you're reassigningit, but you're still leaving any references to the old function alone.
是的,您已经创建了一个指向原始“A”函数的指针。当您重新分配 bar 时,您正在重新分配它,但您仍然保留对旧函数的任何引用。
So to answer your question, yes, you can rely on it.
所以要回答你的问题,是的,你可以依靠它。
回答by user3015682
I would just like to add this also works for pre-defined named functions as well:
我只想添加这也适用于预定义的命名函数:
function myfunc() { alert("A"); }
var bar = myfunc;
var foo = bar;
bar = function () { alert("B"); };
foo();
This will do the same thing, indicating that function names act like array names (pointers).
这将做同样的事情,表明函数名称的作用类似于数组名称(指针)。

