2013-05-17 40 views
2

有人可以解释为什么我会在下列每种情况下得到结果吗?我希望理解为什么结果是关于JavaScript如何在范围内工作的结果,如果这是问题所在。在第一个例子中,我的代码正常工作。解释这个未捕获的类型错误:对象[对象对象]的属性'x'不是函数

var Employees = function(name, salary) { 
    this.name = name; 
    this.salary = salary; 

    this.addSalary = addSalaryFunction; 

    this.getSalary = function() { 
     return this.salary; 
    }; 

}; 

var addSalaryFunction = function(addition) { 
     this.salary = this.salary + addition; 
    }; 


var ceo = new Employees("Chris", 400000); 
ceo.addSalary(20000); 
document.write(ceo.getSalary()); 

如果我移动addSalaryFunctionEmployees功能,以下this.addSalary我得到的遗漏的类型错误。

var Employees = function(name, salary) { 
    this.name = name; 
    this.salary = salary; 

    this.addSalary = addSalaryFunction; 

    this.getSalary = function() { 
     return this.salary; 
    }; 

    var addSalaryFunction = function(addition) { 
     this.salary = this.salary + addition; 
    }; 
}; 

var ceo = new Employees("Chris", 400000); 
ceo.addSalary(20000); 
document.write(ceo.getSalary()); 

但是,如果我移动addSalaryFunction上述this.addSalary如果工作正常试。尽管我的IDE告诉我,我的本地变量addSalaryFunction是多余的。

var Employees = function(name, salary) { 
    this.name = name; 
    this.salary = salary; 

    var addSalaryFunction = function(addition) { 
     this.salary = this.salary + addition; 
    }; 

    this.addSalary = addSalaryFunction; 

    this.getSalary = function() { 
     return this.salary; 
    }; 

}; 


var ceo = new Employees("Chris", 400000); 
ceo.addSalary(20000); 
document.write(ceo.getSalary()); 

回答

7

这是因为您正在尝试在创建函数之前分配函数。

this.addSalary = addSalaryFunction; // there's no function yet 

//... 

var addSalaryFunction = function(addition) { // now there is, but too late 
    this.salary = this.salary + addition; 
}; 

当你移动的变量赋值的​​以上,现在你想引用它之前创造的功能。

var addSalaryFunction = function(addition) { // here's the function 
    this.salary = this.salary + addition; 
}; 
this.addSalary = addSalaryFunction; // now we can assign it 

如果你曾经使用函数声明的语法来代替,第一个版本会的工作,因为函数声明“悬挂” (他们说)的变量范围的顶部。

this.addSalary = addSalaryFunction; // This now works because of the magic below 

//... 

// This is magically hoisted to the top 
function addSalaryFunction(addition) { 
    this.salary = this.salary + addition; 
} 
+0

[很好的解释](http://javascriptweblog.wordpress.com/2010/07/06/function-declarations-vs-function-expressions/) – RobH

+0

为彻底性。 – rGil

+0

@chris_s:不客气。最终,最干净的解决方案是使用*** rGil ***发布的内容。但是,IMO更好的是通过将所有方法放在'Employees.prototype'上来使用原型继承。然后它们在所有Employee对象之间共享,而不是为每个对象重新创建。 – 2013-05-17 13:33:58

2

第二种方法不起作用,因为addSalaryFunction在声明之前被引用。

您可以消除一些代码,只是声明:

this.addSalary = function(addition) { 
    this.salary = this.salary + addition; 
} 
0

在一个更简单的形式:

var foo = function() { 
    var x = y; 
    var y = 2; 
    return x; 
}; 

var bar = function() { 
    var y = 2; 
    var x = y; 
    return x; 
}; 

显然,bar()将返回2. foo,然而,得到undefined在查找第一行的值为y,所以返回undefined。虽然变量声明被悬挂在其范围的顶部,但变量初始值没有。

相关问题