# 海豚科技 (一面 60min)
介绍自己
由于说到了vue,对比下vue和react的区别
生态,指令,虚拟dom,diff等
vue的渲染过程,从1.0到2.0大概说了下。
1.0的每个{{}}对象一个watcher,到2.0的每个组件一个watcher,然后后数据劫持到Proxy
有没有其他方案实现数组的劫持
Vue的mixins,和react的高阶组件
React的hooks
如果react组件想要复用逻辑如果处理
React高阶组件
React组件之间的数据传递
父子组件,跨层组件,Context,Event Bus
Redux connect干了什么
dva的数据流图
介绍Webpack
实现一个less-loader
JS原型,原型链
new的原理
判断对象的类型的几种方法
type
对于数组、函数、对象来说,其关系错综复杂,使用 typeof 都会统一返回 “object” 字符串,
null也会返回’object’
对NaN返回是’number’
var x = [] var y = {} var z =null var a console.log( typeof 'aaa') // string console.log( typeof 123) // number console.log( typeof true) // boolean console.log( typeof a) // undefined console.log( typeof b) // undefined 未声明也是 undefined console.log( typeof x) // object 数组也是对象 但是用typeof 不能检测出是数组 console.log( typeof y) // object
instanceof
instanceof 用来判断 instanceof 前的 数据 是否 为 instanceof 后的类型 返回一个布尔值 同样不用加() 但是instanceof只能用来检测对象
var x = [] var y = {} var z = null var a = 'aaa' console.log(x instanceof Object) //true 数组也是对象 console.log(x instanceof Array) //true console.log(y instanceof Object) //true console.log(y instanceof Array) //false 但数组不一定是对象 console.log(z instanceof Object) //false 用instanceof检测空对象 也是检测不出来的
constructor
constructor 是通过原型链进行查找的 可以用来查找对象和普通数据 相比于 instanceof 和 typeof 会更加精准
var x = [] var y = {} var z = Date() var a = 'aaa' console.log(x.constructor==Object) //false 在这里 数组并不被识别成对象 console.log(x.constructor==Array) //true console.log(y.constructor==Object) //true console.log(a.constructor==String) //true 字符串可以正常被识别 console.log(z.constructor==Object) //false 时间对象也不被识别成对象 console.log(z.constructor==Date) // true
Object.prototype.toString()
Object.prototype.toString() 是Object原型的方法 相比于以上三个 更加精准
var x = [] var y = {} var z = new Date() var a = 'aaa' console.log(Object.prototype.toString.call(x)) //[object Array] console.log(Object.prototype.toString.call(y)) //[object Object] console.log(Object.prototype.toString.call(z)) //[object Date] console.log(Object.prototype.toString.call(a)) //[object String]
如何改变一个对象的原型链
call,apply,bind。改变构造函数
说说闭包,有什么好处,有什么坏处
说说垃圾回收机制
了解electron吗
近期在学习什么
复习,ssr,vite2
双向链表和单向链表的结构
了解哪些设计模式
浏览器缓存策略
说说浏览器的渲染流程
javascript会阻塞渲染,这个时候怎么做
了解哪些性能优化
- 缓存
- react的shouldComponentUpdate
- redux数据缓存
- webpack生成的js大小分析
Event loop,以及node中的event loop
对pc端,移动端,桌面应用的看法
# 佳华物链云
# 基础类型,引用类型
堆,栈,栈空间,先入后出。
栈(stack)中主要存放一些基本类型的变量和对象的引用,(包含**池,**池存放常量 ),其优势是存取速度比堆要快,并且栈内的数据可以共享,但缺点是存在栈中的数据大小与生存期必须是确定的,缺乏灵活性,
先进后出,后进先出原则,所以 push 优于 unshift
堆(heap)用于复杂数据类型(引用类型)分配空间,例如数组对象、object对象;它是运行时动态分配内存的,因此存取速度较慢。
# 闭包
什么是垃圾回收机制?它是怎么工作的?
那就要知道什么是垃圾,垃圾就是没有被引用的对象,或者是几个对象相互引用形成一个闭环,但是从根上访问不到也是垃圾.他们就会被清除.
标记-清除
1.垃圾回收器获取根并标记他们
2.然后垃圾回收器访问并标记所有来自根的引用
3.然后垃圾回收器访问被标记的对象,并标记他们的引用,防止二遍访问
4.重复上面的步骤直到出现未被标记的引用出现
5.最后删除所有未被标记的对象
什么是根?
根就是一组基本的可达值,他们不会被删除
1.全局变量
2.本地函数的参数和变量
3.当前在调用链上的其他函数的参数和变量
什么是可达值
可达值是js内存管理里最主要的概念,他就是指以某种方式可访问或可调用的一些值,它会被保存在内存中
什么是闭包
闭包就是函数套函数
在闭包里面,内部的函数可以访问到外部函数作用域内的变量,但是外部的函数不能访问内部函数作用域内的变量
function a() {
var num = 0;
function b() {
console.log(++num);
};
return b;
};
var c = a();
c() // 1
c() //2
以前不明白为什么它会每次递加,因为a函数被存进了变量c 他是全局变量,不会被垃圾回收机制回收, 下次再调用C()的时候c的值在内存中保存,所以每次都是在原有的基础上加一
function two() {
var a = 1;
return function() {
a++;
console.log(a);
};
};
two() //2
two() //2
因为这个函数执行完 就销毁了,下次在调用的时候又是一次新的调用跟一起没有关系,所以无论调多少次都是2
为什么闭包不会被回收
因为他本身就是建立在一个函数的内部作用域的子函数,由于可访问上级作用域的原因,即使上级函数执行完,作用域也不会被清除,这时子函数,就是闭包,就拥有了访问上级作用域中变量的权限,即使上级函数执行完,作用域内的值也不会被销毁
使用闭包时,按照作用域链的特点,闭包(函数)外面的变量不会被销毁,因为函数会一直被调用,所以一直存在,如果闭包使用过多会造成内存销毁。
# 词法分析,语义分析
# JS内存回收机制
现在各大浏览器通常用采用的垃圾回收有两种方法:标记清除、引用计数。
标记清除
这是javascript中最常用的垃圾回收方式。当变量进入执行环境是,就标记这个变量为“进入环境”。从逻辑上讲,永远不能释放进入环境的变量所占用的内存,因为只要执行流进入相应的环境,就可能会用到他们。当变量离开环境时,则将其标记为“离开环境”。
引用计数
引用计数的含义是跟踪记录每个值被引用的次数。当声明了一个变量并将一个引用类型赋值给该变量时,则这个值的引用次数就是1。相反,如果包含对这个值引用的变量又取得了另外一个值,则这个值的引用次数就减1。当这个引用次数变成0时,则说明没有办法再访问这个值了,因而就可以将其所占的内存空间给收回来。这样,垃圾收集器下次再运行时,它就会释放那些引用次数为0的值所占的内存。
内存溢出
内存溢出一般是指执行程序时,程序会向系统申请一定大小的内存,当系统现在的实际内存少于需要的内存时,就会造成内存溢出
内存溢出造成的结果是先前保存的数据会被覆盖或者后来的数据会没地方存
内存泄漏
内存泄漏是指程序执行时,一些变量没有及时释放,一直占用着内存 而这种占用内存的行为就叫做内存泄漏。
作为一般的用户,根本感觉不到内存泄漏的存在。真正有危害的是内存泄漏的堆积,这会最终消耗尽系统所有的内存。从这个角度来说,一次性内存泄漏并没有什么危害,因为它不会堆积。
内存泄漏如果一直堆积,最终会导致内存溢出问题
# meta
width=device-width :表示宽度是设备屏幕的宽度 initial-scale=1.0:表示初始的缩放比例 minimum-scale=0.5:表示最小的缩放比例 maximum-scale=2.0:表示最大的缩放比例 user-scalable=yes:表示用户是否可以调整缩放比例
# margin重叠
边界重叠: 是指两个或多个盒子(可能相邻也可能嵌套)的相邻边界(其间没有任何非空内容、补白、边框)重合在一起而形成一个单一边界。
两个或多个块级盒子的垂直相邻边界会重合。结果的边界宽度是相邻边界宽度中最大的值。
外边距(margin)重叠示例
外边距重叠是指两个垂直相邻的块级元素,当上下两个边距相遇时,外边距会产生重叠现象,且重叠后的外边距,等于其中较大者。
同理,如果一个无内容的空元素,其自身上下边距也会产生重叠。
外边距重叠的意义
外边距的重叠只产生在普通流文档的上下外边距之间,这个看起来有点奇怪的规则,其实有其现实意义。设想,当我们上下排列一系列规则的块级元素(如段落P)时,那么块元素之间因为外边距重叠的存在,段落之间就不会产生双倍的距离。
防止外边距重叠解决方案:
外层元素padding代替
外层元素 overflow:hidden;
内层元素绝对定位 postion:absolute:
内层元素 加float:left;或display:inline-block;
内层元素padding:1px;
内层元素透明边框 border:1px solid transparent;
# BFC
BFC(Block Formatting Context)格式化上下文,是Web页面中盒模型布局的CSS渲染模式,指一个独立的渲染区域或者说是一个隔离的独立容器。
- BFC就是一种布局方式,可以理解为一个作用范围,即在一个BFC里的布局与其之外的布局不相关或者说不相互影响。
形成条件
1、浮动元素,float 除 none 以外的值;
2、定位元素,position(absolute,fixed);
3、display 为以下其中之一的值 inline-block,table-cell,table-caption;
4、overflow 除了 visible 以外的值(hidden,auto,scroll);
特性
1. 内部的Box会在垂直方向上一个接一个的放置;
2. 垂直方向上的距离有margin决定。(完整的说法是:属于同一个BFC的两个相邻的Box的margin会发生重叠,与方向无关)
3. 每个盒子的左外边框紧挨着包含块的左边框(从右到左的格式,则为紧挨右边框),即使浮动元素也是如此。(这说明BFC中的子元素不会超出它的包含块)
4. BFC的区域不会与float的元素区域重叠
5. 计算BFC的高度时,浮动子元素也参与计算;
6. BFC就是页面上的一个隔离的独立容器,容器里面的子元素不会影响到外面的元素,反之亦然;
# webpack AST
# async修饰的方法,返回的什么
Promise对象
# Promise优缺点
缺点
1、无法取消Promise,一旦新建它就会立即执行,无法中途取消。
2、如果不设置回调函数,promise内部抛出的错误,不会反应到外部。
3、当处于pending状态时,无法得知目前进展到哪一个阶段(刚刚开始还是即将完成)。
优点
解决回调地狱(Callback Hell)问题
更好地进行错误捕获
Q: then、catch 和 finally 序列能否顺序颠倒?
A: 可以,效果完全一样。但不建议这样做,最好按 then-catch-finally 的顺序编写程序。
Q: 除了 then 块以外,其它两种块能否多次使用?
A: 可以,finally 与 then 一样会按顺序执行,但是 catch 块只会执行第一个,除非 catch 块里有异常。所以最好只安排一个 catch 和 finally 块。
Q: then 块如何中断?
A: then 块默认会向下顺序执行,return 是不能中断的,可以通过 throw 来跳转至 catch 实现中断。
Q: 什么时候适合用 Promise 而不是传统回调函数?
A: 当需要多次顺序执行异步操作的时候,例如,如果想通过异步方法先后检测用户名和密码,需要先异步检测用户名,然后再异步检测密码的情况下就很适合 Promise。
Q: Promise 是一种将异步转换为同步的方法吗?
A: 完全不是。Promise 只不过是一种更良好的编程风格。
Q: 什么时候我们需要再写一个 then 而不是在当前的 then 接着编程?
A: 当你又需要调用一个异步任务的时候。