灵魂拷问:说说你对前端的理解:
大多数人对前端的认识可能是写点简单的 HTML,CSS 样式,制作点网页界面,其实不然。
2005 年之前,前端开发这个词还是很少见的,尤其在国内。但近几年的前端可谓是飞速发展,在没有前端岗位之前,一个项目中负责后台功能逻辑处理的代码和前端页面展示代码混在一起,不免会给开发和维护带来各种问题,渐渐的许多大中小公司开始把前后端的界限分的越来越明确,前端工程师只管前端的事情,后端工程师只管后端的事情。
前端工程师的主要工作就是通过代码方式,增强系统的交互功能 ,同时结合后台开发技术,进行互联网的 Web 和 App 开发,致力于通过技术改善用户体验 。现在前端工程师的工作不仅仅只是网页制作,还有微网站、APP制作、游戏制作等,前端的技术也慢慢的从原来的 HTML+CSS+JavaScript 愈来愈丰富,如 jquery、Vue、React 等。同时不久将来相信前端工作开发模式将实现突破,Serverless无服务端计算的出现让我看到了这些迹象,
前端开发工程师在整个项目的开发和交付中扮演相当重要的角色,前端工程师是最贴近用户的程序员,主要负责实现页面交互,优化提升用户体验,如果后端是用来解决系统能不能用的问题,那么前端就用来解决系统好不好用的问题。
————————————————
什么是web标准?
WEB标准不是某一个标准,而是一系列标准的集合。网页主要由三部分组成:结构(Structure)、表现(Presentation)和行为 (Behavior)。
对应的标准也分三方面:结构化标准语言主要包括XHTML和XML,表现标准语言主要包括CSS,行为标准主要包括对象模型(如 W3C DOM)、ECMAScript等。这些标准大部分由W3C起草和发布,也有一些是其他标准组织制订的标准,比如ECMA(European Computer Manufacturers Association)的ECMAScript标准。
firefox没有浏览器内核
flash和js通过类ExternalInterface进行交互。
ExternalInterface有两个方法call和addCallback:
1、ExternalInterface.addCallback("在js里可调用的flash方法名",flash内方法) //在js里调用flash里的方法
2、ExternalInterface.call("js方法",传给js的参数) //在flash里调用js里的方法
————————————————
cookie虽然在持久保存客户端数据提供了方便,分担了服务器存储的负担,但还是有很多局限性的。
Doctype作用? 严格模式与混杂模式如何区分?它们有何意义?
参考答案
1. 声明位于文档中的最前面,处于 标签之前。告知浏览器以何种模式来渲染文档。
2. 严格模式的排版和 JS 运作模式是 以该浏览器支持的最高标准运行。
3. 在混杂模式中,页面以宽松的向后兼容的方式显示。模拟老式浏览器的行为以防止站点无法工作。
4. DOCTYPE不存在或格式不正确会导致文档以混杂模式呈现。
你知道多少种Doctype文档类型?
参考答案
1. 该标签可声明三种 DTD 类型,分别表示严格版本、过渡版本以及基于框架的 HTML 文档。Strict、Transitional 以及 Frameset。
HTML与XHTML——二者有什么区别
XHTML(可扩展超文本标记语言) = XML(可扩展标记语言) + HTML(超文本标记语言)
参考答案
最主要的不同:
XHTML 元素必须被正确地嵌套。
XHTML 元素必须被关闭。
标签名必须用小写字母。
XHTML 文档必须拥有根元素。
overflow属性定义溢出元素内容区的内容会如何处理
展开
参数是scroll时候,必会出现滚动条。
参数是auto时候,子元素内容大于父元素时出现滚动条。
参数是visible时候,溢出的内容出现在父元素之外。
参数是hidden时候,溢出隐藏。
————————————————
HTTP部分
SGML是指“标准通用标记语言”
HTML“HyperText Markup Language” (超文本标识语言)
xml(eXtensible Markup Language), “可扩展标识语言“
HTML 是人们抽取了 SGML 的一个微小子集而提取出来的。其早期规范比较松散,但比较易学。
XML 也是 SGML 的一个子集,但使用比较严格的模式。
DTD是文档类型定义,可定义合法的XML文档构建模块,它使用一系列合法的元素来定义文档的结构。
HTML5 ≈ HTML + CSS 3 + JavaScript + API.
从输入网址到显示页面的过程分析
1)应用层DNS解析域名
2)浏览器向服务器建立TCP连接(默认端口为80)(详细可以说下三次握手)
3)客户端发送HTTP请求
4)服务器响应请求
5)服务器向浏览器返回相应文件
6)TCP连接释放
7)浏览器根据HTML文件进行解析构建DOM树,构建渲染树,JS根据DOMAPI操作执行绑定事件等,页面显示完成。
HTML全局属性(global attribute)有哪些?
MDN: html global attribute或者W3C HTML global-attributes
accesskey:设置快捷键,提供快速访问元素如aaa在windows下的firefox中按alt + shift + a可激活元素
class:为元素设置类标识,多个类名用空格分开,CSS和javascript可通过class属性获取元素
contenteditable: 指定元素内容是否可编辑
contextmenu: 自定义鼠标右键弹出菜单内容
data-*: 为元素增加自定义属性
dir: 设置元素文本方向
draggable: 设置元素是否可拖拽
dropzone: 设置元素拖放类型: copy, move, link
hidden: 表示一个元素是否与文档。样式上会导致元素不显示,但是不能用这个属性实现样式效果
id: 元素id,文档内唯一
lang: 元素内容的语言
spellcheck: 是否启动拼写和语法检查
style: 行内css样式
tabindex: 设置元素可以获得焦点,通过tab可以导航
title: 元素相关的建议信息
translate: 元素和子孙节点内容是否需要本地化
————————————————
说说超链接target属性的取值和作用?
参考答案
target这个属性指定所链接的页面在浏览器窗口中的打开方式。
它的参数值主要有:
a、 _blank :在新浏览器窗口中打开链接文件
b、 _parent :将链接的文件载入含有该链接框架的父框架集或父窗口中。如果含有该链接的框架不是嵌套的,则在浏览器全屏窗口中载入链接的文件,就象 _self 参数一。
c、 _self :在同一框架或窗口中打开所链接的文档。此参数为默认值,通常不用指定。但是我不太理解。
d、 _top :在当前的整个浏览器窗口中打开所链接的文档,因而会删除所有框架。
`data-`属性的作用是什么?
参考答案
`data-`为H5新增的为前端开发者提供自定义的属性,这些属性集可以通过对象的 `dataset` 属性获取,不支持该属性的浏览器可以通过 `getAttribute` 方法获取 :
需要注意的是:`data-`之后的以连字符分割的多个单词组成的属性,获取的时候使用驼峰风格。 所有主流浏览器都支持 data-* 属性。
即:当没有合适的属性和元素时,自定义的 data 属性是能够存储页面或 App 的私有的自定义数据。
Vue scoped原理:
在vue文件中的style标签上,有一个特殊的属性:scoped。当一个style标签拥有scoped属性时,它的CSS样式就只能作用于当前的组件,也就是说,该样式只能适用于当前组件元素。通过该属性,可以使得组件之间的样式不互相污染。如果一个项目中的所有style标签全部加上了scoped,相当于实现了样式的模块化。
给一个组件中的所有dom添加了一个独一无二的动态属性data-v-xxx乱码,然后,给CSS选择器额外添加一个对应的属性选择器来选择该组件中dom,这种做法使得样式只作用于含有该属性的dom——组件内部dom。
介绍一下你对浏览器内核的理解?
参考答案
主要分成两部分:渲染引擎(layout engineer或 Rendering Engine) 和 JS 引擎。
渲染引擎:负责取得网页的内容(HTML、 XML 、图像等等)、整理讯息(例如加入 CSS 等),以及计算网页的显示方式,然后会输出至显示器或打印机。浏览器的内核的不同对于网页的语法解释会有不同,所以渲染的效果也不相同。所有网页浏览器、电子邮件客户端以及其它需要编辑、显示网络内容的应用程序都需要内核。
JS引擎则:解析和执行 javascript 来实现网页的动态效果。
最开始渲染引擎和JS引擎并没有区分的很明确,后来 JS 引擎越来越独立,内核就倾向于只指渲染引擎。
你做的网页在哪些浏览器测试过,这些浏览器的内核分别是什么?
a、 IE: trident 内核
b、 Firefox : gecko 内核
c、 Safari:webkit 内核
d、 Opera: 以前是 presto 内核, Opera 现已改用 Google Chrome 的 Blink 内核
e、 Chrome:Blink( 基于 webkit , Google 与 Opera Software 共同开发 )
什么是WebGL,它有什么优点?
WebGL(全写 Web Graphics Library )是一种 3D 绘图标准,这种绘图技术标准允许把 JavaScript 和 OpenGL ES 2.0 结合在一起,通过增加 OpenGL ES 2.0 的一个 JavaScript 绑定, WebGL 可以为 HTML5 Canvas 提供硬件 3D 加速渲染,这样 Web 开发人员就可以借助系统显卡来在浏览器里更流畅地展示 3D 场景和模型了,还能创建复杂的导航和数据视觉化。显然, WebGL 技术标准免去了开发网页专用渲染插件的麻烦,可被用于创建具有复杂 3D 结构的网站页面,甚至可以用来设计 3D 网页游戏等等。
WebGL完美地解决了现有的 Web 交互式三维动画的两个问题:
第一,它通过HTML脚本本身实现 Web 交互式三维动画的制作,无需任何浏览器插件支持 ;
第二,它利用底层的图形硬件加速功能进行的图形渲染,是通过统一的、标准的、跨平台的OpenGL接口实现的。
通俗说WebGL中 canvas 绘图中的 3D 版本。因为原生的 WebGL 很复杂,我们经常会使用一些三方的库,如 three.js 等,这些库多数用于 HTML5 游戏开发。
前端页面有哪三层构成,分别是什么?作用是什么?
结构层、表示层、行为层
结构层(structural layer)
由 HTML 或 XHTML之类的标记语言负责创建。标签,也就是那些出现在尖括号里的单词,对网页内容的语义含义做出了描述,但这些标签不包含任何关于如何显示有关内容的信息。例如,P标签表达了这样一种语义:”这是一个文本段。”
表示层(presentation layer)
由 CSS 负责创建。 CSS对”如何显示有关内容”的问题做出了回答。
行为层(behaviorlayer)
负责回答”内容应该如何对事件做出反应”这一问题。这是 Javascript 语言和 DOM主宰的领域
如何实现浏览器内多个标签页之间的通信?
参考答案
调用 localstorge、cookies 等本地存储方式
iframe的优缺点?
参考答案
优点:
1. 解决加载缓慢的第三方内容如图标和广告等的加载问题
2. Security sandbox
3. 并行加载脚本
缺点:
1. iframe会阻塞主页面的Onload事件
2. 即时内容为空,加载也需要时间
3. 没有语意
如果把 HTML5 看作做一个开放平台,那它的构建模块有哪些?
简述什么是跨域?解决跨域的几种方式?
跨域,指的是浏览器不能执行其他网站的脚本。它是由浏览器的同源策略造成的,是浏览器对JavaScript施加的安全限制。
同源策略:协议、端口、域名都必须一致!
解决跨域的方法:
CORS(跨域资源共享)
JSONP
Web Socket
postMessage(HTML5中的XMLHttpRequest Level 2中的API)
window.name + iframe
location.hash + iframe
动态创建script
document.domain + iframe (只有在主域相同的时候才能使用该方法)
CSS部分
position的absolute与fixed共同点与不同点
参考答案
A:共同点:
1.改变行内元素的呈现方式,display被置为inline-block;
2.让元素脱离普通流,不占据空间;
3.默认会覆盖到非定位元素上
B不同点:
absolute的”根元素“是可以设置的,而fixed的”根元素“固定为浏览器窗口。
当你滚动网页,fixed元素与浏览器窗口之间的距离是不变的。
link标签和import标签的区别
参考回答:
link属于html标签,而@import是css提供的
页面被加载时,link会同时被加载,而@import引用的css会等到页面加载结束后加载。
link是html标签,因此没有兼容性,而@import只有IE5以上才能识别。
link方式样式的权重高于@import的。
常见的内联(行内)、块状(块级)、内联块状元素分别有?
Block是块级元素,独占一行,,能设置宽度,高度,margin/padding水平垂直方向都有效,自动填充父元素,当超出的时候,自动换行。
Inline:设置width和height无效,不独占一行,margin在竖直方向上无效,padding在水平方向垂直方向都有效,前后无换行符
Inline-block:能设置宽度高度,margin/padding水平垂直方向 都有效,前后无换行符
内联:span、a 、br、 i 、em 、strong、label、q、var、cite、code
块状:div、p、h1、ol、ul、li、dl、table、address、blockquote、form行内块元素
内联块状元素:input 、 img
CSS3有哪些新特性?
参考答案
1. CSS3实现圆角(border-radius),阴影(box-shadow),
2. 对文字加特效(text-shadow、),线性渐变(gradient),旋转(transform)
3. transform:rotate(9deg) scale(0.85,0.90) translate(0px,-30px) skew(-9deg,0deg);// 旋转,缩放,定位,倾斜
4. 增加了更多的CSS选择器 多背景 rgba
5. 在CSS3中唯一引入的伪类是 ::selection.
6. 媒体查询,多栏布局
7. border-image
为什么img标签是inline元素还可以设置宽高?
在 CSS 中,可替换元素(replaced element)的展现效果不是由 CSS 来控制的。这些元素是一种外部对象,它们外观的渲染,是独立于 CSS 的。
简单来说,它们的内容不受当前文档的样式的影响。CSS 可以影响可替换元素的位置,但不会影响到可替换元素自身的内容。例如
有些元素仅在特定情况下被作为可替换元素处理,例如:
"image" 类型的 元素就像一样可替换
CSS的 content 属性用于在元素的 ::before 和 ::after 伪元素中插入内容。使用content 属性插入的内容都是匿名的可替换元素。
浮动的工作原理
CSS 的 Float(浮动),会使元素向左或向右移动,其周围的元素也会重新排列。
浮动元素脱离文档流,不占据空间。浮动元素碰到包含它的边框或者浮动元素的边框停留
清除浮动
1. 使用空标签清除浮动。
这种方法是在所有浮动标签后面添加一个空标签 定义css clear:both. 弊端就是增加了无意义标签。
2. 使用overflow,可以给父元素设置overflow:auto或者hidden
或者给包含浮动元素的父标签添加css属性 overflow:auto; zoom:1; zoom:1用于兼容IE6。
3. 使用after伪对象清除浮动。
该方法只适用于非IE浏览器。具体写法可参照以下示例。使用中需注意以下几点。一、该方法中必须为需要清除浮动元素的伪对象中设置 height:0,否则该元素会比实际高出若干像素;
z-index
z-index:可以设置元素的叠加顺序,但依赖定位属性
float:left、right、none、inherit
最初是为了文本环绕效果
圣杯布局和双飞翼布局:
1.两种布局方式都是把主列放在文档流最前面,使主列优先加载。
2.两种布局方式在实现上也有相同之处,都是让三列浮动,然后通过负外边距形成三列布局;所以footer需要加上clear:both;来清楚浮动。
3.两种布局方式的不同之处在于如何处理中间列的位置
相关代码参考面经
圣杯布局是利用父容器的左、右内边距+两个从列相对定位
双飞翼布局是把主列嵌套在一个新的父级块中利用主列的左右外边距进行布局调整。
个人还是推荐使用双飞翼布局
如何防止回流
重绘:当元素的外观或外观可见性(visibility)发生变化时会触发重绘
回流:render树中的部分或全部因为元素的规模尺寸、布局、隐藏等改变,需要重新计算render树。
避免回流和重绘方法
减少回流、重绘其实就是需要减少对render tree的操作,并减少对一些style信息的请求,尽量利用好浏览器的优化策略
(1) 避免操作DOM,创建一个documentFragment或div,在它上面应用所有DOM操作,最后再把它添加到window.document。也可以在一个display:none的元素上进行操作,最终把它显示出来。因为display:none上的DOM操作不会引发回流和重绘。
(2) 让要操作的元素进行"离线处理",处理完后一起更新,这里所谓的"离线处理"即让元素不存在于render tree中。如读取offsetLeft等属性。
(3) 尽可能在DOM树的末端改变class ,尽可能在DOM树的里面改变class,可以限制回流的范围,使其影响尽可能少的节点。
(4) 避免设置多层内联样式,因为每一个都会造成回流,样式合并在一个外部类,这样当该元素的class属性被操作时,只会产生一个reflow。
(5) 将需要多次回流的元素position属性设为absolute或fixed,这样该元素就会脱离文档流,它的变化不会影响其他元素变化。比如动画效果应用到position属性为absolute或fixed的元素上。
(6) 牺牲平滑度换取速度,动画元素每次移动3像素可能在非常快的机器上看起来平滑度低了,但它不会导致CPU在较慢的机器和移动设备中抖动
(7) 避免使用table布局,在布局完全建立之前,table需要很多关口,table是可以影响之前已经进入的DOM元素的显示的元素。即使一些小的变化和会导致table中所有其他节点回流。
(8) 避免使用css的JavaScript表达式,该规则较过时,但是个好主意。因为每次都需要重新计算文档,或部分文档、回流。
回流时,浏览器会使渲染树中受影响的部分失效,然后重新构造这部分的render树。完成回流之后浏览器会重新布局、绘制受影响的部分到屏幕中,该过程就是重绘。所以回流必定会引起重绘,但重绘不一定引起回流。
每个页面至少需要一次回流,就是页面第一次加载时。回流变化涉及到部分页面(或整个页面)的布局。一个元素的回流导致其所有子元素以及DOM中紧随其后的祖先元素和其子元素都发生回流。
执行顺序 先回流后重绘
————————————————
CSS预处理器:sass、less
Sass&Less是什么?
Less (Leaner Style Sheets 的缩写) 是一门向后兼容的 CSS 扩展语言。因为 Less 和 CSS 非常像,Less 仅对 CSS 语言增加了少许方便的扩展,学习很容易。
最重要一点:Less支持变量
sass,作为”世界上最成熟、最稳定、最强大的专业级CSS扩展语言”。兼容所有版本的css,且有无数框架使用sass构建,如Compass,Bourbon,和Susy。
相同之处:
Less和Sass在语法上有些共性,比如下面这些:
1、混入(Mixins)——class中的class;
2、参数混入——可以传递参数的class,就像函数一样;
3、嵌套规则——Class中嵌套class,从而减少重复的代码;
4、运算——CSS中用上数学;
5、颜色功能——可以编辑颜色;
6、名字空间(namespace)——分组样式,从而可以被调用;
7、作用域——局部修改样式;
8、JavaScript 赋值——在CSS中使用JavaScript表达式赋值。
两者异同:
1、Less在JS上运行,Sass在Ruby上使用。
Sass基于Ruby,需要安装Ruby。Less和Sass在Ruby中构建相似,但它已被移植到JavaScript中。为了使用LESS,我们可以将适用的JavaScript文件上载到服务器或通过脱机编译器编译CSS表。
2、编写变量的方式不同。
Sass使用$,而Less使用@。
3、在Less中,仅允许循环数值。
在Sass中,我们可以遍历任何类型的数据。但在Less中,我们只能使用递归函数循环数值。
4、Sass有Compass,Less有Preboot
Sass和LESS有可用于集成mixins的扩展(在整个站点中存储和共享CSS声明的能力)。
Sass有适用于mixins的Compass,其中包括所有可用的选项以及未来支持的更新。
LESS有Preboot.less,LESS Mixins,LESS Elements,gs和Frameless。LESS的软件支持比Sass更加分散,导致许多不同的扩展选项可能不会以相同的方式运行。对于项目,我们可能需要所有列出的扩展以获得与Compass类似的性能。
描述下 “reset” CSS 文件的作用和使用它的好处。
因为浏览器的品种很多,每个浏览器的默认样式也是不同的,所以定义一个css reset可以使各浏览器的默认样式统一。
使用 CSS 预处理器的优缺点有哪些?(SASS,Compass,Stylus,LESS) 描述下你曾经使用过的 CSS 预处理的优缺点。
缺点:简单来说CSS预处理器语言较CSS玩法变得更高级了,但同时降低了自己对最终代码的控制力。更致命的是提高了门槛,首先是上手门槛,其次是维护门槛,再来是团队整体水平和规范的门槛。这也造成了初学学习成本的昂贵。
优点:用一种专门的编程语言,为CSS增加了一些编程的特性,将CSS作为目标生成文件,然后开发者就只要使用这种语言进行编码工作。通俗的说,CSS预处理器用一种专门的编程语言,进行Web页面样式设计,然后再编译成正常的CSS文件,以供项目使用。CSS预处理器为CSS增加一些编程的特性,无需考虑浏览器的兼容性问题,例如你可以在CSS中使用变量、简单的逻辑程序、函数等等在编程语言中的一些基本特性,可以让你的CSS更加简洁、适应性更强、可读性更佳,更易于代码的维护等诸多好处。
Javascript部分
ECMA-262标准为ECMAScript提供核心语言功能,比如:语法、关键字、保留字和操作符等;
ECMAScript是JavaScript的核心,规定了JS的语法规范
DOM(文档对象模型)是一组用来描述脚本怎样与结构化文档进行交互和访问的web标准。
BOM即浏览器对象模型,它提供了独立于内容而与浏览器窗口进行交互的对象,其核心对象是window
Defer
Javascript中defer的作用是文档加载完毕了再执行脚本,这样会避免找不到对象的问题,延缓执行。
Async:
与defer属性相似,都用于改变外部脚本的行为,并告诉浏览器立即下载脚本文件。但与def不同的是标记为async的属性并不保证它们的执行顺序(谁先加载完就先执行谁)。
闭包
闭包的理解:
闭包就是能够读取其他函数内部变量的函数,或者子函数在外调用,子函数所在的父函数的作用域不会被释放
闭包的弊端:由于调用后变量不会自动清除,然后就会导致内存泄漏、一些空间的浪费以及性能消耗等问题。
解决方法:将变量指向null,清楚变量
闭包的作用:
1.匿名自执行函数(创建了一个匿名的函数,并立即执行它,由于外部无法引用它内部的变量,因此在函数执行完后会立刻释放资源,关键是不污染全局对象。)
2.结果缓存(变量不会自动释放,结果得到缓存)
3.封装
4.实现类和继承
结合实际案例:
https://blog.csdn.net/u011086209/article/details/88858277
原型链
对象上有这么一个属性:__proto__,它是对象独有的属性,可以看成__proto__属性都是由一个对象指向一个对象,即指向他们的原型对象(也可以理解为父对象)
原型链的理解以及__proto__的作用:
当访问一个对象的属性时,如果该对象没有这个属性,那个就会沿着该对象__proto__属性所指向的对象(可以理解为父对象)里面找,如果父对象没有这个属性,则会沿着父对象__proto__属性所指向的对象里面找,如果还是没有,就会继续往上找,直到原型链顶端null,null继续往上找相当于给null赋值,会报错,所以null已经是原型链的顶端。
JS的垃圾回收机制 GC(garbage collection)
面试怎么回答
1)问什么是垃圾
一般来说没有被引用的对象就是垃圾,就是要被清除, 有个例外如果几个对象引用形成一个环,互相引用,但根访问不到它们,这几个对象也是垃圾,也要被清除。
2)如何检垃圾
一种算法是标记-清除算法,另一种是引用计数(主要用在IE游览 器)
一些优化:
分代回收——对象分为两组:“新对象”和“旧对象”。许多对象出现,完成它们的工作并迅速结 ,它们很快就会被清理干净。那些活得足够久的对象,会变“老”,并且很少接受检查。
增量回收——如果有很多对象,并且我们试图一次遍历并标记整个对象集,那么可能会花费一些时间,并在执行中会有一定的延迟。因此,引擎试图将垃圾回收分解为多个部分。然后,各个部分分别执行。这需要额外的标记来跟踪变化,这样有很多微小的延迟,而不是很大的延迟。
空闲时间收集——垃圾回收器只在 CPU 空闲时运行,以减少对执行的可能影响。
JS继承的6种方式
1、原型链继承
例如Cat这个类想通过原型链继承Animal这个类,那么就可以new一个空对象,这个空对象指向Animal并且Cat.prototype指向这个空对象,这种就是基于原型链的继承。
Cat.prototype = new Animal();
2、借用构造函数继承(call()、apply()、bind())
function Cat(){
Animal.call(this,"tony");
this.age = '11'
}
console.log(Cat.name); //tony
console.log(Cat.age); //11
console.log(Cat instanceof Animal) //flase
只继承了父类构造函数的属性,没有继承父类原型的属性
3、实例继承
4、拷贝继承
5、组合继承
6、寄生组合式继承
具体内容参考:https://www.cnblogs.com/ranyonsue/p/11201730.html
前端性能优化:DOM操作性能优化建议
其实在web开发中,单纯因为js导致性能问题的很少,主要都是因为DOM操作引起的。
1查找元素的优化
2改变DOM,包括添加,修改,删除DOM
3改变DOM的样式类等
4批量修改DOM
5减少iframe
6样式放在header中,脚本放在关闭标签之前
前端模块化
就是复杂的文件编程一个一个独立的模块,比如js文件等等,分成独立的模块有利于重用(复用性)和维护(版本迭代),这样会引来模块之间相互依赖的问题,所以有了commonJS规范,AMD,CMD规范等等,以及用于js打包(编译等处理)的工具webpack
前端模块规范
有三种:CommonJs,AMD和CMD。
CommonJs用在服务器端,AMD和CMD用在浏览器环境
AMD 是 RequireJS 在推广过程中对模块定义的规范化产出。
CMD 是 SeaJS 在推广过程中对模块定义的规范化产出。
AMD:提前执行(异步加载:依赖先执行)+延迟执行
CMD:延迟执行(运行到需加载,根据顺序执行)
var、let、const 的区别及实现原理
一、var声明的变量会挂载在window上,而let和const声明的变量不会
var a =100;
console.log(a,window.a);// 100 100
let b =10;
console.log(b,window.b);// 10 undefined
const c =1;
console.log(c,window.c);// 1 undefined
二、var声明变量存在变量提升,let和const不存在变量提升
console.log(a);// undefined ===>JS进行预解析, a已声明还没赋值,默认得到undefined值
var a =100;
console.log(b);// 报错:b is not defined ===> 找不到b这个变量
let b =10;
console.log(c);// 报错:c is not defined ===> 找不到c这个变量
const c =10;
三、let和const声明形成块作用域,而var不存在此作用域
if(1){
vara =100;
let b =10;
const c =1;
}
console.log(a);// 100
console.log(b)// 报错:b is not defined ===> 找不到b这个变量
console.log(c)// 报错:c is not defined ===> 找不到c这个变量
四、同一作用域下let和const不能声明同名变量,而var可以
var a =100;
console.log(a);// 100
var a =10;
console.log(a);// 10
let a =100;
let a =10;// 报错:Identifier 'a' has already been declared ===> 标识符a已经被声明
五、let和const定义的变量是存在暂时性死区的,而var没有
暂时性死区:let、const定义的变量不存在变量提升,没有进行初始化,访问将会报错
var a =100;
if(1){
a =10;
//在当前块作用域中存在a使用let/const声明的情况下,给a赋值10时,只会在当前作用域找变量a,
// 而这时,还未到声明时候,所以控制台Error:a is not defined
let a =1;
}
let和const基本相同,但是如果const定义的是常量,那么const定义的是只读变量,也就是说不能改变,但是注意!!!!仅限于常量!!!例如定义一个Pi,不可改变值,并且一定要进行赋值处理。
const obj = {};
obj.name = '111';
console.log(obj.name);//111 const声明变量是可以改变的;
const pi = 3.1315926;
pi =1; //报错,常量不可改变
const a;//报错 const a = 1; //正确
经典笔试题:
for(var i=0;i<5;i++){ setTimeout(()=>{ console.log(i);
//5个5
},100) }
console.log(i);//5
console.log('=============')
for(let j=0;j<5;j++){ setTimeout(()=>{ console.log(j);
//0,1,2,3,4 },
100) }
console.log(j);//报错 j is not defined
原因:setTimeout是个异步函数,它会在循环结束后再执行,第一个循环中的i用var声明,因此是个全局变量,当循环结束时,i=10,就会输出10个10.第二个循环的j是用let声明的,在每次循环中,setTimeout里的j都是独立的(局部作用域),因此输出0-9.
var:函数作用域;存在变量提升;可重复定义;声明的变量会作为window的属性。
let:块级作用域;不存在变量提升(有暂时性死区);不可重复定义;声明的变量不会作为window的属性。
全局作用域:
不在任何函数内定义的变量
函数作用域:
在函数体内定义的变量就叫做函数作用域,外层作用域可以调用内层作用域(这里指不超出函数范围)
函数作用域中的变量可能会覆盖全局作用域中的变量,
也会将变量泄露成全局变量
块作用域:
ES5没有块作用域,一般在{}花括号内,外层作用域不能调用内层作用域变量,内层作用域可以声明外层作用域的同名变量。
例如:
function a()
{ let a = 5;
if(true){ let a = 10; }
console.log(a) ; // 5; 内部作用域无法访问外部作用域,但是换成var就可以
}
let的原理:let是es6语法,经babel打包后会加上_,避免复用,例如let i = 0 会转变成var _i = 0
const的原理:object.defineproperty里面的writeable属性
vue2的原理:Object.defineProperty 的 getter 和 setter(数据双向绑定)
vue3的原理:proxy(代理)
vue2和vue3的区别:
1.使用了 proxy 替代 Object.defineProperty
Vue 的反应系统是使用 Object.defineProperty 的 getter 和 setter。 但是,Vue 3 使用 ES2015 Proxy 作为其观察者机制。Proxy 对象用于定义基本操作的自定义行为, Proxy 不仅可以代理对象,还可以代理数组,还可以代理动态增加的属性,节省内存,速度加倍。
2.diff算法的改进:
例如:vue2diff算法中,div标签,AST树形式下他的text和method是分开的,而vue3AST树形式下div标签的text、method是合并的。diff算法改进,AST树优化,变得更加简便,能够更快遍历,并且只遍历那些需要修改的部分,没有修改的不会被遍历,减少性能消耗。
3.新增 hook api
4.更好的ts支持,vue 3 直接用 ts 重写 (TypeScript)
AST(抽象语法树)
前言
抽象语法树(AST)是源代码的抽象语法结构的树状表示,树上的每个节点都表示源代码中的一种结构,构成一个虚拟DOM节点
转换成AST形式:
constructor有什么作用
constructor 属性返回对创建此对象的数组函数的引用。
var test=new Array();
if (test.constructor==Array)
{
document.write("This is an Array");
}
if (test.constructor==Boolean)
{
document.write("This is a Boolean");
}
if (test.constructor==Date)
{
document.write("This is a Date");
}
if (test.constructor==String)
{
document.write("This is a String");
}
输出:
This is an Array
arguments:代表参数
详情浏览:https://blog.csdn.net/zjy_android_blog/article/details/80934042
JS计算中:0.1+0.2为什么不等于0.3?
原因:JS计算是二进制存储,当十进制计算的时候精度会缺失,就像10进制无法精确1/3,而三进制中1/3就是0.1
==和===、以及Object.is的区别:
当进行双等号比较时候: 先检查两个操作数数据类型,如果相同, 则进行===比较, 如果不同, 则愿意为你进行一次类型转换, 转换成相同类型后再进行比较, 而===比较时, 如果类型不同,直接就是false.
Object.is()是ES6新增的用来比较两个值是否严格相等的方法,与===的行为基本一致。
==:
主要存在:强制转换成number,null==undefined
" "==0 //true
"0"==0 //true
" " !="0" //true
123=="123" //true
null==undefined //true
Object.is:
主要的区别就是
+0!=-0
NaN==NaN
NaN是number类型
数组的常用方法:
https://blog.csdn.net/qq_39408204/article/details/89468377?ops_request_misc=%257B%2522request%255Fid%2522%253A%2522159041040019195265906335%2522%252C%2522scm%2522%253A%252220140713.130102334.pc%255Fall.%2522%257D&request_id=159041040019195265906335&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2~all~first_rank_v2~rank_v25-1-89468377.first_rank_v2_rank_v25&utm_term=%E6%95%B0%E7%BB%84%E5%B8%B8%E7%94%A8%E6%96%B9%E6%B3%95
JS中强制类型转换为number类型的方法有:parseInt()、parseFloat()、number()。
创建一个子节点___createElement(),插入一个节点_appendChild() __,在已有元素之前插入节点__insertbefore(),删除字节点_____removeChild()。
获取元素的第一个子节点__firstNode___________________,获取元素的最后一个子节点__lastNode______________,上一个兄弟节点____previousSibling_________________,下一个兄弟节点__________nextSibling___________。
————————————————
常用运算符有那五大类_____算术运算符___、逻辑运算符______、关系运算符________、赋值运算符_、比较运算符_______。
把字符串按照指定字符分割并返回数组的方法为:splice(‘|’);
大写字母转小写字母的方法为:toLowerCase();
小写字母转大写字母的方法为:toUpperCase();
查询字符在字符串中位置的方法_indexof(‘a’);
返回指定位置字符串的方法charAt(3)。
转换成字符串:toString() //参数可填进制,进行进制转换 ,null和undefined没有toString()方法
不确定转换值是否是null或者undefined:String() //进行转换
还可以:
Object:
有x=15,y=64,写出生成x到y直接随机数的方法:Math.Random()*49+15。
JS中的多次执行的定时器为:setInterval(function(){},1000);
只执行一次的定时器为:setTimeout(function(){},1000);
清除定时器的方法:clearInterval(timer) clearTimeout(timer)。
获取滚动条滚动高度的方法:
__对象.onscroll = function(){ console.log(this.scrollTop)}。
JS中绑定事件的方法:对象.fn;
解除事件绑定的方法________________对象.onclick = null___。
对数字向上取整的方法:Math.ceil()___;向下取整的方法:Math.floor();四舍五入的方法:Math.round()。
对JSON 的了解?
参考答案
JSON(JavaScript Object Notation) 是一种轻量级的数据交换格式。它是基于JavaScript的一个子集。数据格式简单, 易于读写, 占用带宽小。
1{"age":"12", "name":"back"}
js延迟加载的方式有哪些?
参考答案
1. defer和async
没有 defer 或 async,浏览器会立即加载并执行指定的脚本,“立即”指的是在渲染该 script 标签之下的文档元素之前,也就是说不等待后续载入的文档元素,读到就加载并执行。
有 async,加载和渲染后续文档元素的过程将和 script.js 的加载与执行并行进行(异步)。
有 defer,加载后续文档元素的过程将和 script.js 的加载并行进行(异步),但是 script.js 的执行要在所有元素解析完成之后,DOMContentLoaded 事件触发之前完成。
2. 动态创建DOM方式(创建script,插入到DOM中,加载完毕后callBack)
3. 按需异步载入js
Javascript的事件流模型都有什么?
“事件冒泡”:事件开始由最具体的元素接受,然后逐级向上传播
“事件捕捉”:事件由最不具体的节点先接收,然后逐级向下,一直到最具体的
“DOM事件流”:三个阶段:事件捕捉,目标阶段,事件冒泡
什么是Ajax和JSON,他们的优缺点?
Ajax是异步JavaScript和XML,用于在Web页面中实现异步数据交互。
优点:
可以使得页面不重载全部内容的情况下加载局部内容,降低数据传输量
避免用户不断刷新或者跳转页面,提高用户体验
缺点:
对搜索引擎不友好(
要实现ajax下的前后退功能成本较大
可能造成请求数的增加
跨域问题限制
JSON是一种轻量级的数据交换格式,ECMA的一个子集
优点:轻量级、易于人的阅读和编写,便于机器(JavaScript)解析,支持复合数据类型(数组、对象、字符串、数字)
java script中变量的命名规则:
1.变量只可以由字母、数字组成。如:name,a1,、_组成。如:name,a1,、
组成。如:name,a1,money,stu_name;
2.变量区分大小写。如student和Student为两个不同的变量;
3.变量不能以数字开头。如123name为非法变量,会报错;
4.变量名不能是ES规则中的关键字或保留字。
5.虽然没有硬性要求,但再实际工作中一般采用驼峰命名法。如:showTime,deptNo。
————————————————
js的typeof返回哪些数据类型?
typeof arguments // object
返回值为:object
arguments是对象,不是真正的数组,它是一个伪数组,是可以使用方括号和整数索引的元素。通常利用Array的原型方式将其转换为数组。
你都使用哪些工具来测试代码的性能?
Profiler, JSPerf(http://jsperf.com/nexttick-vs-setzerotimeout-vs-settimeout), Dromaeo
请谈一下你对网页标准和标准制定机构重要性的理解?
(google)w3c存在的意义就是让浏览器兼容性问题尽量小,首先是他们对浏览器开发者的约束,然后是对开发者的约束。
什么是 FOUC(无样式内容闪烁)?你如何来避免 FOUC?
FOUC – Flash Of Unstyled Content 文档样式闪烁
而引用CSS文件的@import就是造成这个问题的罪魁祸首。IE会先加载整个HTML文档的DOM,然后再去导入外部的CSS文件,因此,在页面DOM加载完成到CSS导入完成中间会有一段时间页面上的内容是没有样式的,这段时间的长短跟网速,电脑速度都有关系。
解决方法简单的出奇,只要在
之间加入一个或者元素就可以了。doctype(文档类型)的作用是什么?你知道多少种文档类型?
此标签可告知浏览器文档使用哪种 HTML 或 XHTML 规范。
该标签可声明三种 DTD 类型,分别表示严格版本、过渡版本以及基于框架的 HTML 文档。
HTML 4.01 规定了三种文档类型:Strict、Transitional 以及 Frameset。
XHTML 1.0 规定了三种 XML 文档类型:Strict、Transitional 以及 Frameset。
Standards (标准)模式(也就是严格呈现模式)用于呈现遵循最新标准的网页
Quirks(包容)模式(也就是松散呈现模式或者兼容模式)用于呈现为传统浏览器而设计的网页。
生成时间戳的三种方法?
1. var time = Date.parse(new date())
2. var time = (new date()).valueOf()
3. var time = (new date()).getTime()
阻止事件默认行为和事件冒泡的方法是什么
默认行为:event.preventDefault();
冒泡:
jq: event.stopPropregation();
IE: event.cancelBubble();
foo = foo || bar ,这行代码是什么意思?为什么要这样写?
foo和bar应该都是bool型变量,||是表示 或 的意思,只要foo或者bar有一个为真,那么这个表达式的值就为真,并把它赋给foo
如何判断一个数组(讲到typeof差点掉坑里)
参考回答:
Object.prototype.toString.call()
instanceof
你说到typeof,能不能加一个限制条件达到判断条件
参考回答:
typeof只能判断是object,可以判断一下是否拥有数组的方法
简历中提到了requestAnimationFrame,请问是怎么使用的
参考回答:
requestAnimationFrame() 方法告诉浏览器您希望执行动画并请求浏览器在下一次重绘之前调用指定的函数来更新动画。该方法使用一个回调函数作为参数,这个回调函数会在浏览器重绘之前调用。
window.requestAnimationFrame(callback);
字符串和数组的相互转化
ES6新特性:
https://blog.csdn.net/weixin_43307658/article/details/86698281?ops_request_misc=%257B%2522request%255Fid%2522%253A%2522159046117619726869007005%2522%252C%2522scm%2522%253A%252220140713.130102334.pc%255Fall.%2522%257D&request_id=159046117619726869007005&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2~all~first_rank_v2~rank_v25-1-86698281.first_rank_v2_rank_v25&utm_term=es6%E6%96%B0%E7%89%B9%E6%80%A7%E7%94%A8%E8%BF%87%E5%93%AA%E4%BA%9B
ES6之扩展运算符(。。。)
对象中的扩展运算符(...)用于取出参数对象中的所有可遍历属性,拷贝到当前对象之中
1.对象同名会覆盖
可用于去重:return [...new Set(arr)]
可用于求大小:Math.max(...arr)
前端入门16-JavaScript进阶之EC和VO
https://www.cnblogs.com/dasusu/p/10071326.html
什么是Virtual Dom?
所谓的 virtual dom,也就是虚拟节点。它通过 JS 的 Object 对象模拟 DOM 中的节点,然后再通过特定的 render 方法将其渲染成真实的 DOM 节点。
webpack用来干什么的
参考回答:
webpack 是一个现代 JavaScript 应用程序的静态模块打包器(module bundler)。当 webpack 处理应用程序时,它会递归地构建一个依赖关系图(dependency graph),其中包含应用程序需要的每个模块,然后将所有这些模块打包成一个或多个bundle。
js原型链,原型链的顶端是什么?Object的原型是什么?Object的原型的原型是什么?在数组原型链上实现删除数组重复数据的方法
原型链顶端是Object.prototype
Object的原型是Object.prototype
Object.prototype.__proto__ === null,Object.prototype没有原型
事件捕获
捕获型事件(event capturing):事件从最不精确的对象(document 对象)开始触发,然后到最精确(也可以在窗口级别捕获事件,不过必须由开发人员特别指定)
事件冒泡
冒泡型事件:事件按照从最特定的事件目标到最不特定的事件目标(document对象)的顺序触发。
————————————————
JS的作用域类型:
一般认为的作用域是词法作用域,此外JS还提供了一些动态改变作用域的方法,常见的作用域类型有:
函数作用域,如果在函数内部我们给未定义的一个变量赋值,这个变量会转变成为一个全局变量,
块作用域:块作用域吧标识符限制在{}中
for in 取 key; for of 取 value
for of 只能用于数组遍历,for in还可以用于对象属性的遍历,还能遍历对象原型上可枚举的属性,但是不能进行几何运算
for-in不保证迭代的顺序,for of保证迭代的顺序,使用的时候需要在对象的原型上添加一个迭代器属性
for……in遍历数组的问题
1.index索引为字符串型数字,不能直接进行几何运算
2.遍历顺序有可能不是按照实际数组的内部顺序
3.使用for in会遍历数组所有的可枚举属性,包括原型。例如上栗的原型方法method和name属性
所以for in更适合遍历对象,不要使用for in遍历数组。
记住,for in遍历的是数组的索引(即键名),而for of遍历的是数组元素值。
for of遍历的只是数组内的元素,而不包括数组的原型属性method和索引name
作用域链
当代码在一个环境中执行时,会创建变量对象(VO)的一个作用域链(scope chain,简称sc)来保证对执行环境(执行上下文)有权访问的变量和函数的有序访问。
什么是预加载
资源预加载是另一个性能优化技术,我们可以使用该技术来预先告知浏览器某些资源可能在将来会被使用到。预加载简单来说就是将所有所需的资源提前请求加载到本地,这样后面在需要用到时就直接从缓存取资源。
数组扁平化:https://blog.csdn.net/sinat_17775997/article/details/88786357?ops_request_misc=%257B%2522request%255Fid%2522%253A%2522159089313419195162520561%2522%252C%2522scm%2522%253A%252220140713.130102334..%2522%257D&request_id=159089313419195162520561&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2~all~first_rank_v2~rank_v28-1-88786357.pc_insert_v2&utm_term=%E6%95%B0%E7%BB%84%E6%89%81%E5%B9%B3%E5%8C%96
Promise
https://blog.csdn.net/q121516340/article/details/100127549?ops_request_misc=%257B%2522request%255Fid%2522%253A%2522159089601319724843313336%2522%252C%2522scm%2522%253A%252220140713.130102334..%2522%257D&request_id=159089601319724843313336&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2~all~first_rank_v2~rank_v28-1-100127549.pc_insert_v2&utm_term=%E9%9D%A2%E8%AF%95promise
Ajax的过程:
1.创建一个XMLHttpRequest异步对象
2.创建一个Http请求,包含请求方法、url、验证信息
3.设置响应http请求状态变化的函数
4.发送http请求
5.接受异步调用返回的数据
6.利用Javascript和dom操作对页面进行局部更新
通常浏览器缓存策略分为两种:强缓存和协商缓存,并且缓存策略都是通过设置 HTTP Header 来实现的。
typeof null == object
不同的对象在底层都表示为二进制,在 JavaScript 中二进制前三位都为 0 的话会被判
断为 object 类型, null 的二进制表示是全 0,自然前三位也是 0,所以执行 typeof 时会返回“ object
Promise中错误是如何处理的
通过try catch扩展作用域捕获错误,再通过订阅发布者模式来调用回调函数。
发布者-订阅者模式又称观察者模式:当一个对象(发布者)状态发生改变时,所有依赖它的对象(订阅者)都会得到通知
如何串行执行多个Promise。
reduce、
使用async + 循环 + await、
使用新出的for await of
for await of和for of规则类似,只需要实现一个内部[Symbol.asyncIterator]方法即可
怎么获得对象上的属性:比如说通过Object.keys()
参考回答:
从ES5开始,有三种方法可以列出对象的属性
for(let I in obj)该方法依次访问一个对象及其原型链中所有可枚举的类型
object.keys:返回一个数组,包括所有可枚举的属性名称
object.getOwnPropertyNames:返回一个数组包含不可枚举的属性
箭头函数是没有this和arguments变量的
sort方法的原理:sort使用的是插入排序和快速排序结合的排序算法
JSONP原理
ajax请求受同源策略影响,不允许进行跨域请求,而script标签src属性中的链接却可以访问跨域的js脚本,利用这个特性,服务端不再返回JSON格式的数据,而是返回一段调用某个函数的js代码,在src中进行了调用,这样实现了跨域。
Virtual DOM和diff算法 概念理解
vdom是虚拟DOM(Virtual DOM)的简称,指的是用JS模拟的DOM结构,将DOM变化的对比放在JS层来做。换而言之,vdom就是JS对象。
为什么用VDOM
采用JS对象模拟的方法,将DOM的比对操作放在JS层,减少浏览器不必要的重绘,提高效率。
所谓diff算法,就是用来找出两段文本之间的差异的一种算法。
DOM操作是非常昂贵的,因此我们需要尽量地减少DOM操作。这就需要找出本次DOM必须更新的节点来更新,其他的不更新,这个找出的过程,就需要应用diff算法。
Vue
什么是生命周期:
从Vue实例创建、运行、到销毁期间,总是伴随着各种各样的事件,这些事件,统称为生命周期!
[生命周期钩子]( https://cn.vuejs.org/v2/api/ #选项-生命周期钩子):就是生命周期事件的别名而已;
生命周期钩子 = 生命周期函数 = 生命周期事件
主要的生命周期函数分类:
- 创建期间的生命周期函数:
+ beforeCreate:实例刚在内存中被创建出来,此时,还没有初始化好 data 和 methods 属性
+ created:实例已经在内存中创建OK,此时 data 和 methods 已经创建OK,此时还没有开始 编译模板
+ beforeMount:此时已经完成了模板的编译,但是还没有挂载到页面中
+ mounted:此时,已经将编译好的模板,挂载到了页面指定的容器中显示
- 运行期间的生命周期函数:
+ beforeUpdate:状态更新之前执行此函数, 此时 data 中的状态值是最新的,但是界面上显示的 数据还是旧的,因为此时还没有开始重新渲染DOM节点
+ updated:实例更新完毕之后调用此函数,此时 data 中的状态值 和 界面上显示的数据,都已经完成了更新,界面已经被重新渲染好了!
- 销毁期间的生命周期函数:
+ beforeDestroy:实例销毁之前调用。在这一步,实例仍然完全可用。
+ destroyed:Vue 实例销毁后调用。调用后,Vue 实例指示的所有东西都会解绑定,所有的事件监听器会被移除,所有的子实例也会被销毁。
————————————————
在vue中computed是计算属性,主要作用是把数据存储到内存中,减少不必要的请求,还可以利用computed给子组件的data赋值。
Vue 响应系统,其核心有三点:observe、watcher、dep:
observe:遍历 data 中的属性,使用 Object.defineProperty 的 get/set 方法对其进行数据劫持;
dep:每个属性拥有自己的消息订阅器 dep,用于存放所有订阅了该属性的观察者对象;
watcher:观察者(对象),通过 dep 实现对响应属性的监听,监听到结果后,主动触发自己的回调进行响应。
vue.js的两个核心是什么?
数据驱动和组件化。
v-show与v-if的区别
v-show相当于css里面的display:none;
v-if是相当于直接删除
相比之下,v-if更适合条件不经常改变的场景,因为它切换开销相对较大,而v-show适用于频繁切换条件。
为什么vue data一定是一个函数:
object是一个引用类型,如果不用函数私有化data,data存放在同一个地址,当data改变时候,所以组件引用的data都会改变,data会共享。
Computer与Watch区别:
https://blog.csdn.net/zhouzy539/article/details/96340814
watch适用于一对多的场景,比如搜索框
watch:{
a(newname.oldname){}
}
computed适用于多对一的 场景,比如购物车
computed:{
newA:function(){
retrun this.a
}
}
computed有缓存
Mixin
实现多个组件可以共享数据和方法
Mixin的应用场景
比如项目中多处的view层使用到下拉刷新以及自动加载功能,处理这些相同的逻辑,每一个view层都要写一遍是浪费生命的。这种情况就很适合使用mixin。
Mixin对于封装一小段想要复用的代码来讲是有用的,Mixin的优点是不需要传递状态,但缺点也显而易见可能会被滥用
例如富文本编译按钮获取内容的时候,可以利用Mixin
是Vue的内置组件,能在组件切换过程中将状态保留在内存中,防止重复渲染DOM。
如何减少长列表的渲染时间:
1.我们可以通过 object.freeze 方法来冻结一个对象,这个对象一旦被冻结,vue就不会对数据进行劫持了。
2.懒计算和缓存,避免重复计算。
3.使用纯组件(pure component)来避免重渲染。
4.可视区域渲染,需要的本分渲染出来,不需要隐藏,表现为分页。
5.改变数据进行dom
hash:有# , history:去除#
Webpack除了压缩还有其他什么功能吗?
web可以将js、css甚至图片模块化
webpack另一个重要功能就是翻译,许多浏览器不支持ES6,webpack可以将ES6翻译成ES5进行使用
Promise.all 功能:
Promise.all(iterable)返回一个新的Promise实例,此实例在iterable参数内素有的Promise都fulfilled或者参数中不包含Promise时,状态变成fulfilled。 如果参数中Promise有一个失败rejected ,此实例回调失败,失败原因的是第一个失败Promise的返回结果
var p1 = Promise.resolve(1);
var p2 = 2;
var p3 = new Promise((resolve, reject) => {
setTimeout(resolve, 100, '3');
})
Promise.all([p1, p2, p3]).then(values => {
console.log(values)
})
常见的数据结构:
数组 (Array)
栈 (Stack)
堆 (Heap)
队列 (Queue)
链表 (Linked List)
树 (Tree)
图 (Graph)
散列表 (Hash)
数据结构是指相互之间存在一种或多种特定关系的数据元素的集合
EXT.JS
ext写的页面,由items加xtype构成
ExtJS是一个Ajax框架,是一个用JavaScript写的,用于在客户端创建丰富多彩的web应用程序界面。
好处,封装的非常好,常见的组件该有都有,基本上不会去写css和html而是使用模版,缺点:框架太老,社区太小,知道的人不多。
Extjs控件的生命周期大体分为三个阶段:初始化、渲染、销毁
enabled、
disable、
beforeshow、
show、
beforehide、
hide、
beforerender、
render、
beforedesctory、
destory 事件
EXTJS的组件体系中有进40种组件,而这些组件又可以大致分成三大类,即基本组件、工具栏组件、表单及元素组件。
基本组件常用的有box、button、container等
工具栏组件常用有toolbar、tbbutton等
表单及元素组件:form、checkbox、radio
EXTJS常见布局:
最常用的边框布局——BorderLayout
最简单的布局——FitLayout
制作伸缩菜单的布局——Accordion
实现操作向导的布局——CardLayout
控制位置和大小的布局——AbsoluteLayout
表单专用的布局——FormLayout
分列布局——ColumnLayout
表格状布局——TabelLayout
BoxLayout——HBox
BoxLayout——VBox
————————————————
路由 通过监听地址栏hash值变化
前端项目优化:代码,外观
代码优化:
有公共的复用的地方抽取
多写注释,代码可读性要强
用es6规整代码
使用less等css预处理器翻新
尽量少操作dom
体验方面优化:
用webpack压缩代码
用css精灵图方式去优化图片资源,精灵图就是把很多的小图片合并到一张较大的图片里
减少http请求
数据量大的时候做分页,避免一次性请求过多
正则表达式
用于匹配规律规则的表达式
正则表达式中/i,/g,/ig,/gi,/m的区别和含义
/i (忽略大小写)
/g (全文查找出现的所有匹配字符)
/m (多行查找)
/gi(全文查找、忽略大小写)
/ig(全文查找、忽略大小写)
什么时候需要用vuex
当你需要共享一些数据,以及组件的时候,可以将数据和组件抽离出来,例如购物车,修改一处地方,全局都会修改。
为什么说vue是轻量级的框架
轻不是指他的文件、包轻,而是指vue是一个渐进式框架,vue的原理是数据双向绑定,vue2是基于object.defineProperty里面的getter和setter,vue3是用proxy取代,vue框架避免了对dom的直接操作,对文件影响很轻,所以才说vue是轻量级的框架。
vue中直接写this. xxx是怎么更新UI界面的?(数据绑定原理)
vue的原理是数据双向绑定,vue2是基于object.defineproperty,vue3则是用proxy取代监听,当写this.xxx,修改数据的时候,就会被监听到并回调更新到UI界面上。
js怎么实现继承
js继承有许多种方式,主要有原型链继承
Webpack打包原理:
webpack 是一个现代 JavaScript 应用程序的静态模块打包器(module bundler)。当 webpack 处理应用程序时,它会递归地构建一个依赖关系图(dependency graph),其中包含应用程序需要的每个模块,然后将所有这些模块打包成一个或多个bundle.js,通过代码分割成单元片段并按需加载。
webpack打包过程
1.从配置文件中找到entry point
2. 解析模块系统
3. 解决依赖
4. 解决依赖管理(读取,解析,解决)
5. 合并所有使用的模块
6. 合并模块系统的运行时环境
7. 产生打包后的文件
渐进增强与优雅降级
1.什么是渐进增强
在网页开发中,渐进增强认为应该专注于内容本身。一开始针对低版本的浏览器构建页面,满足最基本的功能,再针对高级浏 览器进行效果,交互,追加各种功能以达到更好用户体验,换句话说,就是以最低要求,实现最基础功能为基本,向上兼容。以css为例,以下这种写法就是渐进增强。
2.什么是优雅降级
在网页开发中,优雅降级指的是一开始针对一个高版本的浏览器构建页面,先完善所有的功能。然后针对各个不同的浏览器进行测试,修复,保证低级浏览器也有基本功能 就好,低级浏览器被认为“简陋却无妨 (poor, but passable)” 可以做一些小的调整来适应某个特定的浏览器。但由于它们并非我们所关注的焦点,因此除了修复较 大的错误之外,其它的差异将被直接忽略。也就是以高要求,高版本为基准,向下兼容。同样以css为例,优雅降级的写法如下。
css平常依据什么工具解决兼容性问题:caniuse
https://blog.csdn.net/webxuexi168/article/details/104502021/?biz_id=102&utm_term=css%E5%B9%B3%E5%B8%B8%E4%BE%9D%E6%8D%AE%E4%BB%80%E4%B9%88%E5%B7%A5%E5%85%B7%E8%A7%A3%E5%86%B3%E5%85%BC%E5%AE%B9%E6%80%A7%E9%97%AE%E9%A2%98&utm_medium=distribute.pc_search_result.none-task-blog-2~all~sobaiduweb~default-0-104502021&spm=1018.2118.3001.4187
说一下什么是virtual dom
虚拟dom节点指的是javascript用对象结构对dom数的描述,然后利用diff检测虚拟dom节点和dom树,然后通过调用patch函数比较虚拟dom和dom树返回最新值,进而更新dom树,减少性能消耗。虚拟dom节点其实是javascript和DOM树直接的一个缓存。
diff:用来比较两个文件或者目录之间的差异。
setTimeout(function() {
console.log(1)
}, 0);
new Promise(function(resolve, reject) {
console.log(2)
for (var i = 0; i < 10000; i++) {
if(i === 10) {console.log(10)}
i == 9999 && resolve();
}
console.log(3)
}).then(function() {
console.log(4)
})
console.log(5);
输出答案为2 10 3 5 4 1
执行顺序为:同步执行的代码-》promise.then->settimeout
ie 各版本和 chrome 可以并行下载多少个资源
参考答案
1. IE6 2 个并发
2. iE7 升级之后的 6 个并发,之后版本也是 6 个
3. Firefox,chrome 也是6个
1em就等于16px。
Javascript里面的继承怎么实现,如何避免原型链上面的对象共享:
Javascript实现继承的方式有很多,一般是原型链继承、利用构造函数继承,然后原型链继承与利用构造函数继承结合,能够避免原型链上面的对象共享,许多前端框架都有封装extend()函数,达到这个效果,原理是利用一个空对象作为中间变量。
什么时候用到闭包
1.防抖节流的时候:防抖节流会生成很多变量,为了避免这些变量污染全局变量,使用闭包特性可以避免变量污染全局环境。
2.迭代的时候,利用闭包保存结果,进行下一次迭代。
防抖节流:
函数防抖:高频事件触发时候,在n秒内执行一次,但是再次触发时候,时间重新计算;
函数节流:高频时间触发时候,在n秒内执行一次,但是再次触发时候,n秒只能执行,时间不重新计算;
两者区别:函数防抖是防止重复触发,一定时间内不断的重复触发他会不执行,函数节流是稀释触发次数。
https://blog.csdn.net/zuorishu/article/details/93630578?ops_request_misc=%257B%2522request%255Fid%2522%253A%2522159654073419725247611829%2522%252C%2522scm%2522%253A%252220140713.130102334..%2522%257D&request_id=159654073419725247611829&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2~all~first_rank_ecpm_v3~pc_rank_v2-1-93630578.first_rank_ecpm_v3_pc_rank_v2&utm_term=js+%E9%98%B2%E6%8A%96&spm=1018.2118.3001.4187
浏览器渲染过程?
浏览器输入url,浏览器主进程接管,开一个下载线程,
然后进行 http请求(略去DNS查询,IP寻址等等操作),然后等待响应,获取内容,
随后将内容通过RendererHost接口转交给Renderer进程
解析html建立dom树
解析css构建render树(将CSS代码解析成树形的数据结构,然后结合DOM合并成render树)
布局render树(Layout/reflow),负责各元素尺寸、位置的计算
绘制render树(paint),绘制页面像素信息
浏览器会将各层的信息发送给GPU,GPU会将各层合成(composite),显示在屏幕上。
prototype和__proto__的关系是什么:
function是对象,function的原型prototype也是对象,他们都有共有的特征,即__proto__,我们称之为隐式原型,没个对象都会初始化这样一个属性,当访问该对象属性的时候,如果该对象上没有属性,就会沿着__proto__所指向的对象往上找,我们把这个对象叫做父对象,如果父对象也没有,同样沿着父对象的__proto__所指向的对象往上着,我们将这个不断往上着的过程称之为原型链继承,最顶端为null,当找到这里会报错。
Node.js 的适用场景
参考答案
1. 高并发
2. 聊天
3. 实时消息推送
viewport的原理:
移动端浏览器通常都会在一个比移动端屏幕更宽的虚拟窗口中渲染页面,这个虚拟窗口就是viewport; 目的是正常展示没有做移动端适配的网页,让他们完整的展示给用户;
meta viewport 标签的作用是:
让当前viewport的宽度等于设备的宽度,同时不允许用户进行手动缩放
域名发散和域名收敛是什么:
Ie6浏览器能够同时发送2个并发请求,IE7以及其他浏览器,例如chrome、火狐,能够同时发送6个并发请求。
域名发散
域名发散就是为了突破浏览器对于同一域名并发请求数的限制,使用域名发散为同一个服务申请多个域名,从而可以一定程度上提高并发量;当然,由于建立新的请求需要一定的代价,因此需要在域名发散与域名收敛间进行trade off,通常发散的域名个数为2-4个;
域名收敛
域名收敛就是将静态资源放在一个域名下不进行发散,这主要是为了适应移动端的发展需求;通常DNS是一个开销较大的操作,而移动端由于网络带宽和实时性、资源等的限制,这些开销对移动端的用户体验是致命的,因此需要进行域名收敛;
float和display:inline-block的区别是什么:
float使元素浮动,display:inline-block是使元素容器行内元素特性,内容块状元素特性。
共同点:都可以设置宽高,会自动填充父元素,然后自动换行。
不同点:float使元素脱离文本流,display:inline-block没有,float默认顶部对齐,display:inline-block默认最高的内容为行高,不会自动补空。
前端优化策略列举:自己描述
首屏、白屏时间如何计算:
首屏指的是页面完全展示
1.正常加载页面时候
首屏时间等于:点8-点1,html内容完全渲染出来时候的时间减去一开始渲染的时间
2.后台直入,自带内容
首屏时间等于:点4-点1,html内容渲染出来时候的时间减去一开始渲染的时间,这里的html页面渲染是在js渲染之前
解释一下作用域和作用域链:
个人理解:作用域就是一个执行上下文,也就是执行环境,例如一个function里面,就是一个块级作用域,然后作用域链就是当在作用域调用变量,你不知道变量值是什么,那么Js运行机制就会自动往父级作用域里面找,例如function里面的作用域父级作用域就是它的外层,window对象,也有可能存在嵌套情况,作用域包含作用,window对象的执行环境永远是最后的执行环境,也就是,window作用域没找变量,这个变量就会报错。
ajax如何实现,readyState的五种状态的含义:
1.创建一个XMLHttpRequest异步对象
2.创建一个http请求,包含请求方式,url,验证信息
3.创建一个响应http请求状态变化的处理函数
4.发送http
5.接受异步调用返回的信息
6.利用javascript和dom操作根据返回的信息对页面进行局部更新
readyState状态码:
0 :未初始化,但是已经声明xhr对象
1:调用了open()函数
2:调用send()函数,但是服务端没有响应
3:正在接受服务端响应回来的信息
4 : 完成响应。
jsonp如何实现:
受同源机制影响,浏览器不能实现跨域,跨域是指调用其他浏览器的js脚本,但是src能够访问其他浏览器的js脚本,基于这个原理,服务端返回一段调用某一函数的js代码,通过src进行访问,进而实现跨域。
vue的双向绑定的原理,和angular的对比
angular的双向绑定原理是通过脏值检测来监控树脂的变化情况,而vue2是通过object.defineProperty里面的getter和setter属性对数据进行劫持监听,vue3则通过proxy代替监听,不仅能监听对象,还能监听数组。
vue slot是做什么的:
插槽(Slot)是Vue提出来的一个概念,正如名字一样,插槽用于决定将所携带的内容,插入到指定的某个位置,从而使模板分块,具有模块化的特质和更大的重用性。插槽显不显示、怎样显示是由父组件来控制的,而插槽在哪里显示就由子组件来进行控制
一般用于:父子通信
Vue里面router-link在电脑上有用,在安卓上没反应怎么解决
Vue路由在Android机上有问题,babel问题,安装babel polypill插件解决。
vue与react的对比,如何选型?从性能,生态圈,数据量,数据的传递上,作比较
https://blog.csdn.net/scarsun/article/details/81636535?ops_request_misc=%257B%2522request%255Fid%2522%253A%2522159657823519726869008794%2522%252C%2522scm%2522%253A%252220140713.130102334.pc%255Fall.%2522%257D&request_id=159657823519726869008794&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2~all~first_rank_ecpm_v3~pc_rank_v2-1-81636535.first_rank_ecpm_v3_pc_rank_v2&utm_term=vue%E4%B8%8Ereact%E7%9A%84%E5%AF%B9%E6%AF%94%2C%E5%A6%82%E4%BD%95%E9%80%89%E5%9E%8B%EF%BC%9F%E4%BB%8E%E6%80%A7%E8%83%BD%EF%BC%8C%E7%94%9F%E6%80%81%E5%9C%88%EF%BC%8C%E6%95%B0%E6%8D%AE%E9%87%8F%EF%BC%8C&spm=1018.2118.3001.4187
谈一谈this的指向问题!!!!!
详细浏览一下网页
https://blog.csdn.net/lxcao/article/details/52750575?ops_request_misc=%257B%2522request%255Fid%2522%253A%2522159667302619724848333717%2522%252C%2522scm%2522%253A%252220140713.130102334.pc%255Fall.%2522%257D&request_id=159667302619724848333717&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2~all~first_rank_ecpm_v3~pc_rank_v2-1-52750575.first_rank_ecpm_v3_pc_rank_v2&utm_term=%E5%89%8D%E7%AB%AF%E4%B8%8D%E5%90%8C%E5%9C%BA%E5%90%88this%E7%9A%84%E7%90%86%E8%A7%A3&spm=1018.2118.3001.4187
Vuex具体步骤以及方法区别了解一下
JS操作中改变原数组方式:
pop():删除 arrayObject 的最后一个元素,把数组长度减 1,并且返回它删除的元素的值。如果数组已经为空,则 pop() 不 改变数组,并返回 undefined 值。arrayObject.pop()
*push():*push() 方法可把它的参数顺序添加到 arrayObject 的尾部。它直接修改 arrayObject,而不是创建一个新的数组,arrayObject.push(newelement1,newelement2,….,newelementX)
reverse():该方法会改变原来的数组,而不会创建新的数组。arrayObject.reverse()
shift():数组的第一个元素从其中删除,并返回第一个元素的值,如果数组是空的,那么 shift() 方法将不进行任何操作.
sort():对数组的引用。请注意,数组在原数组上进行排序,不生成副本。arrayObject.sort(sortby) (如果调用该方法时没有使用参数,将按字母顺序对数组中的元素进行排序,说得更精确点,是按照字符编码的顺序进行排序。要实现这一点,首先应把数组的元素都转换成字符串(如有必要),以便进行比较。
如果想按照其他标准进行排序,就需要提供比较函数,该函数要比较两个值,然后返回一个用于说明这两个值的相对顺序的数字。比较函数应该具有两个参数 a 和 b,其返回值如下:
若 a 小于 b,在排序后的数组中 a 应该出现在 b 之前,则返回一个小于 0 的值。
若 a 等于 b,则返回 0。
若 a 大于 b,则返回一个大于 0 的值。)
*splice():*splice() 方法可删除从 index 处开始的零个或多个元素,并且用参数列表中声明的一个或多个值来替换那些被删除的元素。
如果从 arrayObject 中删除了元素,则返回的是含有被删除的元素的数组
arrayObject.splice(index,howmany,item1,…..,itemX)
unshift():unshift() 方法可向数组的开头添加一个或更多元素,并返回新的长度。arrayObject.unshift(newelement1,newelement2,….,newelementX)返回arrayObject 的新长度
不改变原数组:
concat():用于连接两个或多个数组,仅会返回被连接数组的一个副本,arrayObject.concat(arrayX,arrayX,……,arrayX)
join():返回一个字符串。该字符串是通过把 arrayObject 的每个元素转换为字符串,然后把这些字符串连接起来,arrayObject.join(separator)
slice():如果数组是空的arrayObject.slice(start,end)
其他:
*toSource()*toSource() 方法表示对象的源代码。
该原始值由 Array 对象派生的所有对象继承。
toSource() 方法通常由 JavaScript 在后台自动调用,并不显式地出现在代码中。object.toSource()
toString():arrayObject 的字符串表示。返回值与没有参数的 join() 方法返回的字符串相同arrayObject.toString()
toLocaleString():把数组转换为本地字符串。arrayObject.toLocaleString()
valueOf():valueOf() 方法返回 Array 对象的原始值。
该原始值由 Array 对象派生的所有对象继承。
arrayObject.valueOf()
slice和splice在字符串的区别
splice不能用于数组,slice可以