2014-01-13 65 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