82期问题及答案
1. js中常见的设计模式有哪些?
JavaScript 中常见的设计模式有很多,它们是为了解决特定类型问题而形成的通用解决方案。以下是一些常见的 JavaScript 设计模式,并附带示例说明:
单例模式(Singleton Pattern):
单例模式确保一个类只有一个实例,并提供一个全局访问点。
const Singleton = (function () { let instance; function createInstance() { // 实际创建单例的逻辑 return {}; } return { getInstance: function () { if (!instance) { instance = createInstance(); } return instance; }, }; })(); const singleton1 = Singleton.getInstance(); const singleton2 = Singleton.getInstance(); console.log(singleton1 === singleton2); // true,两者是同一个实例
工厂模式(Factory Pattern):
工厂模式用于创建对象,但隐藏了对象的具体创建细节。
function Dog(name) { this.name = name; } function Cat(name) { this.name = name; } function createAnimal(type, name) { switch (type) { case 'dog': return new Dog(name); case 'cat': return new Cat(name); default: throw new Error('Unknown animal type'); } } const myDog = createAnimal('dog', 'Buddy');
观察者模式(Observer Pattern):
观察者模式用于实现对象间的一对多依赖关系,当一个对象改变状态时,依赖它的对象都会被通知并自动更新。
class Subject { constructor() { this.observers = []; } addObserver(observer) { this.observers.push(observer); } notifyObservers(data) { this.observers.forEach(observer => observer.update(data)); } } class Observer { update(data) { console.log(`Received data: ${data}`); } } const subject = new Subject(); const observer1 = new Observer(); const observer2 = new Observer(); subject.addObserver(observer1); subject.addObserver(observer2); subject.notifyObservers('New data available');
模块模式(Module Pattern):
模块模式将相关的变量和函数封装在一个模块内部,提供了一种避免全局污染的方式。
const Module = (function () { let privateVar = 0; function privateFunction() { // 私有函数逻辑 } return { publicVar: 42, publicFunction: function () { // 公共函数逻辑 }, }; })(); console.log(Module.publicVar);
策略模式(Strategy Pattern):
策略模式定义一系列算法,并将它们封装起来,使它们可以互相替换。
class PaymentStrategy { pay(amount) { // 具体支付逻辑 } } class CreditCardPayment extends PaymentStrategy { pay(amount) { console.log(`Paid $${amount} with credit card`); } } class PayPalPayment extends PaymentStrategy { pay(amount) { console.log(`Paid $${amount} with PayPal`); } } const payment1 = new CreditCardPayment(); const payment2 = new PayPalPayment(); payment1.pay(100); payment2.pay(50);
这只是一小部分常见的 JavaScript 设计模式,还有许多其他模式,每种模式都有不同的用例和优点。选择适当的设计模式取决于你的项目需求和设计目标。
2. instanceof 运算符的原理是什么?能否自己实现一个?
instanceof
运算符用于检查一个对象是否是某个构造函数的实例。它的原理是通过检查对象的原型链,看是否包含构造函数的原型。如果包含,就返回 true
,否则返回 false
。
你可以自己实现一个简单版本的 instanceof
运算符,下面是一个示例:
function customInstanceof(obj, constructor) {
// 检查输入是否合法
if (typeof obj !== 'object' || obj === null) {
return false;
}
// 获取对象的原型
let proto = Object.getPrototypeOf(obj);
// 循环查找原型链,直到找到构造函数的原型或到达原型链末尾(null)
while (proto !== null) {
if (proto === constructor.prototype) {
return true;
}
proto = Object.getPrototypeOf(proto);
}
return false;
}
// 示例
function Person(name) {
this.name = name;
}
const person = new Person('Alice');
console.log(customInstanceof(person, Person)); // true
console.log(customInstanceof(person, Object)); // true,所有对象都是 Object 的实例
console.log(customInstanceof(person, Array)); // false
上述代码中的 customInstanceof
函数模拟了 instanceof
的行为。它首先检查输入是否合法,然后通过循环遍历对象的原型链来查找构造函数的原型,如果找到就返回 true
,否则返回 false
。
需要注意的是,这只是一个简单的演示,实际的 instanceof
实现可能会更复杂,考虑到一些特殊情况。但这个例子可以帮助你理解 instanceof
运算符的基本原理。
3. js中有哪些异步任务,和同步任务有什么区别?
在 JavaScript 中,任务可以分为两种主要类型:异步任务和同步任务。这两种任务的区别在于它们的执行方式和影响程序执行的方式。
同步任务:
同步任务按照代码的顺序执行,即从上到下,一行一行执行。
同步任务会阻塞后续代码的执行,直到当前任务完成。
通常,JavaScript 中的函数调用是同步的,例如普通的函数调用、循环等都是同步任务。
同步任务执行速度较快,通常不需要等待太长时间。
示例:
console.log('Start');
for (let i = 0; i < 1000000000; i++) {
// 同步任务,耗时较长
}
console.log('End');
在上述示例中,for
循环是一个同步任务,会阻塞后续代码的执行。
异步任务:
异步任务不会阻塞后续代码的执行,它们会在后台执行,然后在完成后通知主线程。
异步任务通常涉及 I/O 操作(例如网络请求、文件读取)、定时器(
setTimeout
、setInterval
)以及事件处理(例如用户点击事件、HTTP 请求完成事件)等。异步任务的执行速度不确定,取决于任务本身的性质和执行环境。
示例:
console.log('Start');
setTimeout(function () {
console.log('Async task completed');
}, 1000); // 异步任务,不会阻塞后续代码
console.log('End');
在上述示例中,setTimeout
是一个异步任务,它不会阻塞后续代码的执行,而是在指定的时间后执行回调函数。
总结:
同步任务按照顺序执行,会阻塞后续代码。
异步任务不会阻塞后续代码,它们在后台执行并在完成后通知主线程。
异步任务通常用于处理可能耗时较长或需要等待外部资源的操作,以提高程序的性能和响应性。
JavaScript 使用事件循环机制来处理异步任务,包括宏任务(macrotasks)和微任务(microtasks)。
注意:虽然异步任务不会阻塞后续代码的执行,但它们也不是完全并行执行的,它们仍然需要等待事件循环机制的调度。因此,异步任务的执行顺序可能会受到其他因素的影响。
83期
1. vue中data为什么是一个函数,为什么不能直接写对象
2. 什么是伪类,什么是伪元素,举例说明
3. vue中mixin和extend有什么区别
上面问题的答案会在第二天的公众号推文中公布,如果觉得这篇文章对你有帮助,希望多多点赞收藏加关注,也希望分享给更多爱学习的小伙伴,你的肯定是我最大的动力。
学习不打烊,充电加油只为遇到更好的自己,每天早上9点纯手工发布面试题(死磕自己,愉悦大家) 希望大家在这浮夸的程序员圈里保持冷静,每天坚持花20分钟来学习与思考,在千变万化,类库层出不穷的今天,不要等到找工作时才狂刷题,提倡每日学习。