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)
cle*_*tus 38
是的,这是预期的和设计的.
你的问题基本上是:做foo
参考bar
在另一种语言的指针或引用会吗?
答案是否定的:在价值的bar
,在分配的时间分配给foo
.
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)
这是根据属性名称查找值.
是的,变量指的是函数没有什么特别之处,没有涉及的别名.
var bar = 1;
var foo = bar;
bar = "something entirely different";
// foo is still 1
Run Code Online (Sandbox Code Playgroud)
您将匿名函数的值分配给变量而不是指针.
如果要使用指针,可以使用通过引用传递的对象,而不是复制.
这里有些例子:
"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)