Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/455.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript函数指针分配_Javascript_Function Pointers - Fatal编程技术网

Javascript函数指针分配

Javascript函数指针分配,javascript,function-pointers,Javascript,Function Pointers,考虑以下javascript代码: var bar = function () { alert("A"); } var foo = bar; bar = function () { alert("B"); }; foo(); 运行此代码时,我得到“A”。这种行为是javascript规范的一部分吗?我可以依赖它吗?是的,这是预期的,也是设计的结果 你的问题基本上是:foo引用bar是否像指针或引用在另一种语言中那样 答案是否定的:赋值时bar的值被赋值给foo这是将变量赋值给未命名函数,而不是

考虑以下javascript代码:

var bar = function () { alert("A"); }
var foo = bar;
bar = function () { alert("B"); };
foo();

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

是的,这是预期的,也是设计的结果

你的问题基本上是:
foo
引用
bar
是否像指针或引用在另一种语言中那样


答案是否定的:赋值时
bar
的值被赋值给
foo

这是将变量赋值给未命名函数,而不是函数的指针

是的,您已经创建了指向原始“a”函数的指针。当您重新分配bar时,您是在重新分配它,但仍然保留对旧函数的任何引用


所以要回答你的问题,是的,你可以信赖它

是的,变量引用函数这一事实没有什么特别之处,不涉及别名

var bar = 1;
var foo = bar;
bar = "something entirely different";
// foo is still 1

是的,这是正确的行为

//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();

这些不是函数指针(JS中也没有本地指针)。JS中的函数可以是匿名的,并且是第一类对象。因此

function () { alert("A"); }
创建一个匿名函数,在执行时向“A”发出警报

var bar = function () { alert("A"); };
将该功能分配给bar

var foo = bar;
将foo分配给bar,这是函数“A”

将工具栏重新绑定到匿名函数“B”。这不会影响foo或其他函数“A”

调用存储在foo中的函数,即函数“A”


实际上,在有函数点的语言中,例如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"

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

以下是一些例子:

“obj2”是“obj1”的参考,您更改“obj2”,而“obj1”更改。它将发出警报
false

var obj1 = {prop:true},
    obj2 = obj1;
obj2.prop = false;
alert(obj1.prop);
var obj1 = {subObj:{prop:true}},
    obj2 = obj1.subObj;
obj2.prop = false;
alert(obj1.subObj.prop);
“prop”指向一个不是对象的属性,“prop”不是指向该对象的指针,而是一个副本。如果更改“道具”,则不会更改“obj1”。它将发出警报
true

var obj1 = {prop:true},
    prop = obj1.prop;
prop = false;
alert(obj1.prop);
“obj2”是对“obj1”的“subObj”属性的引用。如果“obj2”更改,“obj1”更改。它将发出警报
false

var obj1 = {prop:true},
    obj2 = obj1;
obj2.prop = false;
alert(obj1.prop);
var obj1 = {subObj:{prop:true}},
    obj2 = obj1.subObj;
obj2.prop = false;
alert(obj1.subObj.prop);

我来晚了一点,但我想无论如何我会给出一个答案,并充实一些东西

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

所以

正在为环境记录“bar”赋值(匿名函数)

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

因为JavaScript是通过字符串而不是内存地址引用的,所以您可以这样做:

someObject["someProperty"]

它根据属性名查找值。

在其他示例中,值未传递任何内容;一切都是通过引用传递的

bar和foo都是指针

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
如果您认为它们是副本,那么您将遇到隐藏的错误和bug。尤其是处理复杂对象时。比如说

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
在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

我只想补充一点,这也适用于预定义的命名函数:

function myfunc() { alert("A"); }
var bar = myfunc;
var foo = bar;
bar = function () { alert("B"); };
foo();
这将做同样的事情,表明函数名的行为类似于数组名(指针)

对于代码中的每个函数声明f,按源代码文本顺序执行以下操作:

设fn为函数声明f中的标识符

设fo为第13条所述实例化函数声明f的结果

让funcalreadydecared成为调用env的HasBinding具体方法并将fn作为参数传递的结果

如果funcAlreadyDeclared为false,则调用env的CreateMutableBinding具体方法,将fn和configurableBindings作为参数传递

参考资料


谢谢。这些例子正是我在阅读这篇文章时想要的::-)当函数不是基元类型时,为什么要传递值的副本?为了澄清这个答案的最后一句话,请记住“bar的值”是“指向函数的指针”,而不是函数本身。因此,在
foo=bar
之后,foo接收到该指针的副本(按值),因此foo和bar都指向独立函数对象。感谢您澄清这一点,我对在线搜索“函数”感到困惑当我被告知它们不是时,它们是原始的。这个答案应该作为我们应该学习更多计算机科学和更少编程的证据……这个答案是完全错误的。我知道这已经很老了,但很明显,人们仍然在跌跌撞撞地走着。Javascript没有指针的概念。Javascript使用引用,这与指针明显不同。这是怎么回事?例如,C++中的不同之处在于,必须使用一个引用操作符来获得指针指向的对象,而引用不需要去引用。但是,在JS中(与Java一样),所有指针都对开发人员隐藏。没有明确的去引用。所以…我不明白为什么指针和引用会有什么不同。“UndertheHood”是一个值,它是指向内存中某个位置的值的查找。不管你称它为指针还是引用doe
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
function myfunc() { alert("A"); }
var bar = myfunc;
var foo = bar;
bar = function () { alert("B"); };
foo();