Coercion __proto__ equality

I want the prototype of these instances to be the same, but the next equality check evaluates to false.

var emp1 = new(EmployeeScope())("John");
var emp2 = new(EmployeeScope())("Amit");
var mgr1 = new(ManagerScope())("Robert", "Data");
var mgr2 = new(ManagerScope())("Alex", "Science");
emp1.getName() // John
emp2.getName() // Amit
mgr1.getDept() // Data
mgr2.getDept() // Science
mgr1.getName() // Robert
mgr2.getName() // Alex

emp1.__proto__ === emp2.__proto__ //false
mgr1.__proto__ === mgr2.__proto__ //false

function EmployeeScope() {
  var name;

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

function ManagerScope() {
  var Employee = EmployeeScope();
  var dept;

  function Manager(newName, newDept) {
    new Employee(newName);
    dept = newDept;
  }
  Manager.prototype = Object.create(Employee.prototype);
  Manager.prototype.constructor = Manager;
  Manager.prototype.getDept = function() {
    return dept
  };
  Manager.prototype.setDept = function(newDept) {
    dept = newDept
  };
  return Manager;
}
+4
source share
2 answers

The reason that the two objects have different prototypes, is that the constructor function Employeeand Managerare again at each function call wrapper in which you put them. Thus, they represent different constructors when called in different wrapper calls.

A general solution that allows object methods to access private members is determined not by the prototype, but by the instances. This way you can define them in the constructor area:

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

function Manager(newName, newDept) {
    var dept = newDept;
    // Inherit from Employee
    Employee.call(this, newName);

    this.getDept = function() {
        return dept
    };
    this.setDept = function(newDept) {
        dept = newDept
    };
}

var emp1 = new Employee("John");
var emp2 = new Employee("Amit");
var mgr1 = new Manager("Robert", "Data");
var mgr2 = new Manager("Alex", "Science");

console.log(emp1.getName()) // John
console.log(emp2.getName()) // Amit
console.log(mgr1.getDept()) // Data
console.log(mgr2.getDept()) // Science
console.log(mgr1.getName()) // Robert
console.log(mgr2.getName()) // Alex

console.log(Object.getPrototypeOf(emp1) === Object.getPrototypeOf(emp2)); 
console.log(Object.getPrototypeOf(mgr1) === Object.getPrototypeOf(mgr2)); 
Run codeHide result

, Object.getPrototypeOf() __proto__.

-, var ( let, const), , .

+1

, , , :

var EmployeeA = EmployeeScope();
var EmployeeB = EmployeeScope();
EmployeeA === EmployeeB // false
EmployeeA.prototype === EmployeeB.prototype // false
var emp1 = new EmployeeA("John");
var emp2 = new EmployeeB("Amit");
Object.getPrototypeOf(emp1) === EmployeeA.prototype // true
Object.getPrototypeOf(emp2) === EmployeeB.prototype // true

EmployeeScope ( + ) , . , , name :

var emp3 = new EmployeeB("Dirk");
Object.getPrototypeOf(emp2) === Object.getPrototypeOf(emp3) // true
emp2.getName() // Dirk - oops

, Manager . "scope" :

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


function Manager(newName, newDept) {
  Employee.call(this, newName);
  this.dept = newDept;
}
Manager.prototype = Object.create(Employee.prototype);
Manager.prototype.constructor = Manager;
Manager.prototype.getDept = function() {
  return this.dept
};
Manager.prototype.setDept = function(newDept) {
  this.dept = newDept
};

var emp1 = new Employee("John");
var emp2 = new Employee("Amit");
var emp3 = new Employee("Dirk");
var mgr1 = new Manager("Robert", "Data");
var mgr2 = new Manager("Alex", "Science");
Object.getPrototypeOf(emp1) === Employee.prototype // true
Object.getPrototypeOf(emp2) === Employee.prototype // true
Object.getPrototypeOf(emp3) === Employee.prototype // true
Object.getPrototypeOf(mgr1) === Manager.prototype // true
Object.getPrototypeOf(mgr2) === Manager.prototype // true
+1

Source: https://habr.com/ru/post/1669623/


All Articles