面试题总结

118 阅读12分钟

1.this的使用原则

this的指向:this的指向是根据执行上下文动态决定的。

  • 在简单调用时,this默认指向的是window/global/undefind; 浏览器,node端,严格模式
  • 对象调用时,绑定在对象上
  • 使用call/apply/bind的时候,绑定在指定的参数上
  • 使用new关键字,通过构造函数调用创建对象上
  • 以上三条优先级:new>call/apply/bind>对象调用
  • 使用箭头函数时,根据外层的规则,决定this的指向

2.实现call函数

function called(context){
    const args = Array.prototype.slice.call(arguments,1);
    //用显式调用的方式,进行模拟
    context.fn = this;
    if(context){
        const result = context.fn(...args);
        delete context.fn;
        return result;
    }else{
        return  this(...args)
    }
}

3.什么是闭包

函数嵌套函数,内层函数引用了外层函数作用域下的变量,并且内层函数在全局环境下可以访问,就形成了闭包。当函数的执行时的作用域,没有在原本的作用域内,就形成了闭包。

4.简述JS原型(prototype)与隐式原型(__proto__)的概念

原型

原型的本质是对象,所有的函数都有原型属性prototype

默认情况下,prototype是一个Object对象

prototype中默认包含一个属性:constructor,该属性指向函数对象本身

隐式原型

所有的对象都有隐式原型proto属性

隐式原型是一个对象,指向创建该对象的构造函数的原型prototype

在查找对象成员时,若对象本身没有该成员,则会到隐式原型中查找

隐式原型和原型出现的根本原因:JS没有记录类型的元类型,因此,JS只能通过对象的隐式原型找到创建他的函数的原型,从而确定其类型

5.请简述原型链的理解

链式:prototype本身是对象,因此,他也有隐式原型,指向的规则不变;这样一来,从某个对象出发,依此寻找隐式原型的指向,将形成一个链条,该链条叫做原型链。

优先级:在查找对象成员时,若对象本身没有该成员,则会去原型量中查找

特殊的两个情况:

  • Function的隐式原型指向自己的原型
  • Object原型的隐式原型指向null

6.请编写promiseChain方法,该方法需要具备:

【1】按照顺序执行队列里的异步函数

【2】等待上一条异步执行完毕后,才能执行下一个

【3】需要接受上一个异步函数返回的值

