83. 面试官:vue中data为什么是一个函数,为什么不能直接写对象

82期问题及答案

1. js中常见的设计模式有哪些?

JavaScript 中常见的设计模式有很多,它们是为了解决特定类型问题而形成的通用解决方案。以下是一些常见的 JavaScript 设计模式,并附带示例说明:

  1. 单例模式(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,两者是同一个实例
  2. 工厂模式(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');
  3. 观察者模式(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');
  4. 模块模式(Module Pattern):

    模块模式将相关的变量和函数封装在一个模块内部,提供了一种避免全局污染的方式。

    const Module = (function () {
      let privateVar = 0;
      
      function privateFunction() {
        // 私有函数逻辑
      }
      
      return {
        publicVar: 42,
        publicFunction: function () {
          // 公共函数逻辑
        },
      };
    })();
    
    console.log(Module.publicVar);
  5. 策略模式(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 中,任务可以分为两种主要类型:异步任务和同步任务。这两种任务的区别在于它们的执行方式和影响程序执行的方式。

同步任务

  1. 同步任务按照代码的顺序执行,即从上到下,一行一行执行。

  2. 同步任务会阻塞后续代码的执行,直到当前任务完成。

  3. 通常,JavaScript 中的函数调用是同步的,例如普通的函数调用、循环等都是同步任务。

  4. 同步任务执行速度较快,通常不需要等待太长时间。

示例:

console.log('Start');
for (let i = 0; i < 1000000000; i++) {
  // 同步任务,耗时较长
}
console.log('End');

在上述示例中,for 循环是一个同步任务,会阻塞后续代码的执行。

异步任务

  1. 异步任务不会阻塞后续代码的执行,它们会在后台执行,然后在完成后通知主线程。

  2. 异步任务通常涉及 I/O 操作(例如网络请求、文件读取)、定时器(setTimeoutsetInterval)以及事件处理(例如用户点击事件、HTTP 请求完成事件)等。

  3. 异步任务的执行速度不确定,取决于任务本身的性质和执行环境。

示例:

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分钟来学习与思考,在千变万化,类库层出不穷的今天,不要等到找工作时才狂刷题,提倡每日学习。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值