Javascript 解释这个未捕获的类型错误:Property';x';对象的属性[object object]不是函数

Javascript 解释这个未捕获的类型错误:Property';x';对象的属性[object object]不是函数,javascript,scope,Javascript,Scope,有人能解释一下为什么我在以下每种情况下都会得到这样的结果吗?我希望了解,如果问题是这样的话,为什么JavaScript如何与作用域协同工作的结果是这样的。在第一个示例中,我的代码正常工作 var Employees = function(name, salary) { this.name = name; this.salary = salary; this.addSalary = addSalaryFunction; this.getSalary = func

有人能解释一下为什么我在以下每种情况下都会得到这样的结果吗?我希望了解,如果问题是这样的话,为什么JavaScript如何与作用域协同工作的结果是这样的。在第一个示例中,我的代码正常工作

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());
如果我将
addSalary函数
移动到
Employees
函数中,并在
this.addSalary
下方,我会得到未捕获的TypeError

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());
但是如果我将
addSalary函数
移到
this.addSalary
上方,if将再次正常工作。虽然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());

这是因为您试图在创建函数之前分配它

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

//...

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

当您将变量赋值移到
this.addSalary=addSalaryFunction
上方时,您现在正在创建函数,然后再尝试引用它

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;
}

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

您可以删除一些代码,只需声明:

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

以更简单的形式:

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

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

显然,
bar()
将返回2<但是,code>foo在第一行查找值
y
时会获取
undefined
,因此返回
undefined
。虽然变量声明被提升到其作用域的顶部,但变量初始化却不是。

这是一个特定的提升问题。看看这个解释:

@chris\u s:不客气。最终,最干净的解决方案是使用rGil发布的内容。但在我看来,更好的方法是使用原型继承,将所有方法放在
Employees.prototype
上。然后,它们在所有Employee对象之间共享,而不是为每个对象重新创建。