javascript干货笔记

189 阅读8分钟

1. 关于设计一点事

点点滴滴慢慢积累设计干货: mp.weixin.qq.com/s/TGkjEV0F7…

  1. 图片设计: 利用墙壁阴影与相框(添加植物增强生活气氛)
  2. UI准备工作:UI配色、 背景模块设计、 字体大小颜色规范、 图片大小格式规范、 留白规范、 按钮样式统一

2. 好用的新特性

  1. 指数运算: 2**(3**2) ==> 512

  2. 扩展运算符: (浅拷贝)

    • 复制数组
    let a = [1,3,32]
    let a1 = [...a1] // [1,3,32]
    
    • 合并数组:
    let a2 = [...a,...a1] // [1,3,32,1,3,32]
    
    • 将字符串转换为数组:
    let str = 'str'; 
    [..str] // ['s','t','r']
    
    
    

3. 浅拷贝vs深拷贝

一、堆和栈的区别

深拷贝和浅拷贝的主要区别就是其在内存中的存储类型不同

堆和栈都是内存中划分出来用来存储的区域

栈(stack)为自动分配的内存空间,它由系统自动释放;而堆(heap)则是动态分配的内存,大小不定也不会自动释放。

二、 数据类型

基本数据类型

  • 基本数据类型主要是:undefined,boolean,number,string,null
  • 基本数据类型存放在栈中
  • 基本数据类型值不可变
  • 基本类型的比较是值的比较

引用类型

  • 引用类型存放在堆中
  • 引用类型值可变
  • 引用类型的比较是引用的比较

深拷贝:将 B 对象拷贝到 A 对象中,包括 B 里面的子对象,
浅拷贝:将 B 对象拷贝到 A 对象中,但不包括 B 里面的子对象

和原数据是否指向同一对象第一层数据为基本数据类型原数据中包含子对象
赋值改变会使原数据一同改变改变会使原数据一同改变
浅拷贝改变不会使原数据一同改变改变会使原数据一同改变
深拷贝改变不会使原数据一同改变改变不会使原数据一同改变

三、 浅拷贝缺陷

由于对象、数组是引用型数据,特点是该数据是存放在堆中,通过指针引用地址获取值,因而赋值时,只是将 aObj 的指针 赋予 bObj (let bObj = aObj),实际上aObj与bObj存储的地址是一样的,也就是说,若bObj.value = 2 , aObj.value也会等于2,同理,改变aObj的值也影响bObj,这就是浅拷贝所带来的缺点

image.png

如果将浅拷贝转为深拷贝

典型案例就是经常遇见的数组对象赋值问题,因为对象的深度不一,类型也不一,经常赋值时,因为浅拷贝原因而影响到了源数据数值

常见的解决方案:

  • 解构赋值

只适用于只有一层数组或对象,若数组里包括对象,则依然有影响

  • JSON.parse( JSON.stringify( Array || Object ) )

这个是最易用的解决方案,原理是将引用型数据(数组、对象)转化为 字符串,改变存储位置从而达到深拷贝效果,但是缺点也很明显,在项目中,常常会因为其中包括特殊符号而赋值失败,如:在对象中含有富文本、对象中包括了函数

  • 深拷贝转浅拷贝方法

原理: 分为基本类型数据和引用类型数据进行赋值处理

function deepClone(obj) {
    let res = null;
    const reference = [Date, RegExp, Set, WeakSet, Map, WeakMap, Error];
    if (reference.includes(obj?.constructor)) {
        res = new obj.constructor(obj);
    } else if (Array.isArray(obj)) {
        res = [];
        obj.forEach((e, i) => {
            res[i] = deepClone(e);
        });
    } else if (typeof obj === "object" && obj !== null) {
        res = {};
        for (const key in obj) {
            if (Object.hasOwnProperty.call(obj, key)) {
                res[key] = deepClone(obj[key]);
            }
        }
    } else {
        res = obj;
    }
    return res;
}

4. 浏览器解析渲染页面:

不用浏览器使用的内核不同,所以他们的渲染过程也是不一样的。目前主要有两个:

webkit渲染过程

