使用JavaScript,假设我有一个函数X,并在该函数中创建一个名为objectX的对象。函数X返回objectX。稍后在代码函数Z(somevar,anObject)中接收objectX作为其参数之一。
现在在函数Z中,objectX及其所有属性在函数Z?
中称为anObject如果函数Z返回anObject会发生什么?其余的代码是否会将对象视为“objectX”或“anObject”?
function X() {
...
objectX = {};
...
return objectX;
}
X();
function Z(anything, anObject) {
...
return anObject
}
Z(something, objectX);
答案 0 :(得分:4)
anObject
和objectX
都引用了内存中的相同空间,因此,根据需要命名,它始终是同一个对象。
答案 1 :(得分:4)
这主要是范围问题。
function X() {
// local objectX, only accessible through this name inside X()
var objectX = {};
objectX.foo = 'bar';
return objectX;
}
function Z(somevar, anObject) {
// anObject is passed in as a parameter
// it's only accessible through this name inside Z()
anObject.foo = somevar;
return anObject;
}
// get the 'objectX' from X() and store it in global variable a
var a = X();
// pass the received 'objectX' into Z()
// note that the variable names objectX and anObject cannot be accessed
// because they are local variables of the functions X() / Z()
var b = Z('baz', a);
// a is now the same as b, they both reference the same var
// a.foo and b.foo both are set to 'baz'
答案 2 :(得分:2)
我相信一个例子是最好的教学方式。这是一些代码(click here在JS Bin中看到它):
// Defines the variable to keep track of how many objects X() defines.
var num = 1;
// Instantiate another variable to see if it is changed by Z().
var anObject;
// Creates an object with a comment and a random number.
function X() {
// Create an object and give it a name.
var objectX = {comment : "Creation #" + num};
// Increase the value of num.
num++;
// Add another random number between 0 and 100 inclusively.
objectX.randNum = Math.round(Math.random() * 100);
// Return objectX.
return objectX;
}
// Modifies the second parameter by adding the value of the first parameter.
function Z(somevar, anObject) {
anObject.somevar = somevar;
return anObject;
}
var objectX = X(), objectY = X();
objectX2 = Z('coolness', objectX);
// Notice that objectX is still the result of calling X() the first time.
alert("objectX.comment = " + objectX.comment);
// Notice that objectX is not equal to objectY.
alert("objectX === objectY evaluates to " + (objectX === objectY));
// Notice that objectX2 is the same thing as objectX.
alert("objectX === objectX2 evaulates to " + (objectX === objectX2));
// Notice that anObject is not defined.
alert("typeof anObject evaluates to " + (typeof anObject) + " after Z is called.");
alert("Now review the JavaScript code.");
如果阅读评论,您将找到问题的答案。首先你会注意到在函数Z中,因为我传递了objectX作为第二个参数,在函数内部,它可以被anObject引用。其次你会注意到,一旦在函数Z之外,anObject不再引用objectX。这些评论还揭示了JavaScript中的其他事情。
答案 3 :(得分:1)
以下是jsfiddle
的链接让我们看下面的例子:
Person = function(name){
this.name = name;
}
function x(){
var john = new Person('john');
return john;
}
function z(tempVar, anObject){
var newObj = anObject;
newObj.name = tempVar;
return newObj;
}
myPerson = x();
console.log(myPerson.name); //john
console.log(z('peter', myPerson).name); //peter
console.log(myPerson.name); //peter
你可以看到,即使你在z中创建了一个新对象,但因为它们引用了同一个对象,所以在调用z()之后myPerson的name属性也会被更改。
答案 4 :(得分:1)
Javascript具有功能范围。这意味着在函数内声明的每个变量只能从该函数中访问。
如果您使用var
正确声明了objectX变量,则如下所示:
function X() {
...
var objectX = {};
...
return objectX;
}
然后objectX
只会在objectX
函数中被称为X
。在其他地方,它将被称为您分配给它的任何变量。由于在您的代码中,您没有将X()
的结果分配给任何内容,因此无法从任何地方访问objectX
。
然而,这是Javascript更严重的设计缺陷之一:如果不显式声明变量(使用var
语句或作为函数参数),该变量将自动成为全局变量。这意味着它可以随时随地访问。
因此,在上面的代码中,您可以按名称访问objectX
。
anObject
正确声明(作为参数),这意味着其范围将仅限于Z
函数。
简而言之,编写代码的方式objectX
可以通过objectX
变量随处访问,而在函数Z
中,您可以将其引用为{{ 1}}和objectX
。
为此,我建议您重构代码,例如igorw。