Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

面试题4(day2) #7

Open
robbiemie opened this issue Feb 28, 2024 · 0 comments
Open

面试题4(day2) #7

robbiemie opened this issue Feb 28, 2024 · 0 comments

Comments

@robbiemie
Copy link
Owner

讲讲 vue 响应式原理

在改变数据的时候,视图会跟着更新。这意味着你只需要进行数据的管理,给我们搬砖提供了很大的便利。

React也有这种特性,但是React的响应式方式跟VUE完全不同。React是通过this.setState去改变数据,然后根据新的数据重新渲染出虚拟DOM,最后通过对比虚拟DOM找到需要更新的节点进行更新。也就是说React是依靠着虚拟DOM以及DOM的diff算法做到这一点的。

第一步:组件初始化的时候,先给每一个Data属性都注册getter,setter,也就是reactive化。然后再new 一个自己的Watcher对象,此时watcher会立即调用组件的render函数去生成虚拟DOM。在调用render的时候,就会需要用到data的属性值,此时会触发getter函数,将当前的Watcher函数注册进sub里。
第二步:当data属性发生改变之后,就会遍历sub里所有的watcher对象,通知它们去重新渲染组件。

实现一个事件发布订阅类

题解

class EventEmitter {

  constructor() {
    this.eventMap = {}
  }

  emit(name, ...args) {
    if(!this.eventMap[name]) return
    for(let callback of this.eventMap[name]) {
      callback.apply(this, args)
    }
  }

  on(name, callback) {
    if(!this.eventMap[name]) {
      this.eventMap[name] = []
    }
    this.eventMap[name].push(callback)
  }

  once(name, callback) {
    if(!this.eventMap[name]) {
      this.eventMap[name] = []
    }
    callback.once = true
    this.eventMap[name].push(callback)
  }

  off(name, callback) {
    if(!this.eventMap[name]) return
    const index = this.eventMap[name].findIndex(item => item === callback);
    if(index > -1) {
      this.eventMap.splice(index, 1)
    }
  }
}

classA extends classB 编译成 es5

class A {
  constructor(name) { this.name = name}
  say() {}
}

class B {
}

题解

// 方法1
function A (name) {
  this.name = name
}

A.prototype.say = function() {}


function B (name) {
  A.call(this, name)
}

B.prototype = Object.create(A.prototype)
B.prototype.constructor = B

new B()

// 方法2


// class A {
//   constructor(name) { this.name = name}
//   say() {}
// }

// class B {

// }


function A (name) {
  this.name = name
}

A.prototype.say = function() {}


function B (name) {
  A.call(this, name)
}

function extend(CstrA, CstrB) {
  const pt = Object.create(CstrA.prototype);
  CstrB.prototype = pt;
  CstrB.prototype.constructor = CstrB
}

extend(A, B)

new B()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

1 participant