js面试题目之连续赋值
图解经典面试题之连续赋值
1 | var a=b={n: 1}; |

图解经典面试题之连续赋值
1 | var a=b={n: 1}; |

1、DNS解析
2、TCP连接
3、发起http请求
4、服务器处理http请求
5、服务器响应http请求
6、浏览器渲染页面
7、连接结束
输入网址,浏览器并不知道要去哪里找资源,需要DNS递归查询对应IP
前端内容繁复,平时难免会碰到一些奇奇怪怪或者暂时无法理解的问题,所以特开此文将这些问题记录下来。
问题描述:移动端的屏幕适配问题,至今没有想明白是什么原因
出现场景:移动端App webview内。
复现步骤:刚开始手机字体大小为正常,打开页面后将App切后台,调整手机字体大小到最大,即出现这种情况。理论上webview内部不应该受到系统字体的影响,在原生中将该功能禁用即可。但是奇怪的是根元素的字体大小确实设置为18px,最终计算出来的字体大小却是27px。
html中已经禁止了页面缩放,但是并没有效果。
1 | <meta name="viewport" content="user-scalable=no, initial-scale=1, maximum-scale=1, minimum-scale=1, width=device-width" /> |

解决方案:计算最后放大了多少倍,同比缩小:
为了提高代码设计水平,测试是必不可少的。jest是facebook出的一个测试框架,里面自带断言库,而且VUE有个Vue Test Utils提供了官方支持,因此这里使用jest构建VUE单元测试部分。开始前建议先浏览一下官方网站,进行初步了解。
新建一个文件夹,然后执行:
1 | npm init |
这就安装好了,接下来写一个简单的函数:

然后在你的项目文件夹下执行jest, 就会自动搜索所有.test.js和.spec.js文件进行测试。
接着我们改一下目录,增加一个SRC文件夹,里面放着我们的原文件,然后新建test文件夹,将测试文件全部放进去
在demo.test.js中添加代码:
1 | // demo.test.js |
前端适配是个麻烦事。PC端要适配不同浏览器,移动端又要适配各种屏幕。而这一切的根源,要从「设备像素」和「逻辑像素」这对概念说起。
设备像素(Device Pixel)是屏幕的物理像素,一块屏幕出厂时就固定的发光点数量。比如 iPhone 8 是 750 × 1334 像素,这是硬件决定的,改不了。
逻辑像素(CSS Pixel / Logical Pixel)是我们写代码时用的像素。CSS 里的 width: 375px 指的就是逻辑像素。
为什么会有两套像素系统?因为手机屏幕太小了,如果 1px CSS 对应 1 个物理像素,文字和按钮会小到看不清。所以苹果在 iPhone 4 上提出了 Retina 概念,用一个逻辑像素对应多个物理像素。
DPR 就是设备像素与逻辑像素的比值:
1 | DPR = 设备像素 / 逻辑像素 |
常见的 DPR 值:
| 设备 | 逻辑分辨率 | 物理分辨率 | DPR |
|---|---|---|---|
| iPhone SE / 6/7/8 | 375 × 667 | 750 × 1334 | 2 |
| iPhone 12 Pro | 390 × 844 | 1170 × 2532 | 3 |
| MacBook Pro Retina | 1440 × 900 | 2880 × 1800 | 2 |
| 普通 1080p 显示器 | 1920 × 1080 | 1920 × 1080 | 1 |
DPR = 1 时,一个 CSS 像素就是一个物理像素;DPR = 2 时,一个 CSS 像素由 2×2 个物理像素渲染,所以画面更细腻。
异步编程是JS中必备的一部分。由于JS是单线程,如果全部事件都顺序执行会阻塞进程。所以一些耗时较长的事件采用异步方式进行。这里记录一些《深入浅出Node.js》笔记,有些地方没有碰到过,不理解,后续完善。
1 | try { |
现在有一个异步方法:
1 | const async = function (callback) { |
这里调用async()方法只能捕获async方法的异常,但是回调callback的异常却无法捕获
多线程语言容易发生的一个问题是线程之间状态不同步。比如有两个线程A和B,A线程要对一个资源进行删除操作,B线程要对一个资源进行修改操作,这时候两个线程容易发生冲突。JS是单线程语言,貌似不会发送这种情况,但是真的如此吗?请看下面这个情况,这是在处理公司业务时碰到的,具体代码无法透漏:
本地状态需要跟服务器状态同步,并且采取轮询策略。同时本地又是可以一直操作的,所以如果网络延迟就会产生图中的情况,本地数据会一直跳变。
这时可以借用多线程之间互斥锁的思想,将过程简化如下:
简化之后,就发现本地操作和服务端操作两个线程要对UI这个资源同时进行操作,所以需要加个互斥锁,本地操作时禁止服务端进行操作,本地操作完成并且收到服务端的回调才解锁。
总结:多线程事件如框架组件内部数据更新、git协作开发等合作事件,最重要的是找出共享资源,理清楚操作方和他们之间的关系,再进行工作协调,保证每次只有一方在操作共享资源,保证所有状态同步。
二叉树是最常见的数据结构之一,很多复杂问题(二叉搜索树、堆、Trie)都是在二叉树基础上扩展的。本文总结二叉树的核心操作和常见题型。
遍历是二叉树最基本的操作,分为深度优先(DFS)和广度优先(BFS)两大类。
1 | function preorder(root) { |
1 | function inorder(root) { |
《JS高级程序设计》中说JS的继承有原型链、构造函数、组合式、原型式、寄生式、寄生组合式继承,加上ES6的class继承,一共有7种方式。前6种最关键的是搞清楚构造函数、原型对象、原型链的关系,其他模式都是这些的组合。
构造函数也是函数,跟普通函数的没什么区别,但是可以用new()方法创建实例
e.g.
1 | function Animal(name, legCount) { |
每个函数都有一个prototype属性(对象没有这个属性),指向一个原型对象,即Animal.prototype( 这玩意是个对象,名字就叫Animal.prototye )
Animal.prototype默认有个constructor属性,这个对象的constructor属性指向该对象对应的构造函数,即Animal()。
1 | console.log(Animal.prototype); |