const promisePipe = (proArr, concurrent) => {    if (concurrent > proArr.length) {        return Promise.all(proArr.map(fn => fn())).then((res) => {            console.log(res);        })    };    let _arr = [...proArr];    //100个函数,并发    for (let i = 0; i < concurrent.length; i++) {        let fn = _arr.shift()        run(fn)    }    function run(fn) {        fn().then((res) => {            console.log(res);            if (_arr.length) {                run(_arr.shift())            }        })    }}promisePipe(proArr, 10)

7.手写umd的规范

(function (global, factory) {    if (typeof module === "object" && exports !== "undefind") {        module.exports = factory();    } else if (typeof define === 'function') {        if (define.amd) {            define('[module]', factory)        } else if (define.cmd) {        }    } else {        global = typeof globalThis !== 'undefined' ? globalThis : global        global.module = factory()    }})(this, function () {    return "module";})  

8.AMD和CMD的区别是?

  1. CMD和AMD都是为了javascript 模块化开发的规范
  2. CMD是sea.js推广过程中对模块定义的规范化产出;AMD是require.js推广过程中对模块定义的规范化产出
  3. AMD是异步模块定义的意思,他是一个在浏览器模块开发的规范,由于不是JS原生支持,使用AMD规范进行页面开发时,需要对应的函数库
  4. require.js解决的问题,多个JS文件可以有依赖关系,被依赖的文件需要早于依赖她的文件加载到浏览器,JS加载的时候浏览器停止页面渲染,加载文件越多,页面失去响应时间越长
  5. CMD通用模块定义,是国内发展的,有浏览器实现sea.js,sea.js要解决的问题和require.js一样,只不过模块定义的方式和模块加载时机有所不同
  6. CMD推崇依赖就近,AMD推崇依赖前置

9.stopPropgation 和stopImmediatePropagation 的区别是什么?

.stopPropgation() :会阻止事件继续进行传播,包括捕获和冒泡

.stopImmediatePropagation():不仅会阻止,而且对于多个相同类型的事件的事件监听函数绑定在同一个元素的情况,会在触发时,阻止该元素的其他事件

10.哪些情况会回流或重绘?

  • 改变窗口大小
  • 修改盒模型
  • 增删样式
  • 重构布局
  • 重设尺寸
  • 改变字体
  • 改变文字

11.衡量性能有哪些指标?

(1)FP - first print :首次绘制时间 首次绘制包括了任何用户自定义的背景绘制,它是将第一个像素点绘制到屏幕的时刻,对于应用页面,用户在视觉上首次出现不同于跳转之前的内容时间点,或者说是页面发生第一次绘制的时间点。(2)FCP - first contented print :首次有内容绘制时间 指浏览器完成渲染 DOM 中第一个内容的时间点,可能是文本、图像、SVG或者其他任何元素,此时用户应该在视觉上有直观的感受。(3)FMP - first meaningful print:首次有意义绘制时间 指页面关键元素渲染时间。这个概念并没有标准化定义,因为关键元素可以由开发者自行定义——究竟什么是“有意义”的内容,只有开发者或者产品经理自己了解。 (4)首屏时间 对于所有网页应用,这是一个非常重要的指标。用大白话来说,就是进入页面之后,应用渲染完整个屏幕(未滚动之前)内容的时间。需要注意的是,业界对于这个指标其实同样并没有确切的定论,比如这个时间是否包含屏幕内图片的渲染完成时间。(5)TTI - Time to Interactive:用户可交互时间 顾名思义,也就是用户可以与应用进行交互的时间。(6)TTFB - time for first byte:网络请求耗时 TTFB是发出页面请求到接收到应答数据第一个字节所花费的毫秒数(7)DCL:DomContentLoaded L:DOM onload 总下载时间 页面所有资源加载完成所需要的时间。一般可以统计 window.onload 时间,这样可以统计出同步加载的资源全部加载完的耗时。如果页面中存在较多异步渲染,也可以将异步渲染全部完成的时间作为总下载时间。(8)LCP(Largest Contentful Paint)good - 2.5sec - middle - 4.0 sec - poor 衡量页面的加载体验,它表示视口内可见的最大内容元素的渲染时间。相比 FCP,这个指标可以更加真实地反映具体内容加载速度。比如,如果页面渲染前有一个 loading 动画,那么 FCP 可能会以 loading 动画出现的时间为准,而 LCP 定义了 loading 动画加载后,真实渲染出内容的时间。(9)FID(First Input Delay)首次输入延迟 good - 100ms - middle - 300ms - poor (10)react 18 - 调度器。衡量可交互性,它表示用户和页面进行首次交互操作所花费的时间。它比 TTI(Time to Interact)更加提前,这个阶段虽然页面已经显示出部分内容,但并不能完全具备可交互性,对于用户的响应可能会有较大的延迟。 (11)CLS(Cumulative Layout Shift)good - 0.1- middle - 0.25 - poor 衡量视觉稳定性,表示页面的整个生命周期中,发生的每个意外的样式移动的所有单独布局更改得分的总和。所以这个分数当然越小越好。

12.函数式编程的优势有什么?

  • 表达更加清晰,因为“一切都是函数”,通过函数的合理命名,函数原子的拆分,我们能够一眼看出城西在做什么,以及做的过程
  • 利于复用 因为一切都是函数,函数本身具有天然的复用能力
  • 利于维护,纯函数和幂等性保证同样的输入就有同样的输出,在维护或者调试代码时,能够更加专注,减少因为共享带来的潜在问题

13.写一个函数计算结果的memorize函数

const memorize = (fn)=>{let cacheMap = {}return  function (...args) {    const cacheKey = args.join('_');    if (cacheKey in cacheMap) {        return cacheMap[cacheKey]    }else{        return cacheMap[cacheKey] = fn.apply(this||{},args);    }}}function add(a,b) {    console.log(a,b);    return a+b;}const madd = memorize(add);madd(1,2);madd(1,2);madd(1,2);

14.写一个加法器,满足:add(1)(2) === 3, add(1)(2)(3)(4) === 1

const add = (arg1) => {    let args = [arg1]    const fn = (arg2) => {        args.push(arg2);        return fn;    }    //当我进行判断的时候,我再调用这个方法    fn.toString = function () {        return args.reduce((prev, item) => {            prev + item        }, 0)    }    return fn;}

15.列举如下TS中枚举异构类型的取值分别是?并用js实现双向mapping

enum ENUM{
 A,
 B,
 C = "C",
 D = "D",
 E = 6,
 F
    }

答案:a,0,1,c,d,6,7

let Enum;(function (Enum) {    //正向    Enum["A"] = 0;    Enum["B"] = 1;    Enum["C"] = "C";    Enum["D"] = "D";    Enum["E"] = 6;    Enum["F"] = 7;    //逆向    Enum[0] = "A";    Enum[1] = "B";    Enum[6] = "E";    Enum[6] = "F";}(    Enum || (Enum = {})))

16.type 和interface的异同?

异:

interface描述数据结构,用type描述类型;

interface直接描述数据,type可以进行与或运算;

同:

都是对于数据结构的辅助型描述

17.什么是泛型,泛型的概念

不预先指定数据的类型,使用时再去过程中指定类型的一种方式

例如:

function class <T, U>(name: T, teacher: U) {    return name + teacher}

18.分别用函数对象以及类,定义es,ts两个子类,并让他们同时继承zhaowa类

class Zhaowa {
    constructor(){
}
} 
class Es extends Zhaowa{
    constructor(props){
        super(props)
}
}
class Ts extends Zhaowa{
    constructor(props){
        super(props)
}
}

19.v-if和v-show有什么区别

v-if会确保在切换过程中组件被销毁和重建;同时也是惰性的;如果在初始渲染时条件为假,则什么也不做———直到条件第一次变为真时,才会开始渲染条件块。v-show不管初始条件是什么,元素总是会被渲染,并且只是简单的基于css的“display”属性进行切换

20.简述vue父组件与子组件生命周期的钩子函数执行顺序

Vue的父组件和子组件生命周期钩子函数执行顺序:

  • 加载渲染过程父beforeCreate > 父created>父beforeMount>子beforeCreate>子created>子mounted>父mounted
  • 子组件更新过程 父beforeUpdate > 子beforeUpdate > 子updated >父 updated
  • 父组件更新过程 父beforeUpdate 》父updated
  • 销毁过程父beforeDestroy>子beforeDestroy>子destroyed >父destroyed

21.简述至少五种vue组件间的通信方式

  • props/$emit --用于父子组件之间通信
  • ref/ref/children | $parent --用于指向性通信
  • EventBus --隔代、兄弟等非直接通信
  • attrs/attrs/listener --隔代监听型通信
  • provide/inject --隔代广播等
  • vuex /pinia 整体状态机

22.简述或者手写mixins以及extends的区别和写法

mixins ——混入,就是复制,作用就是减少data、methods、钩子的重复

<template>    <div>        zhaowa    </div></template><script >import log from "../mixins/log.js";export default {    data() {        return {            name: "zhaowa"        };    },    created() {        console.log("zhaowa的created");    },    mixins: [log]};</script>const log = {    data() {        return {            name: undefined,            time: undefined        }    },    created() {        if (!this.name) {            throw new Errow("need name")        }    }}export default log<style lang='' scoped></style>

extends是比mixins更抽象一点的封装,理解为合并混入➕继承

<template>    <div>        Child1    </div></template><script >import MyVue from "../MyVue.js";export default {    data() {        return {            name: "Child1"        }    },    extends: MyVue}</script><style lang='' scoped></style>

23.npm Cl 和install的区别

  1. npm Cl 必须有package-lock.json 文件
  2. 且下载完全依赖该文件
  3. 会删除node_modules
  4. 如果和package.json 冲突,则直接报错
  5. 只能一次性安装
  6. 永不改写package.json 和package-lock.json 文件

24.child_process 有哪几种子线程的方式,区别是什么?

  • spawn :最基础的,其他的方式,都是基于此派生的
  • fock :在源码里加了一个IPC,默认只能走IPC
  • execfile :shell 默认是false,拿不到系统环境,参数是数组
  • exec:shell是true,能拿到系统环境,讲参数进行了格式化

25.写一个发布订阅模式

26.React Native 如何实现对IOS和Android的不同样式

主要可以使用Platform 中相关的特性,比如对于屏幕安全区域,Android默认无原生组件,需要在此处添加相应代码,判断statusBar 的内容;

27.简述至少五种vue 组件间的通信方式

  1. props/$emit 用于父子组件之间通信
  2. ref/ref/children | $parent -用于指向性通信
  3. EventBus -隔代、兄弟等非直接通信
  4. attrs/attrs/listener -隔代等监听型通信
  5. vuex /pinia 整体状态机

28.CSS3有哪些新特性

  1. 新增各种CSS选择器
  2. 圆角(border-raduis)
  3. 多列布局(multi-column layout)
  4. 阴影和反射(shadoweflect)
  5. 文字特效(text-shadow)
  6. 文字渲染(text-decoration)
  7. 线性渐变(gradient)
  8. 旋转(transform)
  9. 增加了旋转,缩放,定位,倾斜,动画,多背景

29.哪些情况会回流或重绘?

  • 改变窗口大小
  • 修改盒模型
  • 增删样式
  • 重构布局
  • 重设尺寸
  • 改变字体
  • 改动文字

30.设计模式的基础分类

  1. 创建型模式:用于创建对象的设计模式。一般可以简化用户创建对象的过程。其次可以降低耦合度,用户不需要关心对象具体的创建过程。包含:单例模式、工厂模式、建造者模式
  2. 结构型模型:组织对象之间的结构。使其易于扩展等。包括:代理模式、适配器模式、装饰器模式
  3. 行为模型:主要用于决定对象如何做出行为,包括:模版方式模式,命令模式,观察者模式,职责模式

31.为何需要通过状态流转的方式切换状态,有何优势和作用

可以规避异步操作同时改变状态的情况发生在actions中,将异步转为同步,保证切换state时都为同步状态切换

32.RN中如何实现下拉刷新

可以使用flatView去实现下拉刷新,上拉加载等功能

33.css中position有几种,什么区别

  • static static为position属性的默认值,在不设置position属性时就是static;元素按照标准流进行排布;对于static,设置left,right,top,bottom是没有任何效果的;
  • relative 元素按照标准流进行排布;定位参照对象是元素自己原来的位置,可以通过left,right,top,bottom来进行位置调整;相对定位应用场景:在不影响其他元素位置的前提下,可以对当前元素位置进行微调;
  • absolute 元素脱离标准流,定位参照对象是最近一级拥有定位的祖先元素,可以通过left,right,top,bottom来进行位置调整;如果一直往上层元素找不到有定位的元素,那么最终的参照对象为视口;拥有定位的祖先元素:position的值不为static的元素;
  • fixed  元素脱离标准流;定位参照对象是视口,可以通过left,right,top,bottom来进行位置调整;当画布滚动时,元素的位置时固定不动的
  • sticky 会在fixed 和relative之间进行切换使用