You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

256 lines
17 KiB
Markdown

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

# 期末答疑(一):前端代码单元测试怎么做?
你好我是winter。
我们专栏课程的知识部分已经告一段落了。今天,我来集中解决一下大家在学习中遇到的问题,我争取用快问快答的形式,咱们多回答一些问题。
**1\. 前端代码单元测试还是非常有必要的,不知道老师这一块是怎么做的,能否分享一下?**
答:关于单元测试这件事,虽然在业务代码我没做成功过,但是它在框架和基础库开发中起到了非常积极的作用。
我们平时写代码也肯定写一部分就要运行一下试试其实这种行为就是单元测试只是我们把很多自动化的内容用人肉执行了并且没有保存和管理case也没有统计code coverage。
只要选择一个好的单元测试框架,单元测试成本其实不高,尤其是比较复杂的底层库,引入单元测试不但不会消耗时间,还会提高效率。
所以我认为单元测试要实行,有两个关键点你要格外注意:一是出一套好的单元测试方案,二是在基础库和框架开发中引入单元测试。
**2\. 关于Undefined 如果一个变量没有赋值后面又赋值这个过程就是“变量会被篡改”的意思么而null 为什么又不会被篡改?一个变量开始定义为 null 然后赋值其他数据这个过程不算篡改吗?**
undefined是个全局变量null是个关键字在一些版本比较旧的浏览器上你可以试试
```
undefined = 1;
```
但是你在任何版本的浏览器上,都不能这么干:
```
null = 1;
```
这样的话,上面这个代码就会报错了。
**3\. winter老师你好我们公司的前端是Node.js写的如何做性能监控呢如何做页面加载优化呢我对您的页面性能打分系统很感兴趣能详细讲一讲吗谢谢了。**
首先Node.js写的是服务端代码跟前端性能没有任何关系Node.js的性能监控比前端性能监控复杂得多你可以了解下alinode。
前端性能打分可能主要包含几个部分。
* 图片检查图片数量和图片大小比如单个超过50k总量超过400k的图片就要注意了如果检查到小图片也可以建议用data uri内联。
* 请求数检查请求数检查是否有独立的JS、CSS请求这些都是潜在的优化点。
域名检查域名是否有在http dns的范围内检查域名数量是否过多检查资源文件域名是否属于CDN。
* 实际加载时间:如果测试环境加载时间过程,也可能说明一些问题。
* 缓存:检查静态资源是否设置了正确的缓存。
你可以自己动手试试。
**4\. 有一个疑惑是,大小写的两个属性有什么区别呢,比如:**
```
Screenscreen
Eventevent
```
答:这里面大写的是类,小写的是对象。
**5\. 我还是比较认同从左往右匹配的规则这样就像老师讲的可以在构建DOM树的同时来进行匹配CSS规则相当于同时构建渲染树了而不必等到DOM构建完毕再进行CSS的规则匹配。**
**进行构建渲染树虽然从右向左匹配对于复杂的选择器更优但是这里面浪费了等待DOM构建完毕才能使用的CSS匹配规则。而且相对于同为id等单一选择器而言明显从左向右更具有优势这是我的一点想法望老师指正**
答:其实我在[之前的分享](https://v.youku.com/v_show/id_XMjMzMzU2NDc2.html?spm=a2h0k.11417342.soresults.dtitle)中做过一个试验当时的Chrome确实是从右往左如果#id在最左速度会更快但是那个过程是后添加CSS的情况。
**6\. 程老师你好。我在很多地方看到的说法是CSS会阻塞DOM渲染但不会阻塞DOM的解析且CSS文件的请求是异步请求。**
**那么如果按照您所说DOM的构建和CSS属性的计算是同步的话head中CSS文件的下载以及CSSOM的rule部分的构建应该会阻塞HTML的解析和DOM的构建。好像这两种说法之间就有了冲突。麻烦程老师有空的时候可以帮忙解释一下万分感谢。**
其实你误解了我的意思DOM构建的结果到CSS属性计算是个流水线所以CSS会阻塞CSS计算不会阻塞DOM构建。
**7\. 老师我记得有的书上或者是资料上说超过五次的if else 就最好用 switch case来替换。这样效率更好。您这里为什么说不用这个呢**
我在性能部分讲了“凡是不做profiling的性能优化都是耍流氓”。
具体的话,你可以看一看“[43 | 性能:前端的性能到底对业务数据有多大的影响](https://time.geekbang.org/column/article/94156)”这一篇。
**8\. 函数调用和函数执行有什么区别? 有没有相应的标准?**
我们一般讲“A函数调用了B函数”“浏览器执行了B函数”所以你看两者的区别是主语不同你可以感受一下区别。它们对应的标准都是ECMA262。
**9\. 请问下老师为什么flexible布局方案不再维护了呢这个方案本身存在问题吗**
不存在问题但是rem计算是个历史方案现在我比较推荐大家使用vw。
**10\. 有的工业软件3D建模的也可以用浏览器来实现了用的是ThreeJS WebGL老师了解这些嘛怎么看待这个发展前景。**
挺好的但是我觉得这件事由本来做3D的工程师转型更方便。
**11\. 最近出于好奇我clone了github上chrome的源码仓库发现竟然有12G多貌似比linux内核的源码还多。个人特别想探索一下浏览器源码但面对如此庞大的代码不禁望而生畏也不知从何下手。**
**请问老师浏览器内核源码该如何去研究skia渲染引擎是最先进吗svgcanvasWebGL该如何选择怎样深入地学习和掌握它们呢望老师拨冗答疑谢谢**
答:你先编译通过吧,然后试着跑起来打断点这样子,其实这件事没有捷径,多花些时间就可以。
skia引擎是不是最先进这事我也不好说其实在工程领域我们一般不追求“最先进”我们只需要它“足够先进”。
关于如何选择,我收到了很多问题,不过我其实都不做回答,毕竟我没法替你决定你自己的职业发展道路,这个责任实在是有些重大了。
**12.看完老师列出的表格更迷茫了比如为什么transform属于level 1transform不是CSS3里的属性么level4是什么是CSS4么为什么color这种常用属性属于level4?不应该属于level1么好迷茫哦。**
我先解释一下你的问题一方面level4里有不等于level3里没有另一个是W3C定level并不是十分严谨有从1开始也有从3开始的。
除此之外我想提醒一下这个表格并不是给你去看level的而是告诉你标准在哪里让你去读标准的。
**13\. 请问老师我后台用的是Tomcat服务器前端用ajax请求静态资源时会间隔会报412也就是一次成功进入后台一次报412这该怎么解决呢**
理论上412意思是你浏览器的问题。从你提供的信息我没法给你解决方案建议你可以搞一个最小复现环境去Tomcat社区问。
**14.老师好,有个疑问: WHATWG 和 W3C 标准以哪个为准,这两个标准有什么区别?是不是相互不认可的。**
这个问题比较复杂WHATWG最初是几家不满W3C出走搞出来的后来被招安了把HTML5带回了W3C不过两边出标准的思路还是不太一样WHATWG是living standard就是随时更新标准没有版本的概念我是个人会倾向于WHATWG版本因为比较新而且Chrome跟得比较紧。
**15\. winter老师好可以给我讲一下那个presentational attributes ,有些看不懂。**
```
function showThis(){
console.log(this);
}
var o = {
showThis: showThis
}
showThis(); // global
o.showThis(); // o
```
**我知道函数中的this是由调用函数的对象决定的但这种理解总感觉是由结论推原因老师能不能讲解下。**
this是由调用函数的对象决定这完全是个规定没有什么原因。你后面的问题我节选掉了我其实没太理解到你想表述的意思你看到了可以再给我留言
**16\. 喜欢使用let和const看很多库里面他们都喜欢使用const并且推荐使用const比如声明一个数组。**
**老师能讲解下声明一个数组用let和const有什么区别吗在操作数组时都是往数组中push值原先的变量并物理地址并没有发生变化如果用let和用const有什么区别为什么const的性能会好一点**
性能好一些完全是乱说的用const的话可以避免你误把数组整个赋值掉比较有安全感吧。
1. **老师我有几个问题希望你回答:**
**老师讲到:“注意,我们这里讲的渲染过程,是不会把子元素绘制到渲染的位图上的,这样,当父子元素的相对位置发生变化时,可以保证渲染的结果能够最大程度被缓存,减少重新渲染。”**
* 缓存的是什么东西,位图吗?如何减少重新渲染的?
* 是不是所有的元素都有对应的位图?
**文中你举了两个例子,说如果只有一个位图,任何改变都会引起所有重新渲染。这个好理解,一个大位图就是一个单元,任何的改动相当于这个单元被变了,所以要重新创建这个,这样理解对吗?**
**但是你下面又说如果不合并,每次还是所有的重新渲染。感觉说的很矛盾啊。希望老师能回答一下我的疑问。**
答:缓存的是位图,父子元素位置变化时,因为子元素的位图被缓存,子元素不需要重新渲染,因为父元素的位图也被缓存,父元素也不需要重新渲染,只有父子元素合成起来的位图需要被渲染。
你这样理解是对的,如果不合并,每次改点什么东西,都要重新逐级合成最终的大位图,也相当于重新渲染。
**18\. 老师,“当没有强制指定文字书写方向时,在左到右文字中插入右到左向文字,会形成一个双向文字盒,反之亦然。”这个能不能给个例子,不明白什么意思。**
答:比如你在中文中插入几个阿拉伯语字符,阿拉伯语字符就会形成一个双向文字盒。
**19\. 看了您的流式数据的解释是不是可以理解当看到页面渲染的时候DOM是不是有可能都还没构建完成呢即使是理论上有这种可能吗**
渲染不但发生在DOM构建之前甚至可能发生在你下载网页完成之前比如你上个XX软件下载站是不是下载链接还没见到就看到广告了你提到的网上的那段是别人写错了。我节选掉了
**20\. footer 也可以和 asidenavsection 相关联(header不存在关联问题)不存在关联问题是什么意思啊不应该在header中使用吗下面又说header中可以使用nav老师的“关联”是什么意思啊**
因为footer有自己的语义footer必须要指明是谁的footer这样footer中的作者、地址才有意义所谓的关联就是这个意思了。
**21\. 子元素的事件委托给父元素时添加事件监听的第三个参数直接设置为true在捕获过程就判断父元素上的事件目标会比冒泡好些嘛**
答:对,但是你需要在捕获阶段想办法知道事件具体发生在哪个子元素上。
**22\. 老师 如果我想更深入的了解移动端的兼容问题,有没有好的学习路线呢?**
答:兼容问题不是学出来的,你想在山中苦修,自出洞来无敌手?手机早就更新好几代了。所以兼容问题必须靠实践,在一个需要兼容性的业务上,不断积累和更新兼容性知识。
**23\. 老师我在理解SICP这本书的过程抽象和数据抽象的时候代入到前端比如生命周期、事件处理等更多是过程的抽象能提出一些公用的过程而数据抽象更多指的是组件内的数据定义、api的设计、高阶组件等。**
**请问我这样理解对吗?或者说老师对过程抽象和数据抽象在前端中怎么理解的?如果理解得不对,有什么好的书或者文章帮助理解?**
SICP讲的是很实在的编程技巧在前端中对应的是变量、循环、条件这些东西SICP是一本好书你应该更认真地去阅读它。
**24\. 通过这个课程老师对于前端的划分为JavaScript、HTML和CSS、浏览器、工程实践几个部分。**
* **疑问1现在前端基本把Node也包括进来了对于Node的知识应该怎么定位**
* **疑问2Node属于后端的范畴了是否应该去学习下java相关的后端体系学习了后端的体系是否会反过来促进前端知识的学习呢。**
**winter老师对这两个问题怎么看呢谢谢。**
Node属于后端electron属于客户端不论你学哪个体系肯定对前端都有促进作用。
但是你不能认为懂了Node就懂了后端懂了electron就懂了客户端每个领域都可以很深入知识本来就是学不完的你能掌握多少只跟投入的时间有关这道理是很简单的与其困惑不如把困惑的时间拿来学习相信你会有所收获的。
**25\. 老师CSS是如何依附在DOM树上的?是通过前面讲得Node实例来实现的?**
在Node实例上添加属性我在“[12 | 浏览器:一个浏览器是如何工作的(阶段三)](https://time.geekbang.org/column/article/80311)”讲到了,你可以返回去看看。
**26.清楚为什么要使用语义化标签,是否有必要使用之前,很难让自己有动机去应用每个标签。另外标签新推出如何保持实时掌握最新的标签呢,如何解决浏览器兼容的问题?**
答:对语义化标签,我是建议不必追求全部掌握,现有需求再找标签即可。
**27\. 老师您好有个疑问想请教一下为啥基于对象关联风格的面向对象并不是像模拟类的行为的面向对象那么流行呢原型委托这种的不是应该更符合JavaScript语言本身的设计嘛类似这种**
```
var father = {
a: 1,
fn(): {
return 123;
}
}
var child = Object.create(father);
child.fn(); // 123
```
大部分人在学校学的都是C++和Java我就没见过教原型的这是现实没办法。
**28\. 老师,可否稍加解释一下执行上下文的分类? 网络上的文章说“ JavaScript 中可执行的代码可分为三种类型全局代码、函数代码、eval 代码对应三种执行上下文全局执行上下文、函数执行上下文、eval 执行上下文)。**
**在 ECMAScript 2018 中没有找到这种说法的依据。我的意思是,我不太清楚这些文章的说法是否正确,是否不够全面。**
答:这个说法倒不能说不正确,但是严重过时了。
现在ECMAScript 2018里面执行上下文非常复杂你可以看看各种Record重学前端课程里面也没有讲全。
**29\. 老师在ES5之前版本规范中会提及JavaScript的可执行代码分为全局、函数、Eval。但是在ES6之后版本规范中再也不提及可执行代码的概念了这是为什么呢**
答:其实这里是重构了一下表达方式,新加入了模块什么的。
**30\. 试过好多次找了很多方法flex兼容IE9以下每次都失败有什么好的解决办法吗**
如果真有IE9兼容需求我想只能单独写一份CSS了。
**31\. 请问大佬,如何冻结对象,一般什么样的场景可以用到?**
Object.freeze函数可以冻结对象。一般都是写底层库希望避免篡改。
**32.**
```
new Promise(function(resovle, reject) {
setTimeout(resovle, duration);
})
setTimeout(resovle, duration);和setTimeout(() => {resovle()}, duration);
```
**两者到底有什么区别,想不明白,求教。**
这个区别不大的第二种写法一般都是为了给resolve传参数不过如果你不想给resolve传特定参数为什么还要多写一个函数呢。
**33\. 我听JavaScript像听天书怎么办是不是要从0重新学起呀**
理论上我的课程是把JavaScript的内容重新组织了一下如果平时就在用JavaScript我认为问题不大。如果这部分完全听不懂可能说明确实基础薄弱建议你从0学起。
* * *
好了,本期的答疑告一段落,如果你还有其他的问题,或者还是没有弄清楚,你可以继续给我留言,我会继续解答大家的问题,并一起讨论。