2014-01-13 93 views
0

我這裏有一些代碼Javascript問題。變量設置功能內,但功能外它不是

var F; 
var favv= ['E','I','A','O','U']; 
var i = 0; 

function vowelcount(arg, favv) 
{ 
    for(i=0;i<favv.length;i++) { 
    c = 0; 
    V = favv[i]; 
    for (j=0;j<arg.length;j++) { 
     if (arg[j].toUpperCase()===V) { 
     c++; 
     };  
    } 
    if (c>0) { 
     F=V; 
     return c; 
    } 
    } 
} 

var person1 = {name:"Super",spd:20}; 
var person2 = {name:"Supeer",spd:20}; 

function Scheck(person1, person2) { 

    if (person2.spd>person1.spd) { 

    var sub=person1; 
    person1=person2; 
    person2=sub; 

    } else if (person2.spd===person1.spd) { 

    var ct1 = vowelcount(person1.name, favv); 
    var ct2 = vowelcount(person2.name,F); 

    if (ct2 > ct1) { 
     var subp = person1; 
     person1= person2; 
     person2=subp; 
    } 
    } 
    console.log(person1); 
    console.log(person2); 
} 

Scheck(person1,person2); 

console.log(person1); 
console.log(person2); 

這裏我有元音,兩個人的屬性名稱和社民黨組成的數組。當我運行Scheck時,我想使用vowelcount來確定人們在速度統計相等的情況下會移動的順序。如果您查看函數內的console.logs,它們會輸出正確的名稱......但是在函數後面,console.logs將顯示原始順序。爲什麼是這樣?

+0

JavaScript是按值傳遞的語言。 – Pointy

+0

因爲引用。 –

+0

可能的重複:http://stackoverflow.com/questions/500431/javascript-variable-scope – ernie

回答

2
var subp = person1; 
person1= person2; 
person2=subp; 

這輪交換兩個參數person1person2的價值觀,但他們是本地的功能,因此它不會影響到函數外部的變量。

上面的代碼中的一個簡單的解決方案是使用閉包。不要將變量傳入或接收它們!

function Scheck() { 

... 

Scheck(); 

現在的謝克函數內部,因爲沒有所謂的person1person2局部變量或參數,它將使用變量從外部範圍。然後,交換將按照計劃進行。


另一種選擇是將對象或數組傳遞給Scheck函數。這個函數將能夠改變對象的屬性,並且這些改變將被反映到外面,因爲正在引用相同的對象。您可以使用數組,但以下是帶對象的示例:

function Scheck(people) { 

    var person1 = people.first; // or people[0] if you used an array 
    var person2 = people.second; // or people[1] if you used an array 

    ... 

      if(ct2>ct1) 
       { 

        people.first = person2; // Set people[0] for an array 
        people.second = person1; 

       } 

... 

var people = { 
    first: person1, 
    second: person2 
}; 
Scheck(); 
person1 = people.first; 
person2 = people.second; 

// or for an array: 
var people = [person1, person2]; 
Scheck(people); 
person1 = people[0]; 
person2 = people[1]; 
+0

我真的結束了你的第一個選擇。我只是沒有傳遞任何參數。很高興今天學習一些東西。 –

2

您正在分配函數的參數(創建局部變量),而不是全局變量。

如果你想改變全局狀態,你根本不應該有這些參數。

4

您有範圍問題。你在全局範圍聲明person1和person2,但是將它們作爲你的函數參數,這是sl。不馴的。

爲您的函數中的參數命名不同,然後maek Scheck實際返回person1和person2的值。

你可以讓謝克這樣的:

function Scheck(p1, p2) 
{ 
    // ... do things 

    return [p1, p2];   
} 

再收到這樣的:

var persons = Scheck(person1, person2); 
person1 = persons[0]; 
person2 = persons[1]; 
+0

我想我實際上已經發現了它,但我同意這一點。這對我來說有點草率。因爲我已經聲明瞭person1,person2,至少在這種情況下,我並不需要使用它們作爲參數,至少這是我的理解。 –

+0

是的,確切地說。你不應該以這種方式調用函數。 – dthree

1

在你舍克,使用F作爲第二個參數。 F已被聲明,但沒有給出值,所以它失敗,因爲num> undefined是錯誤的,沒有任何變化。

+0

實際上,我沒有注意到F自己有任何問題,因爲我只需要在此刻運行兩次該函數。 –

+0

我剛剛注意到,在vowelcheck中,它將F設置爲元音,所以它變成了一個具有length屬性的字符串,所以它運行良好,因爲它在用F運行之前先用favv運行它。 – robotmayo

+0

看起來很棒。既然它只在本地使用,'F'應該在該函數的頂部聲明'var F',而不是在文件的頂部!並且給它一個名字......;) – joeytwiddle