JS必会基础知识3

描述cookie和localStorage和sessionStorage的区别

从容量和API易用性角度。

cookie

  1. cookie 本身用于浏览器和 server 通讯,被“借用”到本地存储
  2. api为document.cookie,不够友好
  3. 容量最大为4kB
  4. http请求时需要一同发送到服务器,增加了请求的数据量

localStorage和sessionStorage

  1. 专为本地存储而设计的,最大为5MB
  2. API简单易用,setItemgetItem
  3. 不会随http请求发送出去
  4. localStorage数据永久存储,除非被动删除
  5. sessionStorage中存在当前会话,浏览器关闭后就会清空

从输入URL到渲染出页面的整个过程

  1. DNS解析:域名 -> IP地址
  2. 浏览器根据IP地址向服务器发送http请求
  3. 服务器处理http请求,并返回给浏览器
  4. 根据html代码生成DOM树
  5. 根据CSS代码生成CSSOM
  6. 将DOM树和CSSOM整合成RenderTree
  7. 根据RenderTree渲染页面,遇到script标签则暂停渲染,优先加载脚本并执行js代码,完成后再继续。暂停是因为JS进程和渲染进程是公用一个线程的,js可能会改变DOM结构
  8. 直到渲染完成

其中link要放在head中,因为放在后面可能会造成再次渲染问题,js放在最后,是因为JS进程和渲染进程是公用一个线程的,而且有可能js加载时间很长,然后就会造成页面卡顿现象,img标签不会暂停渲染,不会阻塞DOM渲染,不会造成重排现象。

window.onload和DOMContentLoaded的区别

window.addEventListener('load', function() {
  // 页面全部资源加载完才会执行,包括图片、视频
  console.log('load');  // 后输出
})
document.addEventListener('DOMContentLoaded', function() {
  // DOM渲染完成即可执行,此时图片、视频可能还未加载完成
  console.log('DOMContentLoaded');  // 先输出,所以操作 js 最好在这个方法里面
})

性能优化

原则:

  1. 多使用内存、缓存
  2. 减少CPU计算,减少网络加载耗时
  3. 以空间换取时间

从何入手

1. 让加载更快

1.1 减少资源的体积:压缩代码
1.2 减少访问次数:合并代码、SSR渲染、缓存
1.3 使用更快的网络

2. 让渲染更快

2.1 css放在head部分,js放在body最后
2.2 尽早执行js,用DOMContentLoaded触发
2.3 懒加载:图片懒加载、上滑加载更多
2.4 对DOM查询缓存
2.5 频繁DOM操作,合并到一起插入DOM结构
2.6 节流和防抖

防抖debounce

场景:监听一个输入框的文字,变化后触发change事件,直接用keyup事件,则会频繁触发change事件,使用防抖,只有在用户输入结束或暂停的时候,才会触发change事件




节流throttle

场景:拖拽一个元素师,要随时拿到该元素的拖拽位置,直接用drag事件,则会频繁触发,很容易造成卡顿,此时使用节流的话,无论拖拽速度多快,都快每隔一段时间触发一次

如何捕获异常

  1. try...catch
  2. window.onerror = funtion(message, source, lineNumber, colNumber, error) {}

var 和let、const的区别

  • var是ES5语法,let和const是ES6语法,var有变量提升
  • var和let是变量,可修改,const是常量,不可改变
  • let和const有块级作用域,var没有

手写一个深度比较

// 判断是否是对象
function isObject(target) {
    return typeof target === "object" && target !== null;
}
function isEqual(source, target) {
    // 只要其中有一个不是对象,那就直接比较
    // 如 isEqual(1, { a: 2 })
    // 如 isEqual(1, 1)
    if (!isObject(source) || !isObject(target)) {
        return source === target;
    }
    // 如过两个都引用的是一个对象,直接比较
    // 如 isEqual(a, a)
    if (source === target) {
        return true;
    }
    //  两个都是对象或数组,而且不相等
    // 1. 先取出 source 和 target 的keys, 比较个数
    const sourceKeys = Object.keys(source);
    const targetKeys = Object.keys(target);
    if (sourceKeys.length !== targetKeys.length) {
        return false;
    }
    // 以 source 为基准,和 target 依次递归比较
    for (let key in sourceKeys) {
        const res = isEqual(source[key], target[key]);
        // 如果 res 中有一个为false,那就直接返回false
        if (!res) {
            return false;
        }
    }
    // 如果res都为true
    return true;
}
const a = { a: 1, b: 2, c: { x: 3, y: 4 } };
const b = { a: 1, b: 2, c: { x: 3, y: 4 } };
const c = { a: 1, b: 2, c: { x: 3, y: 4 }, d: 5 };
const d = { a: 1, b: 2, c: { x: 3, y: 44 } };

console.log(isEqual("aa", "aa")); // true
console.log(isEqual(11, 1)); // false
console.log(isEqual(a, b)); // true
console.log(isEqual(a, c)); // false
console.log(isEqual(a, d)); // false

获取URL参数

// 传统方法
function getURLQueryParams(_url) {
    const params = {};
    const url = _url || location.href; // _url 存在则用 _url, 不存在则用location.href
    const search = url.split("?");
    if (!search[1]) {
        return params;
    }
    const searches = search[1].split("&");

    searches.map(item => {
        const items = item.split("=");

        params[items[0]] = items[1];
    });
    return params;
}
console.log(getURLQueryParams("http:www.baidu.com?name=xxx&age=20")); // {name: "xxx", age: "20"}

你可能感兴趣的:(JS必会基础知识3)