MST

星途 面试题库

面试题:JavaScript 子类在原型链与闭包结合场景下的行为分析

有如下代码: ```javascript function Parent() { let privateVar = 10; this.getPrivateVar = function() { return privateVar; } } function Child() { Parent.call(this); } Child.prototype = Object.create(Parent.prototype); Child.prototype.constructor = Child; function outerFunction() { let closureVar = 20; return function innerFunction(childInstance) { console.log(childInstance.getPrivateVar()); console.log(closureVar); } } ``` 1. 分析 `Child` 类的原型链结构;2. 当执行 `let child = new Child(); let func = outerFunction(); func(child);` 时,解释每一步发生了什么,包括 `getPrivateVar` 方法如何访问 `privateVar`,以及 `innerFunction` 如何访问 `closureVar`。
49.2万 热度难度
编程语言JavaScript

知识考点

AI 面试

面试题答案

一键面试

1. Child 类的原型链结构分析

  • Child.prototype 是通过 Object.create(Parent.prototype) 创建的。这意味着 Child.prototype__proto__ 指向 Parent.prototype
  • Child.prototype.constructor 被重新赋值为 Child,以正确指向构造函数。
  • 当创建 Child 的实例 child 时,child.__proto__ 指向 Child.prototype,而 Child.prototype.__proto__ 指向 Parent.prototypeParent.prototype.__proto__ 指向 Object.prototype,最终 Object.prototype.__proto__null
  • 所以原型链结构为:child -> Child.prototype -> Parent.prototype -> Object.prototype -> null

2. 执行 let child = new Child(); let func = outerFunction(); func(child); 每一步解释

  • let child = new Child();
    • new Child() 首先创建一个空对象。
    • 然后 Parent.call(this) 在这个新创建的对象上下文中调用 Parent 构造函数。在 Parent 构造函数中,privateVar 作为局部变量被声明并赋值为 10,同时给新对象添加了 getPrivateVar 方法。这个方法可以访问 Parent 函数作用域内的 privateVar,因为函数闭包的特性,即使 Parent 函数执行完毕,privateVar 依然存在于内存中,并且可以被 getPrivateVar 访问。
    • 最后,新创建的对象(即 child)的 __proto__ 指向 Child.prototype,完成 Child 实例的创建。
  • let func = outerFunction();
    • outerFunction 被调用,声明了局部变量 closureVar 并赋值为 20
    • 然后返回 innerFunctioninnerFunction 形成了一个闭包,它可以访问 outerFunction 作用域内的 closureVar。即使 outerFunction 执行完毕,closureVar 依然存在于内存中,因为 innerFunction 对它的引用。
  • func(child);
    • funcinnerFunction,当调用 func(child) 时,innerFunction 中的 console.log(childInstance.getPrivateVar()); 执行。这里 childInstance 就是 childchild.getPrivateVar() 方法被调用,由于闭包,它可以访问到 Parent 函数作用域内的 privateVar,并返回 10 打印出来。
    • 接着 console.log(closureVar); 执行,由于闭包,innerFunction 可以访问到 outerFunction 作用域内的 closureVar,并打印出 20