面试难: 学习/复习/背各种理论知识 ; 看面试技巧/hr常见问题回答方式
1、require和import区别
① require:运行时加载; import:编译时加载(效率更高);
② require:模块就是对象,import:ES6 模块不是对象,而是通过 export 命令显式指定输出的代码,再通过 import 命令输入;
③ require/exports 输出的是一个值的拷贝,import/export 模块输出的是值的引用
2、说说webpack
① 什么是webpack
模块打包机:它做的事情是,分析你的项目结构,找到JavaScript模块以及其它的一些浏览器不能直接运行的拓展语言(Scss,TypeScript等),并将其转换和打包为合适的格式供浏览器使用。
入口 entry: 告诉 webpack 从哪个文件开始构建,这个文件将作为 webpack 依赖关系图的起点;
出口 output: 告诉 webpack 在哪里输出 构建后的包、包的名称 等;
loader : loader 可以将所有类型的文件转换为 webpack 能够处理的有效模块(webpack 自身只理解 JavaScript)
plugin:可以处理各种任务,从打包优化和压缩,一直到重新定义环境中的变量
3、说说浏览器工作模式
第一步:处理输入;在浏览器的地址栏输入内容按下回车时,UI thread会判断输入的内容是搜索关键词(search query)还是URL,如果是搜索关键词,跳转至默认搜索引擎对应都搜索URL,如果输入的内容是URL,则开始请求URL;
第二步:开始导航;UI thread将关键词搜索对应的URL或输入的URL交给网络线程Network,网络进程进行一系列诸如DNS寻址,建立TLS连接等操作进行资源请求
第三步:读取响应;network thread接收到服务器的响应后,开始解析HTTP响应报文,然后根据响应头中的Content-Type字段来确定响应主体的媒体类型(MIME Type),如果媒体类型是一个HTML文件,则将响应数据交给渲染进程(renderer process)来进行下一步的工作,如果是 zip 文件或者其它文件,会把相关数据传输给下载管理器
第四步:查找渲染进程;解析HTML生成DOM树、构建Render树 、布局Render树、绘制Render树
4、浏览器兼容问题
前端常见浏览器兼容性问题解决方案
5、前端多终端浏览器兼容
一、浏览器兼容
二、宽高自适应
6、vue生命周期
beforeCreate:创建前
访问不到其他生命周期函数以及data身上的属性
created:创建后(重)
当create生命周期函数执行的时候,会将data以及methods身上所有的属性和方法添加到vm的实例身上; created执行的时候会遍历data身上所有的属性,给这些属性添加一个getter/setter方法; 我们可以在当前生命周期函数中进行前后端数据的请求(发起ajax)
beforeMount 挂载前
当前生命周期函数中添加的属性是没有getter和setter方法的。如果需要拥有的情况则用$set; 当前生命周期函数中是模板和数据还未进行结合
mounted: 挂载后(重)
当前生命周期函数是数据和模板进行相结合,生成了真正的DOM结构; 在当前生命周期函数重我们可以访问到真实的DOM结构; 我们可以在当期生命周期函数中做一些插件的实例化
beforeDestroy: 销毁前(重)
在当前生命周期函数中我们依旧是可以访问到真实的DOM结构,因此我们可以在当前生命周期函数中做事件的解绑,以及监听的移除等操作
destroyed:销毁后
当前生命周期函数中我们无法通过ref来访问到真实的DOM结构了
beforeUpdate:更新前 (多次执行)
新的数据还未和模板进行相结合,因此我们可以在当期生命周期函数中做更新数据的最后修改
updated:更新后 (多次执行)
7、js箭头函数和普通函数的区别
1.this(执行上下文)指向
普通函数中的this:
在简单调用中,非严格模式下,指向window。严格模式下,为undefined;
作为某个对象方法调用时,this指向该对象;
当该普通函数被间接调用时,即:使用call()和apply()方法调用时,this指向call()和apply()第一个参数;
该普通函数被用作构造函数用new关键字构造对象实例时,this指向新建的实例;
箭头函数中的this:
没有自己的this,内部this的值,依赖于外部非箭头函数的this。
2.构造函数
(1)普通函数
普通函数可以作为构造函数来用,用new去新建对象实例。
(2)箭头函数
不能当做构造函数去用,并且,会报错。
3.arguments对象
(1)普通函数
普通函数内部,arguments为特殊的类数组对象。包含了函数被调用时的参数列表。
(2)箭头函数
内部是没有arguments对象,同this一样,依赖于外部非箭头函数。
4.隐式return
(1)普通函数
用return去返回一个函数的结果。无return语句,或者return后面无表达式,则返回undefined。
(2)箭头函数
如果函数仅有一个表达式,那么该表达式的结果会被隐式返回。
补充一个问题 函数与方法的区别 :方法(method)是通过对象调用的javascript函数。也就是说,方法也是函数,只是比较特殊的函数;
8、call、apply、bind的区别
都是改变 this 指向
call:参数是一个一个的形式; b.call(a,1,2)
apply: 第二个参数必须是一个数组; b.apply(a,[10,1]);
bind: 传参和call一样,返回的是函数;c = b.bind(a); c();
call和apply都是改变上下文中的this并立即执行这个函数,bind方法可以让对应的函数想什么时候调就什么时候调用,并且可以将参数在执行的时候添加,这是它们的区别,根据自己的实际情况来选择使用
9、vue计算属性和普通函数的区别
计算属性是基于他们的依赖进行缓存的,只有在相关依赖发生改变时,他们才会重新求值,也就是说,只要他的依赖没有发生变化,那么每次访问的时候计算属性都会立即返回之前的计算结果,不再执行函数
10、computed和watch区别
computed(计算属性)
1、computed是计算属性,也就是依赖某个值或者props通过计算得来得数据;
2、 computed的值是在getter执行之后进行缓存的,只有在它依赖的数据发生变化,会重新调用getter来计算;
3、 不支持异步,当computed内有异步操作时无效,无法监听数据的变化;
watch(监听器)
1、watch是监听器,可以监听某一个数据,然后执行相应的操作;
2、不支持缓存,数据变直接会触发相应的操作;
3、监听的函数接收两个参数,第一个参数是最新的值;第二个参数是输入之前的值;
4、支持异步操作;
当多个属性影响一个属性的时候,建议用computed;
当一个值发生变化之后,会引起一系列的操作,这种情况就适合用watch;
11、 var、let、const的区别
var定义的变量,没有块的概念,可以跨块访问, 不能跨函数访问。
let定义的变量,只能在块作用域里访问,不能跨块访问,也不能跨函数访问。
const用来定义常量,使用时必须初始化(即必须赋值),只能在块作用域里访问,而且不能修改;
(const只是一个指针,指向一个内存空间,内存空间的内容可以改变,但是const指向一个新的空间就会报错)
补充:if语句和for语句属于块作用域,不属于函数作用域
12、关于闭包
闭包的概念: 闭包就是能够读取其他函数内部变量的函数;
闭包的用途: 一个是前面提到的可以读取函数内部的变量,另一个就是让这些变量的值始终保持在内存中;
使用闭包的注意点:
① 由于闭包会使得函数中的变量都被保存在内存中,内存消耗很大,所以不能滥用闭包,否则会造成网页的性能问题,在IE中可能导致内存泄露。解决方法是,在退出函数之前,将不使用的局部变量全部删除;
② 闭包会在父函数外部,改变父函数内部变量的值。所以,如果你把父函数当作对象(object)使用,把闭包当作它的公用方法(Public Method),把内部变量当作它的私有属性(private value),这时一定要小心,不要随便改变父函数内部变量的值;
13、原型与原型链
参考: 详解原型链中的prototype和 proto
基本数据类型:String Number Boolean Null undefined
引用数据类型:Array Object Date Function RegExp 等
prototype 只在 Function 中有,而__proto__则在Function和Object中都有
一个对象 A的__proto__属性指向的那个对象B,B就是 A 的原型对象(或者叫父对象),对象 A 可以使用对象 B 中的属性和方法,同时也可以使用对象 B 的 原型对象C 上的属性和方法,以此递归,就是所谓的原型链
new 操作到底做了什么
栗子:
function Parent(name) { this.name = name }
let p = new Parent('张三')
第一步:Parent 被执行。当使用 new 关键字时,Parent 函数会在 p 的作用域下被执行,所以这里的 this 就是实例p,这样,name,age,hobby三个属性才会被当做 p 的属性被创建,
第二步:将 p.__proto__指向 Parent.prototype,这才是构造函数的精髓所在,所以,p 就继承了 Parent.prototype中的(以及其原型链上的)属性和方法。
14、px、em、rem、 vw/vh的区别
px
1.相对长度单位。相对于显示器屏幕分辨率而言。
2.存在浏览器不兼容问题。
em
1.相对长度单位。相对于当前对象内文本字体尺寸。
2.em值并不是固定的,em会继承父级元素的大小.
3.如果父级设置font-size:20px. 那么1em=20px. 2em=40px;如果父级设置font-size为30px. 1em=30px. 2em=60px.
4.存在容易造成字体设置混乱问题。
rem
1.相对长度单位。相对于根节点html字体大小来计算。任意浏览器默认字体高都是16px.
2.如果html根节点设置字体font-size为100px. 则1em=100px. 2em=200px. 跟父级字体无关。
3.浏览器兼容性比较好。
vw/vh
视窗的宽度/高度。100vh/100vw相当于整个视窗的宽高。
1vh=视窗高度的1%;1vw=视窗宽度的1%
15、前端适配方案
(详情请看雅虎14条性能优化原则)。
(1) 减少http请求次数:CSS Sprites, JS、CSS源码压缩、图片大小控制合适;网页Gzip,CDN托管,data缓存 ,图片服务器。
(2) 前端模板 JS+数据,减少由于HTML标签导致的带宽浪费,前端用变量保存AJAX请求结果,每次操作本地变量,不用请求,减少请求次数
(3) 用innerHTML代替DOM操作,减少DOM操作次数,优化javascript性能。
(4) 当需要设置的样式很多时设置className而不是直接操作style。
(5) 少用全局变量、缓存DOM节点查找的结果。减少IO读取操作。
(6) 避免使用CSS Expression(css表达式)又称Dynamic properties(动态属性)。
(7) 图片预加载,将样式表放在顶部,将脚本放在底部 加上时间戳。
16、前端性能优化
其他杂七杂八
1、网络中使用最多的图片格式有哪些? jpg和png有什么区别?
JPEG,GIF,PNG,最流行的是jpeg格式,可以把文件压缩到最小
区别:
1、jpg是有损压缩格式,png是无损压缩格式。
2、jpg图像没有透明的背景,而png图像可以保留透明的背景。
3、png格式的图片可以编辑,但是jpg格式的图片则不可更改。
4、png与jpg图片相比,png格式的图片更大。
2、简述css盒子模型
一个css盒子从外到内可以分成四个部分:margin(外边距),border(边框),padding(内边距),content(内容)
盒子真正的宽应该是:内容宽度+左右填充+左右边距+左右边框
盒子真正的高应该是:内容高度+上下填充+上下边距+上下边框
补充:box-sizing
content-box :
宽度和高度分别应用到元素的内容框。
在宽度和高度之外绘制元素的内边距和边框。
border-box :
为元素设定的宽度和高度决定了元素的边框盒。
就是说,为元素指定的任何内边距和边框都将在已设定的宽度和高度内进行绘制。
通过从已设定的宽度和高度分别减去边框和内边距才能得到内容的宽度和高度。
inherit: 规定应从父元素继承 box-sizing 属性的值。
例题:
<head>
<style>
div {
height: 200px;
margin: 50px;
background: lightblue;
width: 55%;
}
</style>
</head>
<body>
<div></div>
<div></div>
</body>
此时盒子上下间距为 50px
添加样式 display: inline-block;
此时盒子上下间距为 100px 了