JavaScript面试必备题目及解析

学习目标:

  1. 请解释一下JavaScript中的闭包是什么,并举一个例子来说明它的用途。

  2. 如何在JavaScript中实现继承?请提供至少两种不同的方法,并对它们进行比较和讨论。

  3. 请解释一下什么是事件冒泡和事件捕获,并说明它们之间的区别。


学习内容:

  1. JavaScript中的闭包是指函数可以访问其词法环境中定义的变量,即使函数在被定义的作用域之外被调用。闭包可以通过将内部函数返回或传递给其他函数来创建。

下面是一个闭包的示例:

javascript 复制代码
function outerFunction() {
  var outerVariable = 'I am from outer function';

  function innerFunction() {
    console.log(outerVariable);
  }

  return innerFunction;
}

var closure = outerFunction();
closure(); // 输出:I am from outer function

在这个例子中,innerFunction是一个闭包,它可以访问并输出outerVariable,尽管outerVariable是在outerFunction作用域内定义的。闭包能够保留对它们定义时的词法环境的引用。

闭包的用途之一是创建私有变量,因为外部函数的变量对外是不可访问的。另一个用途是在异步操作中保存状态。

  1. 在JavaScript中,我们可以使用原型链和构造函数来实现继承。

方法一:原型链继承

javascript 复制代码
function Parent() {
  this.parentProperty = 'I am from parent';
}

Parent.prototype.parentMethod = function() {
  console.log(this.parentProperty);
}

function Child() {
  this.childProperty = 'I am from child';
}

Child.prototype = Object.create(Parent.prototype);
Child.prototype.constructor = Child;

var child = new Child();
child.parentMethod(); // 输出:I am from child

在这个例子中,Child构造函数继承了Parent构造函数的属性和方法,通过将Child.prototype设置为Object.create(Parent.prototype)来实现原型链继承。这使得Child的实例可以访问Parent原型上定义的属性和方法。

方法二:构造函数继承

javascript 复制代码
function Parent() {
  this.parentProperty = 'I am from parent';
  this.parentMethod = function() {
    console.log(this.parentProperty);
  }
}

function Child() {
  Parent.call(this);
  this.childProperty = 'I am from child';
}

var child = new Child();
child.parentMethod(); // 输出:I am from parent

在这个例子中,Child构造函数使用Parent.call(this)Parent的属性和方法应用到Child实例上。这种方法实现了属性和方法的继承,但是无法继承Parent原型上的方法。

对比:

原型链继承适用于继承方法和属性,但可能会在修改子类原型时对父类产生影响。构造函数继承只能继承属性,但是不会对原型链造成影响。

  1. 事件冒泡和事件捕获是指处理DOM事件时,事件的传播方式。

事件冒泡是从内到外的传播方式,即事件首先在触发元素上被处理,然后向上冒泡到父元素,最终到达文档根节点。

html 复制代码
<div id="outer">
  <div id="inner">
    <button id="button">Click me</button>
  </div>
</div>

<script>
document.getElementById('button').addEventListener('click', function() {
  console.log('Button clicked');
}, false);
</script>

在这个例子中,当按钮被点击时,控制台将输出Button clicked。事件冒泡使得父元素也可以监听到子元素上的事件。

事件捕获是从外到内的传播方式,即事件首先在文档根节点被捕获,然后向下捕获到触发元素。

html 复制代码
<div id="outer">
  <div id="inner">
    <button id="button">Click me</button>
  </div>
</div>

<script>
document.getElementById('button').addEventListener('click', function() {
  console.log('Button clicked');
}, true);
</script>

在这个例子中,当按钮被点击时,控制台将先输出Button clicked,然后才是事件冒泡阶段。

区别:

事件冒泡和事件捕获是两种不同的事件传播方式。事件冒泡从内到外,而事件捕获从外到内。默认情况下,事件是按照事件冒泡方式传播的。你可以通过在addEventListener中将第三个参数设置为true来使用事件捕获方式。

相关推荐
swipe8 小时前
从 0 到 1 实现大文件上传:分片、秒传、断点续传、暂停、重试与服务端合并
前端·javascript·面试
阳火锅12 小时前
😭测试小姐姐终于不骂我了!这个提BUG神器太香了...
前端·javascript·面试
林希_Rachel_傻希希14 小时前
js里面的proxy理解。以及vue3响应式数据设计底层
前端·javascript·面试
用户15630681035118 小时前
Day01 | 什么是Agent?
面试
写代码的皮筏艇18 小时前
React中的forwardRef
前端·react.js·面试
蝎子莱莱爱打怪1 天前
XZLL-IM干货系列 03|消息 ID 设计:一个 UUID 搞不定的事,我用两个 ID 解决了
后端·面试·开源
梯度不陡2 天前
AI 到底能不能从零写软件?ProgramBench 和 RepoZero 给出了两种答案
前端·javascript·面试
胡萝卜术2 天前
滑动窗口最大值:从暴力到单调队列,层层优化全解析
前端·javascript·面试
沉默王二2 天前
面试结束后,我反问:“就面个实习至于上这么大强度吗?”面试官:“你对 RAG、Agent、MCP、Skill 理解得很到位,所以要求高一点。”
面试·agent·ai编程
假如让我当三天老蒯2 天前
Options API(选项式 API) 和 Composition API(组合式 API)
前端·vue.js·面试