Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/file/3.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 JS-理解闭包_Javascript_Function_Web_Reference_Closures - Fatal编程技术网

Javascript JS-理解闭包

Javascript JS-理解闭包,javascript,function,web,reference,closures,Javascript,Function,Web,Reference,Closures,我正在寻找一种动态更改函数返回值的方法。在下面的示例中,getObjRef函数返回立即调用函数的结果,该函数是对对象的引用。然后,在一秒钟后,它会更改对象的值,但是最初返回的引用不会更改 问:我能让它工作吗 function getObjRef() { var o = {val: 1}; return(function (obj) { setTimeout(function () { //trying to change the refer

我正在寻找一种动态更改函数返回值的方法。在下面的示例中,
getObjRef
函数返回立即调用函数的结果,该函数是对对象的引用。然后,在一秒钟后,它会更改对象的值,但是最初返回的引用不会更改

问:我能让它工作吗

function getObjRef() {
    var o = {val: 1};
    return(function (obj) {
        setTimeout(function () {
            //trying to change the referance after 1 sec
            obj = {val: 10};
            console.log("obj ->", obj);
            console.log("o ->", o);
        }, 1000);
        return obj;
    })(o)
}

var objRef = getObjRef();
console.log("objRef initial value->", objRef);
setTimeout(function () {
    console.log("objRef after 2 sec->", objRef)
}, 2000);
(查看日志)

现在可以工作了:

更改
obj={val:10}
obj.val=10

说明:
您必须更改被引用对象(指针指向的对象)的值,而不是将新对象指定给局部变量“obj”,这只是将局部变量设置为新值(但您希望更改原始对象的“val”属性)。

如果您更改此行,则可以执行此操作

obj = {val: 10};
为此:

obj.val = 10;
说明:

运行时,返回对象时带有
{val:1}
setTimeout()
导致的关闭保留了指向该对象的指针

但是,当执行回调时,在回调范围内,您可以将对原始对象的引用替换为对新对象的新引用。此时您实际上有两个对象:一个在外部范围(
{val:1}
)中,另一个在回调范围(
{val:10}
)。因此,当您稍后将对象记录到外部范围时,似乎什么也没有发生


要解决这个问题,您必须维护对外部作用域对象的引用,并按照上面的代码更改其值。

有没有办法替换整个对象。。。比如从{val:1}到{newKey:“hi”}@ShlomiSchwartz-AFAIK,你不能。基本上是因为您无法获得第一个对象的所有引用的列表,您需要将其更改为替换对象。但是,您可以修改旧对象使其看起来像新对象:
delete obj.val;obj.newKey='hi'console.log中(“o->”,o)
您承认最里面的函数可以访问
o
,那么为什么还要麻烦使用中间的、自动执行的函数来捕获对
o
的引用呢?