Uncaught TypeError: невозможно установить свойство getName из неопределенного (анонимная функция)

 <script>  
    var Employee = new function(name)
    {
     this.name=name;
    }
    Employee.prototype.getName = function()
    {
      return this.name;
    }

    var PermanenetEmployee = new function(annualsalary)
    {
    this.annualsalary=annualsalary;
    }
    var employee = new Employee("rahul");
    PermanenetEmployee.prototype = employee;
    var pe = new PermanenetEmployee(5001);
    document.write(pe.getName());



    </script> 

Я реализую наследование в java-скрипте. Из этого кода я хочу напечатать имя сотрудника, например «рахул». Но я получаю сообщение об ошибке, например, Uncaught TypeError: Невозможно установить свойство «getName» из неопределенного (анонимная функция). Как устранить эту ошибку?

Employee.prototype.getName = function()
        {
          return this.name;
        }

person Rahul    schedule 01.07.2016    source источник


Ответы (2)


Это проблема:

var Employee = new function(name)
// ------------^^^
{
 this.name=name;
}

(И то же самое для PermanenetEmployee.)

Вы не хотите new там. new вызывает функцию. Вы хотите сделать это позже, как при назначении employee.


Обратите внимание, что способ, которым вы настраиваете наследование между ними, является антишаблоном. Чтобы сделать PermanenetEmployee правильно "подклассом" Employee, сделайте следующее:

PermanenetEmployee.prototype = Object.create(Employee.prototype);
PermanenetEmployee.prototype.constructor = PermanenetEmployee;

нет

var employee = new Employee("rahul");
PermanenetEmployee.prototype = employee;

...а затем пусть PermanenetEmployee примет name и передаст его Employee:

var PermanenetEmployee = function(name, annualsalary) {
    Employee.all(this, name); // <====
    // ...
};

... или лучше использовать, используйте ES2015 ("ES6") class (транспиляция, если вам нужно, например, с помощью Babel).

Вот правильная установка. Я также исправил опечатку в PermanenetEmployee:

var Employee = function(name) {
    this.name = name;
};
Employee.prototype.getName = function() {
    return this.name;
};

var PermanentEmployee = function(name, annualSalary) {
    Employee.call(this, name);
    this.annualSalary = annualSalary;
};

// Set up subclass
PermanentEmployee.prototype = Object.create(Employee.prototype);
PermanentEmployee.prototype.constructor = PermanentEmployee.prototype;

PermanentEmployee.prototype.getAnnualSalary = function() {
    return this.annualSalary;
};

// Using
var pe = new PermanentEmployee("Rahul", 5001);
console.log(pe.getName());
console.log(pe.getAnnualSalary());

И с ES2015:

class Employee {
    constructor(name) {
        this.name = name;
    }
    getName() {
        return this.name;
    }
}

class PermanentEmployee extends Employee {
    constructor(name, annualSalary) {
        super(name);
        this.annualSalary = annualSalary;
    }

    getAnnualSalary() {
        return this.annualSalary;
    }
}

// Using
var pe = new PermanentEmployee("Rahul", 5001);
console.log(pe.getName());
console.log(pe.getAnnualSalary());

Опять же, обратите внимание, что вам нужно транспилировать, если вы хотите использовать этот синтаксис в дикой природе (пока).

person T.J. Crowder    schedule 01.07.2016

Есть несколько способов заставить наследование работать в JS, я использую этот шаблон.

Сначала объявите базовый прототип:

Employee = function () {
};
Employee.prototype = {
    getName: function () {}
};

И затем прототип, который наследует базу:

PermanentEmployee = function () {
    Employee.call(this);
};

PermanentEmployee.prototype = Object.create(Employee.prototype);
PermanentEmployee.constructor = PermanentEmployee;

PermanentEmployee.prototype.foo = function() {}
person ratchet    schedule 01.07.2016