Gecko渲染过程

  • 根据HTML解析出DOM树

    根据 HTML 的内容,将标签按照结构解析成为DOM 树,DOM 树解析的过程是一个深度优先遍历。即先构建当前节点的所有子节点,再构建下一个兄弟节点

    在读取 HTML 文档,构建 DOM 树的过程中,若遇到 script 标签,则 DOM 树的构建会暂停,直至脚本执行完毕。

  • 根据 CSS 解析生成 CSS 规则树

    解析 CSS 规则树时 js 执行将暂停,直至 CSS 规则树就绪

    解析 CSS 规则树时 js 执行将暂停,直至 CSS 规则树就绪 -- CSS加载会影响DOM渲染

  • 结合DOM树和CSS规则树,生成渲染树

    DOM 树和 CSS 规则树全部准备好了以后,浏览器才会开始构建渲染树。

    精简 CSS 并可以加快 CSS 规则树的构建,从而加快页面相应速度。

  • 根据渲染树计算每一个节点的信息

    布局:通过渲染树渲染对象的信息,计算出每一个渲染对象的位置和尺寸

    回流:在布局完成后,发现了某个部分发生了变化影响了布局,那就需要倒回去重新渲染

  • 根据计算好的信息绘制页面

    绘制阶段,系统会遍历呈现树,并调用呈现器的“paint”方法,将呈现器的内容显示在屏幕上。

    重绘:某个元素的背景颜色,文字颜色等,不影响元素周围或内部布局的属性,将只会引起浏览器的重绘。

    回流:某个元素的尺寸发生了变化,则需重新计算渲染树,重新渲染。

5. CSS 加载会造成阻塞吗?

在浏览器的工作中,DOM解析和CSS解析是两个并行的进程,所以这也解释了为什么CSS加载不会阻塞DOM的解析。

  • 然而,由于Render Tree是依赖于DOM Tree和CSSOM Tree的,所以他必须等待到CSSOM Tree构建完成,也就是CSS资源加载完成(或者CSS资源加载失败)后,才能开始渲染。因此,CSS加载是会阻塞Dom的渲染的。

  • 由于js可能会操作之前的Dom节点和css样式,因此浏览器会维持html中css和js的顺序。因此,样式表会在后面的js执行前先加载执行完毕。所以css会阻塞后面js的执行。

对于浏览器来说,页面加载主要有两个事件,一个是DOMContentLoaded,另一个是onLoad。
onLoad : 等待页面的所有资源都加载完成才会触发
onLoad : 当页面的内容解析完成后,则触发该事件

  • 如果页面中同时存在css和js,并且存在js在css后面,则DOMContentLoaded事件会在css加载完后才执行。

  • 其他情况下,DOMContentLoaded都不会等待css加载,并且DOMContentLoaded事件也不会等待图片、视频等其他资源加载。

6. 如何提高首频加载速度

  1. js外联文件放到body底部,css外联文件放到head内

  2. http静态资源尽量用多个子域名

  3. 服务器端提供html和http静态资源时最好开启gzip

  4. 在js,css,img等资源响应的http headers里设置expires,last-modified

  5. 尽量减少http requests的数量

  6. js/css/html/img资源压缩

  7. 使用css spirtes,可以减少img请求次数

  8. 大图使用lazyload懒加载

  9. 避免404,减少外联js

  10. 减少cookie大小可以提高获得响应的时间

  11. 减少dom elements的数量

  12. 使用异步脚本,动态创建脚本

7. 请描述一下 cookies,sessionStorage 和 localStorage 的区别?

cookie是网站为了标示用户身份而储存在用户本地终端(Client Side)上的数据(通常经过加密)。

cookie数据始终在同源的http请求中携带(即使不需要),记会在浏览器和服务器间来回传递。

sessionStorage和localStorage不会自动把数据发给服务器,仅在本地保存。

存储大小:

  • cookie数据大小不能超过4k。

  • sessionStorage和localStorage 虽然也有存储大小的限制,但比cookie大得多,可以达到5M或更大。

有期时间:

  • localStorage : 存储持久数据,浏览器关闭后数据不丢失除非主动删除数据;
  • sessionStorage : 数据在当前浏览器窗口关闭后自动删除。
  • cookie : 设置的cookie过期时间之前一直有效,即使窗口或浏览器关闭

8. 介绍一下标准的CSS的盒子模型?低版本IE的盒子模型有什么不同的?

(1)有两种, IE 盒子模型、W3C 盒子模型;

(2)盒模型: 内容(content)、填充(padding)、边界(margin)、 边框(border);

(3)区 别: IE的content部分把 border 和 padding计算了进去;


9. 让overflow:scroll平滑滚动?

-webkit-overflow-scrolling: touch;


10. Ajax 解决浏览器缓存问题

1、在ajax发送请求前加上 anyAjaxObj.setRequestHeader("If-Modified-Since","0")。

2、在ajax发送请求前加上 anyAjaxObj.setRequestHeader("Cache-Control","no-cache")。

3、在URL后面加上一个随机数: "fresh=" + Math.random();。

4、在URL后面加上时间戳:"nowtime=" + new Date().getTime();

5、如果是使用jQuery,直接这样就可以了$.ajaxSetup({cache:false})。这样页面的所有ajax都会执行这条语句就是不需要保存缓存记录

来源: