解释这个Uncaught TypeError:对象[object Object]的属性'x'不是函数

chr*_*s_s 2 javascript scope

有人可以解释为什么我会在以下每种情况下得到我的结果吗?我希望了解为什么结果是关于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());
Run Code Online (Sandbox Code Playgroud)

如果我移动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());
Run Code Online (Sandbox Code Playgroud)

但如果我移动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());
Run Code Online (Sandbox Code Playgroud)

小智 7

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

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

//...

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

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

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

如果您使用了函数声明语法,那么第一个版本将起作用,因为函数声明被"提升" (如他们所说)到变量范围的顶部.

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;
}
Run Code Online (Sandbox Code Playgroud)