为什么我的 __proto__ 参考在控制台中显示错误的名称?

Why my __proto__ reference shows wrong name in console?

我的 proto 对“mike”实例的引用指向“Student”,但正如其名称显示的那样,我不知道这是为什么。下面是我的代码和控制台截图:

const Person = function (firstName,birthYear) {
   this.firstName = firstName;
   this.birthYear = birthYear;
}

Person.prototype.calcAge = function () {
   console.log(2037 - this.birthYear);
}


const Student = function (firstName, birthYear, course){
   Person.call(this,firstName,birthYear);
   this.course = course;
};


Student.prototype = Object.create(Person.prototype)

Student.prototype.constructor = Student;

Student.prototype.introduce = function () {
   console.log(`My name is ${this.firstName} and ,I study ${this.course}`);
}

const mike = new Student('Mike',2020, 'Computer Science');

console.log(mike);

当我在控制台上查看时,它显示人员:

Student.prototype = Object.create(Person.prototype) 在这种情况下,您正在创建一个新对象并使其成为 Student.prototype 的值。新对象 Student 的原型是 Person.prototype

您在 Chrome 的控制台中首先看到的是 Student。那是你的 mike 对象的“类型”。

另一方面,mike__proto__ 属性 引用创建此实例的原型。您的代码已使用以下语句明确定义该原型:

Student.prototype = Object.create(Person.prototype);

因此,从那一刻起,Student.prototype instanceof Person 为真,Student.prototype instanceof Student 为假。所有使用 new Student 创建的实例都将在其 __proto__ 属性 中引用 Student.prototype。所以你看到的是预期的。

进行以下分配的事实不会改变此行为:

Student.prototype.constructor = Student;

这是一个表面上的变化,并不能确定 Student 创建的实例的性质。那可能误导了你。

class语法

您提供的代码执行设置原型链所需的步骤,其中 Student 继承自 Person

在现代 JavaScript 中实现这一点并不那么神秘。现在你会这样写这个例子:

class Person {
    constructor(firstName,birthYear) {
        this.firstName = firstName;
        this.birthYear = birthYear;
    }
    calcAge() {
        console.log(2037 - this.birthYear);
    }
}

class Student extends Person {
    constructor(firstName, birthYear, course) {
        super(birthYear, course);
        this.course = course;
    }
    introduce() {
         console.log(`My name is ${this.firstName} and ,I study ${this.course}`);
    }
}

const mike = new Student('Mike',2020, 'Computer Science');

console.log(mike);

控制台中的结果也会在这里确认Student实例的原型对象是Person(而不是Student)的实例。