📅  最后修改于: 2023-12-03 14:42:42.083000             🧑  作者: Mango
如果你正在准备JavaScript面试,以下是一些常见的JavaScript面试问题,以及对每个问题的解释和示例代码。
闭包是指函数可以访问定义在父函数内部作用域中的变量。闭包最常用的应用场景是在实现参数化API时进行数据隐藏。
以下是一个闭包示例:
function outerFunction() {
var outerValue = 'hi';
function innerFunction() {
console.log(outerValue);
}
return innerFunction;
}
var innerFunc = outerFunction();
innerFunc(); // 输出 'hi'
在这个示例中,innerFunction
访问了定义在 outerFunction
中的 outerValue
变量。由于 innerFunction
被外部的变量所引用,因此 outerValue
不会被垃圾回收机制清除。
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
的一个实例。这意味着任何属性或方法的查询都沿着原型链向上进行,直到匹配到适当的属性或方法。
事件委托是指将事件处理程序附加到由其子元素组成的父级元素上,而不是附加到每个子元素上。这样可以在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
元素,以便执行适当的操作。
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
方法用于处理已拒绝的承诺。
模块是将程序分解为可重用部分的一种方式。在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
导出了 add
和 subtract
函数, 并将它们作为对象放到 module.exports
中,以便其他模块可以访问。在 main.js
中,通过使用 require
命令来加载模块,并使用导出的函数来执行相应的操作。