MST

星途 面试题库

面试题:JavaScript构造函数与实例方法在原型链中的角色及性能差异

假设你有一个构造函数`Animal`,其原型上有一个实例方法`eat`。然后创建了`Dog`构造函数继承自`Animal`。阐述`Animal`的实例方法`eat`在`Dog`的实例中的查找路径以及这种原型继承机制对性能有什么潜在影响。如果在`Dog`的实例上直接修改`eat`方法,会对原型链产生什么影响?
25.6万 热度难度
编程语言JavaScript

知识考点

AI 面试

面试题答案

一键面试

Animal的实例方法eatDog的实例中的查找路径

  1. 当在Dog的实例上调用eat方法时,JavaScript 引擎首先会在该实例自身的属性中查找eat方法。由于Dog实例自身并没有直接定义eat方法,所以查找会失败。
  2. 接着,引擎会沿着原型链向上查找。因为Dog构造函数继承自AnimalDog的原型(Dog.prototype)是Animal的一个实例,所以会在Dog.prototype(也就是Animal的实例)中查找eat方法。由于eat方法定义在Animal的原型上,而Dog.prototypeAnimal的实例,所以在这里会找到eat方法并执行。

原型继承机制对性能的潜在影响

  1. 优点
    • 内存共享:多个实例可以共享原型上的方法和属性,节省内存空间。例如,所有Dog实例都可以共享Animal原型上的eat方法,而不需要在每个Dog实例中都创建一个eat方法的副本。
  2. 缺点
    • 查找时间:随着原型链的增长,查找属性和方法的时间会增加。因为每次查找都需要沿着原型链一级一级向上查找,直到找到目标属性或方法,或者到达原型链的顶端(Object.prototype)。如果原型链很长,查找效率会降低。

Dog的实例上直接修改eat方法对原型链的影响

当在Dog的实例上直接修改eat方法时,会在该实例自身创建一个新的eat方法,这个新的eat方法会屏蔽原型链上的eat方法。也就是说,以后在该实例上调用eat方法时,会直接调用实例自身新创建的eat方法,而不再查找原型链上的eat方法。但是,其他Dog实例不受影响,它们仍然会使用原型链上的eat方法,因为每个实例的自有属性是独立的。