程序员去大公司面试自我介绍,学习vue源码(10,前端基础入门

parentName:111

}

},

filters:{

all(){  return “我是过滤器” }

}

})

页面的 filter 解析成什么

首先,上面的例子会被解析成下面的渲染函数

(function() {

with(this) {

return _c(‘div’,[

_v(_s(_f(“all”)(parentName)))

])

}

}

这段代码继续解释下

  1. _c 是渲染组件的函数,这里会渲染出根组件

  2. 这是匿名自执行函数,后面渲染的时候调用,会 绑定当前实例为作用域

  3. with 的作用是,绑定大括号内代码的 变量访问作用域,所以里面的所有变量都会从 实例上获取

然后,你可以看到 ' parentName | all ' 被解析成 _f('all')( parentName )

怎么解析的?

简单说就是,当匹配到 | 这个符号,就知道你用过滤器,然后就解析成 _f 去获取对应过滤器 并调用,这个过程不赘述

_f 是什么?


_f 是获取具体过滤器的函数

1_f 会在Vue 初始化的时候,注册到 Vue 的原型上

// 已简化

function installRenderHelpers(target) {

target._s = toString;

target._f = resolveFilter;

}

installRenderHelpers(Vue.prototype);

所在在 上面的 渲染函数 with 绑定当前实例vm为作用域 之后,_f 从vm 获取,成了这样 vm._f

_f 是 resolveFilter,一个可以获取 具体filter 的函数

使用 _f(“all”) 就能获取到 all 这个过滤器,resolveFilter 下面会说

怎么获取下面继续…

设置的 filter 如何被调用

由上面可以看到,_f 是 resolveFilter 赋值的,下面是 resolveFilter 源码

// 已简化

function resolveFilter(id) {

return resolveAsset(

this.$options, ‘filters’, id, true

) || identity

}

要是你看过学习vue源码(3) 手写Vue.directive、Vue.filter、Vue.component方法,相信这里你很熟悉,其实就是从this.options.filters里找对应的过滤器函数来调用,如图所示

this.options 会拿到当前组件的所有选项

你问我为什么?

根据上一个问题知道

  1. _f  会使用 实例去调用 ,vm._f  类等 vm.resolveFilter

  2. 所以,resolveFilter 的 执行上下文 this 是 vm

  3. 所以,this.$options 就是 实例的 options 啦

接着,调用 resolveAsset ,目的就是拿到 组件选项中的 具体 filter

传入 当前组件的选项 ,指定要其选项 filters ,指定具体 filter 名

function resolveAsset(

options, type, id, warnMissing

) {

// g:拿到  filters 选项

var assets = options[type];

// g:返回 调用的 filter

return assets[id]

}

_f(“all”) 流程 就成了下面这样

  1. 拿到 组件选项 中的 filters

  2. 然后再从 filters 中,拿到 all 这个filter

  3. 执行返回的 all 过滤函数时,传入需要过滤的值 parentName

  4. 得到 返回了 过滤后的值

所以,当渲染函数解析的时候,碰到使用过滤器的地方,按流程拿到过滤值后,就可以渲染到页面上了

_f(“all”)(parentName)) 就会变成 “我是过滤器” 放到 渲染函数中,最后,就是渲染到页面了

总结

fitler 其实就是从组件选项 filters 获取你设置的某个filter,并调用,然后使用你函数执行的返回值渲染

太简单了,总结跟没总结一样…

render 什么时候开始执行?

如果你看过学习vue源码(4) 手写vm.$mount方法,我相信你已经知道了

如图所示,是在挂载阶段执行的。

总结


每个模板经过 compile 都会生成一个 render 函数

render 作为 渲染三部曲的第二部,主要作用就是 执行 render,生成 Vnode

把 template 上绑定的数据,都保存到 vnode 中

然后,生成 Vnode,就是为了给 渲染三部曲的 第三部 Diff 提供源动力

从而完成 DOM 挂载

到这里其实基本就已经结束了render的思路,但是源码中有个静态render,这个 对渲染性能的提高有极大的帮助,所以必须看下。

没错,就是 静态 render,看过学习vue源码(8)手写优化器的人,应该知道什么是 静态 render

静态 render 就是用于渲染哪些不会变化的节点

大家可以先看看,Vue 是怎么判断某个节点是否是静态节点

好,下面开始我们的正文,想了想,我们还是以几个问题开始吧

1、静态 render 是什么样子的

2、静态 render 是怎么生成和 保存

3、静态 render 怎么执行

什么是 静态Render


静态 render 其实跟 render 是一样的,都是执行得到 Vnode

只是静态 render,没有绑定动态数据而已,也就是说不会变化

比如说,一个简单 render 是这样的

绑定了动态数据,需要从实例去获取

_c(‘div’,[_v(_s(aa))])

而静态 render 是这样的

没有动态数据,这个静态render 的执行结果是永远不会变的

_c(‘div’,[_c(‘span’,[_v(“1”)])])

