📜  JavaScript面试问题(1)

📅  最后修改于: 2023-12-03 14:42:42.083000             🧑  作者: Mango

JavaScript面试问题

如果你正在准备JavaScript面试,以下是一些常见的JavaScript面试问题,以及对每个问题的解释和示例代码。

1. 什么是闭包?

闭包是指函数可以访问定义在父函数内部作用域中的变量。闭包最常用的应用场景是在实现参数化API时进行数据隐藏。

以下是一个闭包示例:

function outerFunction() {
  var outerValue = 'hi';

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

  return innerFunction;
}

var innerFunc = outerFunction();
innerFunc(); // 输出 'hi'

在这个示例中,innerFunction 访问了定义在 outerFunction 中的 outerValue 变量。由于 innerFunction 被外部的变量所引用,因此 outerValue 不会被垃圾回收机制清除。

2. 什么是原型继承?

JavaScript不支持类继承,而是通过原型继承来实现对象之间的继承。每个对象都有一个指向其原型的指针,它会从其原型继承属性。

以下是一个原型继承示例:

function Person(name) {
  this.name = name;
}

Person.prototype.sayHello = function() {
  console.log('Hello, my name is ' + 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);
}

var student = new Student('Alice', 10);
student.sayHello(); // 输出 'Hello, my name is Alice'
student.sayGrade(); // 输出 'My grade is 10'

在这个示例中,Student 对象从 Person 对象继承 sayHello 方法,并且通过原型链从其父类继承 Object 对象中的其他属性和方法。通过使用 Object.create 方法,Student.prototype 对象成为了 Person.prototype 的一个实例。这意味着任何属性或方法的查询都沿着原型链向上进行,直到匹配到适当的属性或方法。

3. 什么是事件委托?

事件委托是指将事件处理程序附加到由其子元素组成的父级元素上,而不是附加到每个子元素上。这样可以在DOM结构被更改时仍然继续工作,并且可以提高性能,因为只需处理一个事件处理程序。

以下是一个事件委托示例:

// HTML元素
<ul id="list">
  <li>Item 1</li>
  <li>Item 2</li>
  <li>Item 3</li>
</ul>

// JavaScript代码
var list = document.getElementById('list');
list.addEventListener('click', function(event) {
  if (event.target.tagName === 'LI') {
    console.log(event.target.innerHTML);
  }
});

在这个示例中,click 事件处理程序被添加到 ul 元素上。当单击某个 li 元素时,事件会冒泡到 ul 元素,并且事件处理程序会检查 event.target 是不是 li 元素,以便执行适当的操作。

4. 什么是Promises?

Promises是一种处理异步JavaScript编程的方式,可避免回调函数的“回调地狱”。Promise有三个状态: pending (进行中)、 fulfilled (已完成)、 rejected (已拒绝)。

以下是一个Promise示例:

function getData() {
  return new Promise(function(resolve, reject) {
    setTimeout(function() {
      var data = { name: 'Alice', age: 30 };
      resolve(data);
    }, 1000);
  });
}

getData().then(function(data) {
  console.log(data);
}).catch(function(error) {
  console.error(error);
});

在这个示例中,getData 返回一个Promise,该Promise在1000毫秒后解析为包含数据的对象。 then 方法用于处理已解决的承诺,而 catch 方法用于处理已拒绝的承诺。

5. 什么是模块?

模块是将程序分解为可重用部分的一种方式。在JavaScript中,通常使用CommonJS或ES6模块来实现模块。模块可包含变量、函数和类,这些都被封装在模块的作用域中,以便于共享和重复利用。

以下是一个CommonJS模块示例:

// math.js
function add(a, b) {
  return a + b;
}

function subtract(a, b) {
  return a - b;
}

module.exports = {
  add: add,
  subtract: subtract
};

// main.js
var math = require('./math');

console.log(math.add(3, 4)); // 输出 7
console.log(math.subtract(7, 2)); // 输出 5

在这个示例中, math.js 导出了 addsubtract 函数, 并将它们作为对象放到 module.exports 中,以便其他模块可以访问。在 main.js 中,通过使用 require 命令来加载模块,并使用导出的函数来执行相应的操作。