面试题 总结

206 阅读4分钟

1 防抖节流

防抖:

规定一个期限时间,在首次触发事件时,不立即执行回调函数,而是在期限时间后再执行,如果期限时间内回调函数被重复执行,则期限时间重新计时。

例1:用户在输入框中输入一串字符,只会在最后一次输入完成后再去执行查询ajax请求,这样可以有效减少请求的次数,节约请求资源。

例2:window的scroll、resize事件,不断地滚动、或调整浏览器窗口大小时触发的对应事件,可以允许其只触发一次。

节流:

规定一个期限时间,在该时间内,触发事件的回调函数只能执行一次,如果期限时间内回调函数被多次触发,则只有一次能生效。

例1:在页面无限加载的情况下,需要用户再滚动页面时,每隔一定时间发起一次ajax请求,而不是再用户停下滚动时再去请求数据。

例2:监听滚动事件,比如是否滑倒底部自动加载更多,则用节流来判断。

2 原型和原型链

function Person() {}

prototype

每个函数都有一个 prototype 属性 每一个JavaScript对象(null除外)在创建的时候就会与之关联另一个对象,这个对象就是我们所说的原型,每一个对象都会从原型"继承"属性。

例:Person.prototype.name = 'Kevin';
new Person().name

proto

每一个JavaScript对象(除了 null )都具有的一个属性,叫proto,这个属性会指向该对象的原型

例:new Person().proto === Person.prototype

constructor

每个原型都有一个 constructor 属性指向关联的构造函数 实例原型指向构造函数

例:Person === Person.prototype.constructor

3闭包

闭包是指有权访问另一个函数作用域中的变量的函数

3个特性:

①函数嵌套函数

②函数内部可以引用函数外部的参数和变量

③参数和变量不会被垃圾回收机制回收

好处

①保护函数内的变量安全 ,实现封装,防止变量流入其他环境发生命名冲突

②在内存中维持一个变量,可以做缓存(但使用多了同时也是一项缺点,消耗内存)

③匿名自执行函数可以减少内存消耗

坏处

①其中一点上面已经有体现了,就是被引用的私有变量不能被销毁,增大了内存消耗,造成内存泄漏,解决方法是可以在使用完变量后手动为它赋值为null;

②其次由于闭包涉及跨域访问,所以会导致性能损失,我们可以通过把跨作用域变量存储在局部变量中,然后直接访问局部变量,来减轻对执行速度的影响

4TCP握手

第一次握手:客户端发服务器发起报文。

第二次握手:服务器接收连接请求 返回报文。

第三次握手:客户端收到服务器的报文,连接成功。

5 web优化

  1. 定义局部变量
  2. 小心使用闭包
  3. 不要使用 with() 语句
  4. 不要在数组中挖得太深
  5. 资源合并与压缩
  6. HTML CSS JS 压缩
  7. 图片压缩
  8. 减少HTTP请求

6 重绘和回流

重绘

当render tree中的一些元素需要更新属性,而这些属性只是影响元素的外观,风格,而不会影响布局的,比如background-color。则就叫称为重绘。

回流

当render tree中的一部分(或全部)因为元素的规模尺寸,布局,隐藏等改变而需要重新构建。这就称为回流(reflow)。

7 APP通讯

Hybrid通信 APP中用js解释器

8 TS

TypeScript 是 JavaScript 的一个超集

1 类型批注和编译时类型检查

2 类

3 模块

4 装饰器

9 排序

1 冒泡排序

比较相邻的前后两个数据,如果前面数据大于后面的数据,就将两个数据交换

    for (let i = 0; i < arr.length; i++) {
        for (let j = 0; j < arr.length - i - 1; j++) {
            if (arr[j] > arr[j + 1]) {
                //交换位置
                let min = arr[j+1]
                arr[j+1]=arr[j]
                arr[j]=min
            }
        }
    }

2 选择排序

循环数组 找出最小的与第一个交换 N次后结束

    for (let i = 0; i < arr.length; i++) {
        for (let j = i + 1; j < arr.length; j++) {
            console.log(arr[i],arr[j])
            if (arr[j] < arr[i]) {
                let min = arr[j];
                arr[j] = arr[i];
                arr[i] = min;
            }
        }
    }

10 二叉树循环

前序遍历:先遍历根结点,然后左子树,再右子树

中序遍历:先遍历左子树,然后根结点,再右子树

后续遍历:先遍历左子树,然后右子树,再根结点

递归:

递归函数就是在函数体内调用本函数;

递归函数的使用要注意函数终止条件避免死循环;

11 浏览器访问页面发生了什么

第一步,解析域名,找到主机IP

第二部,浏览器与网站建立TCP连接

第三部分,浏览器发起GET请求

第四部分,显示页面或返回其他

12 继承

常用继承 原型链继承 对象冒充继承

function Person() {
    this.name = '张三'
}

Person.prototype.run = function () { console.log('张三跑步') }

let p1 = new Person()
console.log(p1)
p1.run()
console.log(p1.name)

let p2 = function () {
    Person.call(this)
    console.log(this.name)
}