生成保存静态Render


静态 render 是在 generate 阶段生成的,生成的方式和 render 是一样的

比如在一个模板中,有很多个静态 根节点,像这样

首先,Vue 会在遍历模板的时候,发现 span 和 strong 本身以及其子节点都是静态的

那么就会给 span 和 strong 节点本身设置一个属性 staticRoot,表示他们是静态根节点

然后这两个静态根节点就会生成自己专属的 静态 render

如果你有一直看我的Vue 笔记的话,你应该这里是会有点印象的

之后

静态 render 生成之后是需要保存的,那么保存在哪里呢?

保存在一个数组中,名叫 staticRenderFns,就是直接push 进去

当然了,此时的 push 进去的 静态 render 还是字符串,并没有变成函数

以上面的模板为例,这里的 staticRenderFns 就是这样,包含了两个字符串

staticRenderFns  = [

“_c(‘span’,[_c(‘b’,[_v(“1”)])])”,

“_c(‘strong’,[_c(‘b’,[_v(“1”)])])”

]

但是在后面会逐个遍历变成可执行的函数

staticRenderFns = staticRenderFns.map(code => {

return new Function(code)

});

那么 这个 staticRenderFns 又是什么啊?

每个 Vue 实例都有一个独立的 staticRenderFns,用来保存实例本身的静态 render

staticRenderFns 的位置是

vm.$options.staticRenderFns

执行静态Render


静态 render 需要配合 render 使用,怎么说

看个例子

这个模板的 render 函数是

_c(‘div’,[

_m(0),

_v(_s(a),

_m(1)

])

_m(0) , _m(1) 就是执行的就是 静态 render 函数,然后返回 Vnode

于是 render 也可以完成 vnode 树的构建了

那么 _m 是什么呢?

在 Vue 初始化时,给Vue的原型便注册了这个函数,也就是说每个实例都继承到 _m

function installRenderHelpers(target) {

target._m = renderStatic;

}

installRenderHelpers(Vue.prototype);

再来看 renderStatic

function renderStatic(index) {

var cached = this._staticTrees || (this._staticTrees = []);

var tree = cached[index];

// 如果缓存存在,就直接返回

if (tree) return tree

// 这里是执行 render 的地方

tree = cached[index] =

this.$options.staticRenderFns[index].call(

this, null, this

);

// 只是标记静态 和 节点id 而已

markStatic(tree, “static” + index, false);

return tree

}

这个函数做的事情可以分为几件

1、执行静态render

2、缓存静态render 结果

3、标记 静态 render 执行得到的 Vnode

我们来一个个说

自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。

深知大多数前端工程师,想要提升技能,往往是自己摸索成长或者是报班学习,但对于培训机构动则几千的学费,着实压力不小。自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!

因此收集整理了一份《2024年Web前端开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。
img
img
img
img
img
img

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上前端开发知识点,真正体系化!

由于文件比较大,这里只是将部分目录大纲截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且后续会持续更新

如果你觉得这些内容对你有帮助,可以添加V获取:vip1024c (备注前端)
img

最后

==
就答题情况而言,第一问100%都可以回答正确,第二问大概只有50%正确率,第三问能回答正确的就不多了,第四问再正确就非常非常少了。其实此题并没有太多刁钻匪夷所思的用法,都是一些可能会遇到的场景,而大多数人但凡有1年到2年的工作经验都应该完全正确才对。
只能说有一些人太急躁太轻视了,希望大家通过此文了解js一些特性。

并祝愿大家在新的一年找工作面试中胆大心细,发挥出最好的水平,找到一份理想的工作。

一个人可以走的很快,但一群人才能走的更远。不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎扫码加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!
img

图片转存中…(img-OiAz6QlH-1712558424907)]
[外链图片转存中…(img-BI3WAKEV-1712558424907)]
[外链图片转存中…(img-wXekN5jW-1712558424907)]
[外链图片转存中…(img-Bzfqi7k3-1712558424908)]

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上前端开发知识点,真正体系化!

由于文件比较大,这里只是将部分目录大纲截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且后续会持续更新

如果你觉得这些内容对你有帮助,可以添加V获取:vip1024c (备注前端)
[外链图片转存中…(img-kfwaBS61-1712558424908)]

最后

==
就答题情况而言,第一问100%都可以回答正确,第二问大概只有50%正确率,第三问能回答正确的就不多了,第四问再正确就非常非常少了。其实此题并没有太多刁钻匪夷所思的用法,都是一些可能会遇到的场景,而大多数人但凡有1年到2年的工作经验都应该完全正确才对。
只能说有一些人太急躁太轻视了,希望大家通过此文了解js一些特性。

并祝愿大家在新的一年找工作面试中胆大心细,发挥出最好的水平,找到一份理想的工作。

一个人可以走的很快,但一群人才能走的更远。不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎扫码加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!
[外链图片转存中…(img-vrafTueW-1712558424908)]

  • 9
    点赞
  • 21
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值