MST

星途 面试题库

面试题:JavaScript类与原型链的深入理解

假设有如下代码: ```javascript function Person(name) { this.name = name; } Person.prototype.sayHello = function() { console.log('Hello, I'm'+ this.name); }; function Student(name, grade) { Person.call(this, name); this.grade = grade; } Student.prototype = Object.create(Person.prototype); Student.prototype.constructor = Student; Student.prototype.sayGrade = function() { console.log('My grade is'+ this.grade); }; ``` 1. 请解释上述代码中`Object.create(Person.prototype)`和`Student.prototype.constructor = Student`这两行代码的作用。 2. 如果创建一个`Student`实例`s = new Student('John', 10)`,当调用`s.sayHello()`时,JavaScript引擎是如何通过原型链找到该方法的?
17.2万 热度难度
编程语言JavaScript

知识考点

AI 面试

面试题答案

一键面试

1. 代码作用解释

  • Object.create(Person.prototype)
    • 这行代码创建了一个新的对象,这个新对象的原型被设置为Person.prototype。这使得Student实例能够继承Person原型对象上定义的属性和方法。通过这种方式,Student实现了对Person的原型继承,例如sayHello方法。这样做避免了直接使用Student.prototype = Person.prototype,因为如果直接赋值,会导致StudentPerson的原型对象完全共享,修改一方会影响另一方。使用Object.create创建一个新对象作为Student的原型,使得Student有自己独立的原型对象,同时又能继承Person原型的属性和方法。
  • Student.prototype.constructor = Student
    • 当使用Object.create(Person.prototype)创建Student.prototype时,新的原型对象的constructor属性指向的是Person(因为它继承自Person.prototype)。而我们希望Student实例的constructor属性指向Student自身,这样通过instanceof操作符以及其他需要判断构造函数的场景下能得到正确的结果。例如,如果没有这行代码,s instanceof Student虽然会返回true,但Student.prototype.constructor指向的却是Person,这可能会引起混淆。通过手动设置Student.prototype.constructor = Student,确保了Student实例的constructor属性正确指向Student

2. sayHello方法查找过程

  1. 当调用s.sayHello()时,JavaScript引擎首先在Student实例s自身的属性中查找sayHello方法。由于Student构造函数中没有直接定义sayHello方法,所以在实例上找不到。
  2. 然后,JavaScript引擎会沿着原型链向上查找。Student实例的原型是通过Object.create(Person.prototype)创建的,所以它的原型对象(Student.prototype)上也没有sayHello方法。
  3. 接着,继续沿着原型链向上,Student.prototype的原型是Person.prototype,在Person.prototype中找到了sayHello方法,于是JavaScript引擎调用该方法,并将this绑定到Student实例s上,最终输出Hello, I'm John