Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/418.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

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/spring-mvc/2.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 对象内部的函数不';I don’我不想通过引用进行更改_Javascript - Fatal编程技术网

Javascript 对象内部的函数不';I don’我不想通过引用进行更改

Javascript 对象内部的函数不';I don’我不想通过引用进行更改,javascript,Javascript,我有以下代码: let callback2 = () => console.warn('Old one'); let props2 = { callback2 } function test(props) { props.callback2 = () => console.warn('siema'); } test(props2); callback2(); 这里还有小提琴: 该代码的结果是“旧代码”而不是“siema”。 但函数不是原语,也不是对象,所

我有以下代码:

let callback2 = () => console.warn('Old one');

let props2 = {
    callback2
}

function test(props) {
    props.callback2 = () => console.warn('siema');

}

test(props2);

callback2();
这里还有小提琴:

该代码的结果是“旧代码”而不是“siema”。 但函数不是原语,也不是对象,所以我希望结果是“siema”

你知道我为什么收到“老家伙”的信息吗

=========已编辑:扩展示例===========

let callback2 = () => console.warn('Old one');

let moreTest = {
    moreTest: 'moreTest'
}

let props2 = {
    callback2,
    moreTestObject: moreTest
}

function test(props) {
    props.callback2 = () => console.warn('siema');
    props.moreTestObject.moreTest = 'Changed';

}

test(props2);

console.warn(moreTest)
callback2();
为什么我可以在这里更改对象?但不能改变功能吗

我得到:

{moreTest:“已更改”}

“老的”

预期:

{moreTest:“已更改”}

“锡马”

==========解决方案===========

let callback2 = () => console.warn('Old one');

let moreTest = {
    moreTest: 'moreTest'
}

let props2 = {
    callback2,
    moreTestObject: moreTest
}

function test(props) {
    props.callback2 = () => console.warn('siema');
    props.moreTestObject.moreTest = 'Changed';

}

test(props2);

console.warn(moreTest)
callback2();
我完全理解,我的困惑是因为我不知道对象{}总是知道如何找到它的道具。所以我也有

testObj = {
   inside: 'inside' // 0x123
}
当我调用test.Obj对象时,它知道它需要转到0x123。并将testObj更改为:

testObj.inside = 'outside' //0x125
使用它,testObj.inside和object知道如何转到0x125

因为对象必须以某种方式将信息保存在可以找到它的道具的地方


非常感谢。

如果您调用
props2.callback2()
它将输出
siema

你知道我为什么收到“老家伙”的信息吗

let{callback2}=props的可访问性内部
test()
仅限于初始化它的块,即
test
函数

在测试之外,它将保留

let callback2 = () => console.warn('Old one');
let{callback2}=props中删除
let
设置新的引用,该引用也保留在外部

function test(props) {
    callback2 = props.callback2;

    // callback2 = () => console.warn('siema');
    props.callback2 = () => console.warn('siema');
}
但是函数不是基本的

那没关系。您从未尝试修改函数

对象也不是基本体

首先,创建一个对象,并将原始的
callback2
函数指定给
callback2
属性

然后将
props2
(对该对象的引用)的值复制到函数参数

然后用新值覆盖该对象的
callback2
属性的值(调用
console.warn
的函数)

然后你打电话:

…但这是一个变量,仍然有一个引用原始函数的值。你永远不会改变这一点

为什么我可以在这里更改对象?但不能改变功能吗

x=y
更改左侧的内容

在这里:

左边是
props.moreTestObject
引用的对象的
moreTest
属性

在这里:

左边是
props
引用的对象的
callback2
属性

左边的东西不是函数

在您为其分配新值之前,其保留的值是对函数的引用,但这并不重要,因为您正在用新值覆盖该值


callback2
变量的值也是对该函数的引用(由
props.callback2
的旧值引用),但这并不重要,因为您没有更改
callback2
变量的值。

在函数内部执行的操作不会保留在函数外部。你需要归还道具

function test(props) {
  props.callback2 = () => console.warn('siema');
  return props
}

props2 = test(props2);

这是因为您不替换
callback2
变量,而是替换
props
对象的属性

// you create variable with 1 reference : exemple is our memory addr 0x123
let callback2 = () => console.warn('Old one');

// You copy this reference to another variable : props2 = 0x123 where 0x123 is reference from previous line.
let props2 = {
    callback2
}

