当我希望返回对象中的成员具有父作用域中定义的变量的正确值时,我遇到了一个问题。但是,此成员的值永远不会更改,我必须使用getter方法来检索正确的值。对于一个简单的例子,下面是图的Adjacency Matrix表示的子集:
function AdjacencyMatrix() {
// Here is the set of Vertices
var V = [1, 2, 3];
// Here's some functionality that will remove a vertex at some point,
// right now we're just concerned with updating what V is equal to
function removeVertex(v) {
V.push(4);
V = [];
console.log(V);
}
// A "getter" method for the list of vertices
function getVertices() {
return V;
}
// Ran when the Adjacency Matrix is initialized
console.log(V);
return Object.freeze({
// Member that holds a reference to V
vertices: V,
// Methods that will be used later
removeVertex: removeVertex,
getVertices: getVertices
});
}
// Initially logs [1, 2, 3], which is expected
var M = AdjacencyMatrix();
// Logs [], which is expected
M.removeVertex();
// Logs [1, 2, 3, 4], which is unexpected.
// Instead, it should log []
console.log(M.vertices);
// Logs [], which is expected
console.log(M.getVertices());
返回对象中的vertices
成员是否应始终保持对变量V
指向的引用?相反,在此示例中,访问vertices
上的M
成员会维护对最初分配给变量V
的数组的引用,并忽略变量V
的任何重新分配。
或者,在将vertices
成员分配给V
时,它是否包含对V
的值的引用,而不是该变量的值是什么?
很抱歉,如果难以理解这个问题的措辞,我会尽力说出我的期望和结果。
答案 0 :(得分:2)
vertices: V,
表示:
引用V
引用vertices
属性的内容。
就是这样 - 它不是一个闭包,它只是一个任务。
因此,只要您重新指定V
以引用其他内容,vertices
属性就不会反映出来,因为它会存储原始引用。
答案 1 :(得分:1)
M.vertices
不涉及关闭。
在对象文字中,每个键/值对的右侧都是评估,并且该评估的结果是分配给每个对象属性的结果。
执行此操作时:
return Object.freeze({
// Member that holds a reference to V
vertices: V,
// Methods that will be used later
removeVertex: removeVertex,
getVertices: getVertices
});
V
将被评估为V
此时引用的数组。因此,生成的对象引用该数组,但它与V
无关。
<小时/> 获取您描述的行为(如果这是您确实想要的)。您可以为使用闭包的
vertices
定义一个getter和setter:
var o = {
// Methods that will be used later
removeVertex: removeVertex,
getVertices: getVertices
}
Object.defineProperty(o, 'vertices', {
get: function () { return V; },
set: function (val) { V = val; } // or you can omit the setter
// to make the property readonly
});
return Object.freeze(o);
答案 2 :(得分:0)
顶点保存最初分配给它的V值。如果你来自像C#这样的面向对象语言背景,这相当于&#34;传递值&#34; (即只传递值而不是参考)。