【前端开发者】如果只会用而不会回答技术点的话,可以来看看~

1、谈谈 This 对象的理解

this 是执行上下文中的一个属性,它指向最后一次调用这个方法的对象。在实际开发中,this 的指向可以通过四种调用模式来判断。

第一种是函数调用模式,当一个函数不是一个对象的属性时,直接作为函数来调用时,this 指向全局对象。

第二种是方法调用模式,如果一个函数作为一个对象的方法来调用时,this 指向这个对象。

第三种是构造器调用模式,如果一个函数用 new 调用时,函数执行前会新创建一个对象,this 指向这个新创建的对象

第四种是 apply 、 call 和 bind 调用模式,这三个方法都可以显示的指定调用函数的 this 指向。

其中 apply 方法接收两个参数:一个是 this 绑定的对象,一个是参数数组。call 方法接收的参数,第一个是 this 绑定的对象,后面的其余参数是传入函数执行的参数。

也就是说,在使用 call() 方法时,传递给函数的参数必须逐个列举出来。bind 方法通过传入一个对象,返回一个 this 绑定了传入对象的新函数。这个函数的 this 指向除了使用 new 时会被改变,其他情况下都不会改变。

这四种方式,使用构造器调用模式的优先级最高,然后是 apply 、 call 和 bind 调用模式,然后是方法调用模式,然后是函数调用模式。

2、什么是闭包,为什么要用它?

闭包是指有权访问另一个函数作用域中变量的函数,创建闭包的最常见的方式就是在一个函数内创建另一个函数,创建的函数可以访问到当前函数的局部变量

闭包有两个常用的用途。

闭包的第一个用途是使我们在函数外部能够访问到函数内部的变量。通过使用闭包,我们可以通过在外部调用闭包函数,从而在外部访问到函数内部的变量,可以使用这种方法来创建私有变量。

函数的另一个用途是使已经运行结束的函数上下文中的变量对象继续留在内存中,因为闭包函数保留了这个变量对象的引用,所以这个变量对象不会被回收。

其实闭包的本质就是作用域链的一个特殊的应用,只要了解了作用域链的创建过程,就能够理解闭包的实现原理。

3、浅谈Vue双向数据绑定的原理

所谓双向数据绑定, 无非就是数据层和视图层中的数据同步, 在写入数据时视图层实时的跟着更新!

  • 大佬们是这么描述的:

实现mvvm的双向绑定,是采用数据劫持结合发布者-订阅者模式的方式,通过Object.defineProperty()【Dep】来劫持各个属性的setter,getter,在数据变动时发布消息给订阅者,触发相应的监听回调。就必须要实现以下几点:
1、实现一个数据监听器Observer,能够对数据对象的所有属性进行监听,如有变动可拿到最新值并通知订阅者
2、实现一个指令解析器Compile,对每个元素节点的指令进行扫描和解析,根据指令模板替换数据,以及绑定相应的更新函数
3、实现一个Watcher,作为连接Observer和Compile的桥梁,能够订阅并收到每个属性变动的通知,执行指令绑定的相应回调函数,从而更新视图
4、mvvm入口函数,整合以上三者

【前端开发者】如果只会用而不会回答技术点的话,可以来看看~

个人理解就是getter函数里面执行的任务就是watcher订阅者, 而setter函数执行的任务就是发布者 

ECMAScript中有两种属性: 数据属性和访问器属性, 数据属性一般用于存储数据数值, 访问器属性对应的是set/get操作, 不能直接存储数据值

  • 简单点的方式

【前端开发者】如果只会用而不会回答技术点的话,可以来看看~

如上图所示,我们可以看到,整体实现分为四步:

1、实现一个Compile,对指令进行解析,初始化视图,并且订阅数据的变更,绑定好更新函数

2、实现一个Observer,对数据进行劫持,通知数据的变化

3、实现一个Watcher,将其作为以上两者的一个中介点,在接收数据变更的同时,让Dep添加当前Watcher,并及时通知视图进行update。

4、实现MVVM,整合以上三者,作为一个入口函数

 

  • 流程解读:

第一步:创建MVVM、Compile类,并且利用createDocumentFragment将<div id="app"></div>下的标签放到JS文档碎片中去。

第二步:对 标签 进行编译,将带有 v- 指令的标签和{{ }}的标签解析出来

第三步:创建Observer类进行数据劫持、深度递归劫持,当data中设置值或者修改值的时候,利用Object.defineProperty对值进行监控。

第四步:创建Watch类观察者,用新值和老值进行比对,如果发生变化,就调用更新方法,进行视图更新。

第五步:将输入框v-model和视图绑定起来,输入框的值变化,同时页面中通过{{}}绑定的值也变化,实现双向数据绑定。