function test(props) {
    let {callback2} = props;
    // You replace old reference by new one, this not impact callback2 variable, just remove 1 reference to callback2 and create new one.
    props.callback2 = () => console.warn('siema'); // Replace 0x123 reference by new one, exemple 0x456

}

test(props2);

callback2();
都是关于JavaScript中
垃圾收集器
计数引用

“Complexe type”作为
对象
数组
如果在执行操作时确实克隆了数据(myVar2=myVar1),则可能需要大量内存泄漏

为了防止这种情况,Javascript复制数据的引用(内存中的地址),而不是复制完整数据

在你的案件中,哪里可能令人困惑

行:
props.callback2=()=>console.warn('siema')不影响共享相同内存引用的其他变量。您在对应于此新匿名方法的控制台上用新的内存引用覆盖以前的内存引用
()=>console.warn('siema')

---更新1---

编辑2

根据你最近的更新,我认为除了做这样的事情没有其他选择。或者更优雅的第二个样本

//Change this to var as global variable.
var callback2 = () => console.warn('Old one');

let moreTest = {
    moreTest: 'moreTest'
}

let props2 = {
    callback2,
    moreTestObject: moreTest
}

function test(props) {
    // I see no choice than override both here.
    callback2 = props.callback2 = () => console.warn('siema');

}

test(props2);

console.warn(moreTest)
callback2();
更优雅:

let util = {
    foo : () => console.warn('Old one')
};
​
let second = {
    util
}
let third = {
    util
}
​
​
function test(props) {
     props.foo = () => console.warn('siema');
}
​
test(util);
util.foo(); // Output `siema`
second.util.foo(); // Output `siema`
third.util.foo(); // Output `siema`

props2.callback2()
将打印新消息。那么为什么在扩展示例修改对象中使用“props.moreTestObject.moreTest='Changed';”@PatrykJanik我更新了我的示例,因为您不重写引用,而是重写了影响原始1的引用的一个属性。我希望我的新样品会更清楚。如果没有,请告诉我。我仍然不知道原因:console.warn(moreTest)给了我“Changed”,callback给了我“Old one”更新的问题,我得到了我所期望的。我已经根据您所期望的更新了我的答案。好的解释,@Patryk Janik对另一个引用的更改的影响感到困惑。如果我将引用复制到另一个对象,然后修改该另一个对象,这会影响原始引用吗?answser不是,但我不确定我的解释是否清楚。
props.callback2 = () => console.warn('siema');
function test(props) {
  props.callback2 = () => console.warn('siema');
  return props
}

props2 = test(props2);
// you create variable with 1 reference : exemple is our memory addr 0x123
let callback2 = () => console.warn('Old one');

// You copy this reference to another variable : props2 = 0x123 where 0x123 is reference from previous line.
let props2 = {
    callback2
}

function test(props) {
    let {callback2} = props;
    // You replace old reference by new one, this not impact callback2 variable, just remove 1 reference to callback2 and create new one.
    props.callback2 = () => console.warn('siema'); // Replace 0x123 reference by new one, exemple 0x456

}

test(props2);

callback2();
let callback2 = () => console.warn('Old one');
// This create Ox123 reference in memory.
let moreTest = {
    moreTest: 'moreTest'
}

let props2 = {
    callback2,
    moreTestObject: moreTest // where ou copy Ox123 reference to moreTestObject property
}

function test(props) {
    props.callback2 = () => console.warn('siema');
    // where you edit Ox123 memory reference, is why  you impact both variable who have same reference.
    // props.moreTestObject.moreTest = 'Changed';
    // here you replace Ox123 memory reference by new one : 0x456. This will not impact moreTest original reference because you don't update Ox123 but replace by new entire reference in moreTestObject property
    props.moreTestObject = { moreTest: 'Changed'};

}

test(props2);

console.warn(moreTest)
callback2();
//Change this to var as global variable.
var callback2 = () => console.warn('Old one');

let moreTest = {
    moreTest: 'moreTest'
}

let props2 = {
    callback2,
    moreTestObject: moreTest
}

function test(props) {
    // I see no choice than override both here.
    callback2 = props.callback2 = () => console.warn('siema');

}

test(props2);

console.warn(moreTest)
callback2();
let util = {
    foo : () => console.warn('Old one')
};
​
let second = {
    util
}
let third = {
    util
}
​
​
function test(props) {
     props.foo = () => console.warn('siema');
}
​
test(util);
util.foo(); // Output `siema`
second.util.foo(); // Output `siema`
third.util.foo(); // Output `siema`