前端面试 - JS篇

js

数据类型和计算

  1. 值类型和引用类型
  • 常见值类型
    string、num、undefined、boolean、symbol
  • 常见引用类型
    在这里插入图片描述
  • 值类型和引用类型存储区别
    值可以直接存储在栈中,如下
    在这里插入图片描述
    而引用类型存储如下:
    在这里插入图片描述
  • 堆和栈:(这篇文章介绍得很详细了
    栈内存相当于一个水桶类型,入栈顺序先进后出

栈内存存储基本数据类型,堆内存存储引用数据类型
栈内存中自动分配空间和释放,但堆内存中变量不同,具体看下面垃圾回收机制;

  1. 浏览器的垃圾回收机制
  • 引用计数(ie8及之前)
    跟踪变量被引用次数,引用一次+1,释放-1,当引用次数为0时即可回收
    缺点:
    循环引用时会出问题
  • 标记清除(目前主流浏览器使用)
    当变量进入执行环境时,这个变量标记为“进入环境”;而当变量离开环境时,则将其标记为“离开环境”,垃圾回收器销毁并回收那些被标记为“离开环境”的值所占用的内存空间
    缺点:
  • v8垃圾回收策略
    采用分代回收策略,将内存分为新生代和老生代
    新生代空间中的对象为存活时间较短的对象,大多数的对象被分配在这里,这个区域很小但是垃圾回特别频繁
    老生代空间中的对象为存活时间长或常驻内存对象,大多数从新生代晋升的对象会被移动到这里
  1. 实现深拷贝
  • 循环+递归
  • JSON.stringify与JSON.parse结合
function deepClone(obj){
    let _obj = JSON.stringify(obj),
    objClone = JSON.parse(_obj);
    return objClone
}    
let a=[0,1,[2,3],4],
    b=deepClone(a);
a[0]=1;
a[2][0]=1;
console.log(a,b);
  • 函数库lodash
    该函数库有提供 _.cloneDeep 用来做 Deep Copy

  • 借用JQ的extend

let a=[0,1,[2,3],4],
    b=$.extend(true,[],a);
a[0]=1;
a[2][0]=1;
console.log(a,b);
  1. 防抖节流
    防抖是指 一定时间,连续触发,只在最后一次触发
let deBounce = (fn, delay) => {
    let timer = null;
    return function (...args) {
        if (timer) {
            clearTimeout(timer);
        }
 
        timer = setTimeout(()=> {
            fn(...args);
        }, delay)
    }
}

节流是指 时间持续触发时,在一定间隔时间内触发

let throttle = (fn, delay) => {
    let flag = true;
    return function (...args) {
        if (!flag) return;
        flag = false;
        setTimeout(() => {
            fn(...args);
            flag = true;
        }, delay)
    }
}
  1. 类型计算
  • 包含字符串的计算(需注意)
    在这里插入图片描述
let a= '5' - '3';
let c = '' + 1;
let d= false - true;
let e = null + 1;
let f= [] - [];
let g= [] + [];
console.log(a,b,c,d,e,f,g)
  • 类型转成字符串
    String(value);
    ‘’ + value;
    value.toString()

  • 类型转成数字
    Number();
    ‘’ - value;

  • == 和 === 使用
    除了判断null时使用= = ,其他情况都用 ===

  • falsely变量和truely变量(一个变量双重否定后是true或false来判定)(误区:if判断,truely变量即进入if,falsely变量则进入else在这里插入图片描述

  • && 和 ||
    &&返回falsely变量
    ||返回truely变量

  1. 数组、字符串一些常用函数:看这里
  2. 数组去重、扁平化的一些方法

js原型和原型链相关知识(重要)

  1. 类型判断
  • 平常还有哪些其他判断数据类型的方法呢
  • typeof: typeof 1
    可以判断所有的值类型;可判断函数;可判断是否是引用类型(但不能具体分辨那种类型)
  • instanceof(原理,判断前者的_proto_原型链上是否存在后者的prototype原型对象)
    可判断一个变量是否是Array但是需注意:不能判断简单的数据类型。 还有isArray可以判断是否是数组
    [] instanceof Object 结果也是true,所有的引用类型使用instanceof Object都是true
  • (value).constructor.name,多重继承时会出错,在有原型时出错
  • 推荐:object.prototype.toString.call() 返回格式为[Object, 真实类型];(可以检测所有类型,但不能检测自定义的具体类型)
  • 推荐:Array.isArray()
  • jquery.type
  1. 原型和原型链(是我看到最清晰的解释了)

闭包(重要)

  1. es6语法新特性(具体的文章多处地方都提到了,我就不展开说了)
  • let、const、var区别
  • 模板字符串
  • promise
  • 增加箭头函数
  • Map、Set等新的数据类型
  • 解构赋值
  • 函数默认参数
  1. 作用域问题
  • 变量提升
    var声明的变量作用域为函数作用域,会将变量定义提升至函数作用域顶部,函数声明也会有提升,且函数提升优先级高于变量提升,
  • 块级作用域
    在指定的作用域外无效,位于一对花括号之内,使用let和const声明变量
    使用var声明的变量,在其函数体及其嵌套函数体中都可以访问
  • 暂时性死区
    如下图,从块级作用域顶部到let语句之间的部分称为暂时性死区,如果没有let,则不会形成暂时性死区
    在这里插入图片描述
    大家能准确描述出let、const、var的区别,则就对2中的问题完全掌握
  1. 自由变量
    自由变量的查找,是在函数定义的地方,向上级作用域查找,而不是在调用的地方
  • 闭包指访问了其它作用域中的变量的函数
  • 闭包的应用(可以类比到vue的data是个函数)
    在这里插入图片描述
    使属性不能直接访问,只能通过get方法获取
  1. this的应用场景 (this取什么值,是在函数调用的地方确定,而不是在定义的地方确定)(与闭包相反)
  • 普通函数调用(window)
  • 使用call、bind、apply等(传入什么,this就是什么)
  • 作为对象方法调用(对象本身)
  • 作为构造函数被调用(调用的实例)
  • 箭头函数(没有自己的this,上级作用域的this值)
  1. 箭头函数与普通函数区别
    在这里插入图片描述

  2. call、bind、apply区别

  3. 如何判断函数是构造函数还是普通函数
    当以构造函数调用时,new.target 等于构造函数本身

异步(重要 )

  1. promise的链式调用及一些注意点
    在这里插入图片描述
    promise.all和promise.race
  2. require和import区别
  • require/exports 是运行时动态加载,import/export 是静态编译,所以import无法在函数内部使用,所以一般都在顶部
  • require/exports 输出的是一个值的拷贝,import/export 模块输出的是值的引用
  • import会有提升
  1. 异步使用场景
  2. async/await
    async会返回一个promise对象;
    await相当于promise的.then方法,若promise失败,则await不会触发,需要借助于try…catch捕获;
    async原理:是一种语法糖,是generator函数和promise共同实现的,因为async最后会返回promise,所以最后肯定后return 一个promise,promise中会递归调用generator函数(由next.done来判断是否结束)
  • 执行顺序:对于await后面的内容,都是异步执行(即类似前面提到的event loop中的setTimeout)
  1. event loop(DOM事件也使用回调,也是基于event loop)
    * 浏览器的event loop机制
    这里先给大家看个模拟的运行机制吧
    在这里插入图片描述

再配合下图讲出即可
在这里插入图片描述

在这里插入图片描述
* node 的event loop 机制
在这里插入图片描述
整体来说,两者区别为:
浏览器和 Node 环境下,微任务队列的执行时机不同

Node 端,微任务在事件循环的各个阶段之间执行
浏览器端,微任务在事件循环的 宏任务 执行完之后执行

  1. 宏任务和微任务区别
    宏任务:setTimeout、Ajax、等,发生在DOM渲染之后
    微任务:Promise、async/await等,发生在DOM渲染之前
  2. 宏任务、微任务触发时机解释
    在这里插入图片描述
  3. 设计模式
  • 设计原则
    在这里插入图片描述
    创建
  • 工厂模式:应用场景,创建成功、失败、警告等不同颜色、icon的弹框实例
  • 建造函数:应用场景(常见于初始化),编辑器初始化、vue初始化,首先创建一个简单的vue实例,然后把生命周期、事件、数据、模板渲染这些混入其中
  • 单例模式:应用场景,vue-router
    提高代码复用率
  • 享元模式,把公共部分提取出来,共同使用
  • 模板方法模式,先实现一个最基础的版本,再针对不同需求在基础版上实现
    提高代码可扩展性
  • 适配器模式-接口
  • 装饰者模式-方法内容
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值