2011-02-08 114 views
1

使用JavaScript,假設我有一個函數X,並在該函數中創建了一個名爲objectX的對象。函數X返回objectX。後面的代碼函數Z(somevar,anObject)接收objectX作爲其參數之一。JavaScript對象作爲函數參數

現在在函數Z中,objectX及其所有屬性在函數Z中被稱爲anObject?

如果函數Z返回anObject會發生什麼?其餘的代碼會將對象看作「objectX」還是「anObject」?

function X() { 
    ... 
    objectX = {}; 
    ... 
    return objectX; 
} 

X(); 

function Z(anything, anObject) { 
    ... 
    return anObject 
} 

Z(something, objectX); 
+0

你真的需要解釋你在談論什麼更好。使用psudo代碼或其他東西。你描述的方式,函數X永遠不會被調用。 – Incognito 2011-02-08 15:34:43

+0

@ user257493 - 已添加代碼。 – Ben 2011-02-08 15:44:52

+0

該代碼無法運行。從來沒有調用過`X`函數:Javascript是區分大小寫的,所以`x()'與`X()`有些不同...... – Martijn 2011-02-08 16:01:22

回答

1

Javascript has function scope。這意味着在函數中聲明的每個變量只能從該函數內訪問。

如果你正確地聲明的目標x變量,var,如下所示:

function X() { 
    ... 
    var objectX = {}; 
    ... 
    return objectX; 
} 

然後objectX只會被稱爲objectXX函數內。在其他地方,它將被稱爲你分配給它的任何變量。由於在您的代碼中,您不會將X()的結果分配給任何內容,因此將無法從任何地方訪問objectX

然而,這裏的JavaScript的更嚴重的設計缺陷之一:如果你顯式聲明的變量(使用var聲明,或作爲函數參數),這個變量將自動成爲全球變量。這意味着它可以在任何地方

因此,在上面的代碼中,您可以通過該名稱隨處訪問objectX

anObject,在另一方面,是正確聲明(作爲參數),這意味着它的範圍將僅限於Z功能。

總之,你的代碼的編寫方式,objectX是訪問無處不在objectX變量的方式,並且功能Z裏面,你可以參考它同時作爲objectXanObject


待辦事項,但是,全局變量是一件壞事™,因爲他們可以把它非常難以找出變量被通過誰,什麼時候,爲什麼分配的 - 因爲你已經注意到了。
雖然JavaScript使得它不可能完全避免它們,但通常應儘量保持變量的範圍儘可能小(範圍=在程序中可以訪問該變量的位置)。

爲此,我建議重構您的代碼,如igorw

4

anObjectobjectX都被引用到相同的內存空間,所以,只要你想的名字,它總是相同的對象。

祝你好運!

+0

@ Gonzalo - 即使函數Z將對象作爲「anObject」返回,我仍然可以將其稱爲objectX? – Ben 2011-02-08 15:33:44

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' 
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中創建一個新的對象,而是因爲它們在引用到相同的對象myPerson的name屬性在z()被調用後也會改變。

2

我相信一個例子是最好的教學方式。下面是一些代碼(click here看到它在JS斌):

// 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中的其他事情。