【问题标题】:why does my variable seem to be updating?为什么我的变量似乎正在更新?
【发布时间】:2016-12-02 14:16:55
【问题描述】:
我目前正在学习 JavaScript,据我所知,还没有学到任何可以解释以下内容的东西:
<div id="parent">
<div>One</div>
<div>Two</div>
</div>
<script>
function test(node) {
var divs = node.children;
console.log(divs);
var div = document.createElement("div");
node.appendChild(div);
console.log(divs);
}
test(document.querySelector("#parent"));
</script>
我希望变量 divs 成为一个对象,其中包含运行该行代码时存在的 node 的子 div。它是什么,但是当将子节点添加到父节点时,它似乎会更新。什么解释了这种行为;我是否创建了对元素的引用,如果是,我该如何实现我想要的?
【问题讨论】:
标签:
javascript
html
variables
object
children
【解决方案1】:
在 JavaScript 中,每个对象都是通过引用而不是值传递的。节点的 .children 属性是一个对象(具体来说是 HTMLCollection 对象)。这意味着“divs”变量在运行时将不包含子项,它将引用 children 属性。当子节点更改并添加新节点时,访问 divs 变量将返回子节点的当前状态,因此它也将包含新子节点。如果您只想复制对初始子项的引用,您可以创建另一个变量。
function test(node) {
var children = node.children;
var divs = [];
// copy every child to the divs array
for (var i = 0; i < children.length; i++) {
divs.push(children[i]);
}
var div = document.createElement("div");
node.appendChild(div);
// since divs is just an array copy of the initial children,
// when children change, the divs still only contains the initial nodes
console.log(divs);
// however, as we said before, children will still be a reference to
// current node's children, so
console.log(children); // outputs 3 divs
}
test(document.querySelector("#parent"));
【解决方案2】:
divs 持有对选定节点的children 属性的引用。因此,如果您更改此children 属性,divs 的内容也会更改。
如果你想保持divs稳定,create a shallow copy of the array-like object children:
function test(node) {
var divs = Array.prototype.slice.call(node.children);
console.log(divs);
var div = document.createElement("div");
node.appendChild(div);
console.log(divs);
}
【解决方案3】:
你可以创建一个新数组
var divs = new Array(node.children.length);
for(var i = 0; i < node.children.length; i++){
divs[i] = node.children[i]
}
console.log(divs);
var div = document.createElement("div");
node.appendChild(div);
console.log(divs);
【解决方案4】:
您可以使用 querySelectorAll,它返回一个静态列表而不是 live。有关更多详细信息,您可以查看此链接。
https://www.w3.org/TR/selectors-api/#queryselectorall
<div id="parent">
<div>One</div>
<div>Two</div>
</div>
<script>
function test(node) {
var divs = document.querySelectorAll('#'+node.id +' div');
console.log(divs);
var div = document.createElement("div");
node.appendChild(div);
console.log(divs);
}
test(document.querySelector("#parent",'#parent div'));
</script>