原型与原型链
- 所有函数都有一个特别的属性:
prototype: 显式原型属性
- 所有实例对象都有一个特别的属性:
__proto__: 隐式原型属性
- 显式原型与隐式原型的关系
- 函数的prototype: 定义函数时被自动赋值, 值默认为{}, 即用为原型对象
- 实例对象的__proto__: 在创建实例对象时被自动添加, 并赋值为构造函数的prototype值
- 原型对象即为当前实例对象的父对象
- 原型链
- 所有的实例对象都有__proto__属性, 它指向的就是原型对象
- 这样通过__proto__属性就形成了一个链的结构---->原型链
- 当查找对象内部的属性/方法时, js引擎自动沿着这个原型链查找
- 当给对象属性赋值时不会使用原型链, 而只是在当前对象中进行操作
执行上下文与执行上下文栈
- 变量提升与函数提升
- 变量提升: 在变量定义语句之前, 就可以访问到这个变量(undefined)
- 函数提升: 在函数定义语句之前, 就执行该函数
- 先有变量提升, 再有函数提升
- 理解
- 执行上下文: 由js引擎自动创建的对象, 包含对应作用域中的所有变量属性
- 执行上下文栈: 用来管理产生的多个执行上下文
- 分类:
- 全局: window
- 函数: 对程序员来说是透明的
- 生命周期
- 全局 : 准备执行全局代码前产生, 当页面刷新/关闭页面时死亡
- 函数 : 调用函数时产生, 函数执行完时死亡
- 包含哪些属性:
- 全局 :
- 用var定义的全局变量 ==>undefined
- 使用function声明的函数 ===>function
- this ===>window
- 函数
- 用var定义的局部变量 ==>undefined
- 使用function声明的函数 ===>function
- this ===> 调用函数的对象, 如果没有指定就是window
- 形参变量 ===>对应实参值
- arguments ===>实参列表的伪数组
- 全局 :
- 执行上下文创建和初始化的过程
- 全局:
- 在全局代码执行前最先创建一个全局执行上下文(window)
- 收集一些全局变量, 并初始化
- 将这些变量设置为window的属性
- 函数:
- 在调用函数时, 在执行函数体之前先创建一个函数执行上下文
- 收集一些局部变量, 并初始化
- 将这些变量设置为执行上下文的属性
- 全局:
作用域与作用域链
- 理解:
- 作用域: 一块代码区域, 在编码时就确定了, 不会再变化
- 作用域链: 多个嵌套的作用域形成的由内向外的结构, 用于查找变量
- 分类:
- 全局
- 函数
- js没有块作用域(在ES6之前)
- 作用
- 作用域: 隔离变量, 可以在不同作用域定义同名的变量不冲突
- 作用域链: 查找变量
- 区别作用域与执行上下文
- 作用域: 静态的, 编码时就确定了(不是在运行时), 一旦确定就不会变化了
- 执行上下文: 动态的, 执行代码时动态创建, 当执行结束消失
- 联系: 执行上下文环境是在对应的作用域中的
闭包
- 理解:
- 当嵌套的内部函数引用了外部函数的变量时就产生了闭包
- 通过chrome工具得知: 闭包本质是内部函数中的一个对象, 这个对象中包含引用的变量属性
- 作用:
- 延长局部变量的生命周期
- 让函数外部能操作内部的局部变量
- 写一个闭包程序
function fn1() { var a = 2; function fn2() { a++; console.log(a); } return fn2; } var f = fn1(); f(); f(); - 闭包应用:
- 模块化: 封装一些数据以及操作数据的函数, 向外暴露一些行为
- 循环遍历加监听
- JS框架(jQuery)大量使用了闭包
- 缺点:
- 变量占用内存的时间可能会过长
- 可能导致内存泄露
- 解决:
- 及时释放 : f = null; //让内部函数对象成为垃圾对象
内存溢出与内存泄露
- 内存溢出
- 一种程序运行出现的错误
- 当程序运行需要的内存超过了剩余的内存时, 就出抛出内存溢出的错误
- 内存泄露
- 占用的内存没有及时释放
- 内存泄露积累多了就容易导致内存溢出
- 常见的内存泄露:
- 意外的全局变量
- 没有及时清理的计时器或回调函数
- 闭包
牽著幸福的小豬:
HTML, CSS
- html的语义化:
- 用正确的标签做正确的事情,根据内容的结构化,选择合适的标签
- 便于开发者阅读和写出优雅的代码,便于浏览器的爬虫更好的解析
- 原因:用户体验;有利于seo,便于团队开发
- postion的理解:
- relative:相对于自身原来的位置定位,不脱离文档流
- absolute: a)父元素(relative) - 相对于父元素定位,脱离文档流 b)父元素:无 - 相对于body定位,脱离文档流
- static: 默认
- fixed: 固定定位,相对于浏览器定位,脱离文档流
- inherit:继承父级的positon属性
- initial: 默认值
- 盒模型:
- 标准盒模型:content-box:width = div的宽度
- 怪异盒模型: boxder-box: width = content + padding + border
- 获取元素的宽度: dom.offsetWidth = dom.getBoundingClientRect().width;
- 行内元素和块级元素:
- 行内元素:不能设置宽,高,与其他行内元素位于同一行,一般不在里面嵌套块级元素
- 例如:span, input, label, select, img, textarea, em, strong, i
- 块级元素: 排斥其他元素同行,可设置狂傲,可容纳块,行内元素
- 例如: h1--h6, p, div, dl, dt, dv, ol, ul, li, table, td, th
- 区别:
- 块级元素独占一行,行内元素多个可排成一排;
- 块级元素可设置狂傲,行内元素不能设置宽高;
- 块级元素可以包含块级,行内, 行内元素一般包含行内的和文本
- 块级元素可以设置padding,margin, 行内元素只能设置padding和margin的left/right
- 行内元素:不能设置宽,高,与其他行内元素位于同一行,一般不在里面嵌套块级元素
- BFC(块级格式化上下文)
- 概念:页面的一个独立的渲染区域,容器里面的自元素不会在布局上影响外面的元素,决定块级盒子的浮动,布局的因素
- 触发条件:
- float浮动
- 绝对定位(absolute, fixed)
- 行内块元素(inline-block, table-cell)
- overflo的值不为visible的块元素
- 弹性元素,display:flex/inline-flex
- BFC作用
- 解决上下两个相邻元素的重叠问题(垂直margin合并的问题)
- 正数时:两者之前取最大
- 负数时:绝对值取较大的
- 一正一负: 两者的和
- 清除内部浮动问题
- 解决上下两个相邻元素的重叠问题(垂直margin合并的问题)
- BFC的原理
- BFC不会与float的元素重叠,BFC下的编剧也不会重叠,BFC是一个独立的容器和外面的容器互不干扰,计算BFC的高度,浮动的子元素也会参与
- CSS的动画效果animation
- @keyframes 'loop' {0% {}; 50% {}; 100% {}}
- 伪类的元素: nth-child(even) / nth-child(old)
- css的选择器的优先级:
- 如果多重样式: 外部样式 < 内部样式 < 内联样式
- 注意: 外部样式放在内部样式的后面,则会覆盖;
- 选择器的优先级:
- 内联样式 > id选择器 > 类选择器 > 元素选择器
- 总结
- 越具体优先级越高
- 同样优先级写在后面的覆盖前面的
- !important的优先级最高,但是少用
- 清除浮动的方法:
- overflow: hidden
- clearfix:after { content: '', display: block, clear: both } }
- 父元素给个固定高度
牽著幸福的小豬:
闭包
- 定义:
- 函数和函数内部能访问的变量的总和,就是闭包;
- 当嵌套的内部函数引入用了外部函数的变量
- 本质:内部函数中的一个对象,这个对象中包含了引用的变量属性
- 从技术的角度讲,所有的JavaScript函数都是闭包:它们都是对象,它们都关联到作用域链。
- 作用
- 让函数外部能操作内部的局部变量
- 延长局部变量的生命周期
- 闭包应用:
- 模块化: 封装一些数据以及操作数据的函数, 向外暴露一些行为
- 循环遍历加监听
- JS框架(jQuery)大量使用了闭包
- 缺点:
- 变量占用内存的时间可能会过长
- 可能导致内存泄露
- 解决:
- 及时释放 : f = null; //让内部函数对象成为垃圾对象
内存溢出与内存泄露
- 内存溢出
- 一种程序运行出现的错误
- 当程序运行需要的内存超过了剩余的内存时, 就出抛出内存溢出的错误
- 内存泄露
- 占用的内存没有及时释放
- 内存泄露积累多了就容易导致内存溢出
- 常见的内存泄露:
- 意外的全局变量
- 没有及时清理的计时器或回调函数
- 闭包
立即执行函数
- 定义:声明一个函数,并立即调用这个函数
- 作用:创建一个独立的作用域,这个作用域内的变量,外面访问不到,避免全剧污染
promise的理解
- Promise 是异步编程的一种解决方案,其实是一个构造函数,自己身上有all、reject、resolve这几个方法,有then、catch、finally等方法
- 特点:
- 对象的状态不受外界影响
- 一旦状态改变,就不会再变,任何时候都可以得到这个结果
- promise的其他api
- promise.all
- promise.race
async/await
- 捕获异常: try ... catch
- ().then 后面可以捕获异常
浅拷贝和深拷贝
- 浅拷贝
- 浅拷贝是拷贝一层,深层次的对象级别的就拷贝引用;
- 浅拷贝的时候如果数据是基本数据类型,直接赋值,会拷贝其本身;
- 如果除了基本数据类型之外还有一层对象,那么对于浅拷贝而言就只能拷贝其引用,对象的改变会反应到拷贝对象上;
- 浅拷贝的方法:
- Object.assign(target, ...sources)
- target:目标对象, sources:任意多个源对象,返回值:目标对象会被返回
- Object.assign(target, ...sources)
- 浅拷贝是拷贝一层,深层次的对象级别的就拷贝引用;
- 深拷贝
- 深拷贝是拷贝多层,每一级别的数据都会拷贝出来
- 深拷贝就会拷贝多层,即使是嵌套了对象,也会都拷贝出来。
- 方法
- 对象只有一层的话: Object.assign()函数
- JSON.parse(JSON.stringify(obj))
- 缺点:会抛弃对象的constructor。也就是深拷贝之后,不管这个对象原来的构造函数是什么,在深拷贝之后都会变成Object。
- 递归拷贝
- 使用Object.create()方法
- 直接使用var newObj = Object.create(oldObj),可以达到深拷贝的效果。
- 深拷贝是拷贝多层,每一级别的数据都会拷贝出来
js的垃圾回收机制
- js的内存管理是自动的,无形的,创建的原始值,对象,函数,,,都是会占用内存。
- js的内存管理的可达性:是以某种方式可访问的值,一定存在内存中;
- 可达性分类:
* 固有的可达值的基本集合,明显不会被释放
- 函数的局部变量、函数根(roots)
- 嵌套调用时,调用连上所有的函数的变量与参数根(roots)
- 全局变量
- 内部的根(roots) * 一个值可以通过引用和引用连从根访问任何值,该值也是可达的
- 全局变量中有个属性,该对象的一个属性引用了另一个对象,该对象也是可达的
- 例子1
let user = { name: 'John'};
John = null;
- 不可达,没有引用,不能访问,垃圾回收器会认为是垃圾数据并进行回收,释放内存
- 例子2
let user = { name: 'John'};
let admin = user;
user = null;
- 对象可以通过admin访问,对象还存在内存中,若admin= null,对象就会被删除
- 例子1
let user = { name: 'John'};
John = null;
- 垃圾会是的内部算法 ---》 定期执行垃圾回收 * 垃圾回收器找到所有的根,并标记 * 然后标记来自他们的所有引用 * 便利标记的对象,并标记他们的引用,所有遍历到的对象都会被记住,以免将来遍历到同一个对象 * 。。。直到所有可达的从根部的引用都被访问到 * 没有被标记的对象都会被删除 例子: 一个油桶,流经所有引用并标记所有可达的对象,移除没有标记的
- js的优化: * 分代收集: 对象分成新的,旧的。有些对象出现完成他们的工作并很快死去,他们可以被很快清理,长期存活的对象会变得老旧,被查的频率减少 * 增量收集: 一次性太耗时,垃圾收集分成几部分去完成,逐一进行处理,需要他们之间有额外的标记 * 闲时收集: 在cpu闲时尝试运行,减少对代码的执行影响
- 总结: * 1. 垃圾回收时自动完成的,不能强制执行或阻止执行 * 2. 当对象时可达状态时,一定存在内存中 * 3. 被引用与可访问不同,一组相互链接的对象可能整体都时不可达的 牽著幸福的小豬:
原型与原型链
- 所有函数都有一个特别的属性:
prototype: 显式原型属性
- 所有实例对象都有一个特别的属性:
__proto__: 隐式原型属性
- 显式原型与隐式原型的关系
- 函数的prototype: 定义函数时被自动赋值, 值默认为{}, 即用为原型对象
- 实例对象的__proto__: 在创建实例对象时被自动添加, 并赋值为构造函数的prototype值
- 原型对象即为当前实例对象的父对象
- 原型链
- 所有的实例对象都有__proto__属性, 它指向的就是原型对象
- 这样通过__proto__属性就形成了一个链的结构---->原型链
- 当查找对象内部的属性/方法时, js引擎自动沿着这个原型链查找
- 当给对象属性赋值时不会使用原型链, 而只是在当前对象中进行操作
执行上下文与执行上下文栈
- 变量提升与函数提升
- 变量提升: 在变量定义语句之前, 就可以访问到这个变量(undefined)
- 函数提升: 在函数定义语句之前, 就执行该函数
- 先有变量提升, 再有函数提升
- 理解
- 执行上下文: 由js引擎自动创建的对象, 包含对应作用域中的所有变量属性
- 执行上下文栈: 用来管理产生的多个执行上下文
- 分类:
- 全局: window
- 函数: 对程序员来说是透明的
- 生命周期
- 全局 : 准备执行全局代码前产生, 当页面刷新/关闭页面时死亡
- 函数 : 调用函数时产生, 函数执行完时死亡
- 包含哪些属性:
- 全局 :
- 用var定义的全局变量 ==>undefined
- 使用function声明的函数 ===>function
- this ===>window
- 函数
- 用var定义的局部变量 ==>undefined
- 使用function声明的函数 ===>function
- this ===> 调用函数的对象, 如果没有指定就是window
- 形参变量 ===>对应实参值
- arguments ===>实参列表的伪数组
- 全局 :
- 执行上下文创建和初始化的过程
- 全局:
- 在全局代码执行前最先创建一个全局执行上下文(window)
- 收集一些全局变量, 并初始化
- 将这些变量设置为window的属性
- 函数:
- 在调用函数时, 在执行函数体之前先创建一个函数执行上下文
- 收集一些局部变量, 并初始化
- 将这些变量设置为执行上下文的属性
- 全局:
作用域与作用域链
- 理解:
- 作用域: 一块代码区域, 在编码时就确定了, 不会再变化
- 作用域链: 多个嵌套的作用域形成的由内向外的结构, 用于查找变量
- 分类:
- 全局
- 函数
- js没有块作用域(在ES6之前)
- 作用
- 作用域: 隔离变量, 可以在不同作用域定义同名的变量不冲突
- 作用域链: 查找变量
- 区别作用域与执行上下文
- 作用域: 静态的, 编码时就确定了(不是在运行时), 一旦确定就不会变化了
- 执行上下文: 动态的, 执行代码时动态创建, 当执行结束消失
- 联系: 执行上下文环境是在对应的作用域中的
闭包
- 理解:
- 当嵌套的内部函数引用了外部函数的变量时就产生了闭包
- 通过chrome工具得知: 闭包本质是内部函数中的一个对象, 这个对象中包含引用的变量属性
- 作用:
- 延长局部变量的生命周期
- 让函数外部能操作内部的局部变量
- 写一个闭包程序
function fn1() { var a = 2; function fn2() { a++; console.log(a); } return fn2; } var f = fn1(); f(); f(); - 闭包应用:
- 模块化: 封装一些数据以及操作数据的函数, 向外暴露一些行为
- 循环遍历加监听
- JS框架(jQuery)大量使用了闭包
- 缺点:
- 变量占用内存的时间可能会过长
- 可能导致内存泄露
- 解决:
- 及时释放 : f = null; //让内部函数对象成为垃圾对象
内存溢出与内存泄露
- 内存溢出
- 一种程序运行出现的错误
- 当程序运行需要的内存超过了剩余的内存时, 就出抛出内存溢出的错误
- 内存泄露
- 占用的内存没有及时释放
- 内存泄露积累多了就容易导致内存溢出
- 常见的内存泄露:
- 意外的全局变量
- 没有及时清理的计时器或回调函数
- 闭包
牽著幸福的小豬:
HTML, CSS
- html的语义化:
- 用正确的标签做正确的事情,根据内容的结构化,选择合适的标签
- 便于开发者阅读和写出优雅的代码,便于浏览器的爬虫更好的解析
- 原因:用户体验;有利于seo,便于团队开发
- postion的理解:
- relative:相对于自身原来的位置定位,不脱离文档流
- absolute: a)父元素(relative) - 相对于父元素定位,脱离文档流 b)父元素:无 - 相对于body定位,脱离文档流
- static: 默认
- fixed: 固定定位,相对于浏览器定位,脱离文档流
- inherit:继承父级的positon属性
- initial: 默认值
- 盒模型:
- 标准盒模型:content-box:width = div的宽度
- 怪异盒模型: boxder-box: width = content + padding + border
- 获取元素的宽度: dom.offsetWidth = dom.getBoundingClientRect().width;
- 行内元素和块级元素:
- 行内元素:不能设置宽,高,与其他行内元素位于同一行,一般不在里面嵌套块级元素
- 例如:span, input, label, select, img, textarea, em, strong, i
- 块级元素: 排斥其他元素同行,可设置狂傲,可容纳块,行内元素
- 例如: h1--h6, p, div, dl, dt, dv, ol, ul, li, table, td, th
- 区别:
- 块级元素独占一行,行内元素多个可排成一排;
- 块级元素可设置狂傲,行内元素不能设置宽高;
- 块级元素可以包含块级,行内, 行内元素一般包含行内的和文本
- 块级元素可以设置padding,margin, 行内元素只能设置padding和margin的left/right
- 行内元素:不能设置宽,高,与其他行内元素位于同一行,一般不在里面嵌套块级元素
- BFC(块级格式化上下文)
- 概念:页面的一个独立的渲染区域,容器里面的自元素不会在布局上影响外面的元素,决定块级盒子的浮动,布局的因素
- 触发条件:
- float浮动
- 绝对定位(absolute, fixed)
- 行内块元素(inline-block, table-cell)
- overflo的值不为visible的块元素
- 弹性元素,display:flex/inline-flex
- BFC作用
- 解决上下两个相邻元素的重叠问题(垂直margin合并的问题)
- 正数时:两者之前取最大
- 负数时:绝对值取较大的
- 一正一负: 两者的和
- 清除内部浮动问题
- 解决上下两个相邻元素的重叠问题(垂直margin合并的问题)
- BFC的原理
- BFC不会与float的元素重叠,BFC下的编剧也不会重叠,BFC是一个独立的容器和外面的容器互不干扰,计算BFC的高度,浮动的子元素也会参与
- CSS的动画效果animation
- @keyframes 'loop' {0% {}; 50% {}; 100% {}}
- 伪类的元素: nth-child(even) / nth-child(old)
- css的选择器的优先级:
- 如果多重样式: 外部样式 < 内部样式 < 内联样式
- 注意: 外部样式放在内部样式的后面,则会覆盖;
- 选择器的优先级:
- 内联样式 > id选择器 > 类选择器 > 元素选择器
- 总结
- 越具体优先级越高
- 同样优先级写在后面的覆盖前面的
- !important的优先级最高,但是少用
- 清除浮动的方法:
- overflow: hidden
- clearfix:after { content: '', display: block, clear: both } }
- 父元素给个固定高度
牽著幸福的小豬:
闭包
- 定义:
- 函数和函数内部能访问的变量的总和,就是闭包;
- 当嵌套的内部函数引入用了外部函数的变量
- 本质:内部函数中的一个对象,这个对象中包含了引用的变量属性
- 从技术的角度讲,所有的JavaScript函数都是闭包:它们都是对象,它们都关联到作用域链。
- 作用
- 让函数外部能操作内部的局部变量
- 延长局部变量的生命周期
- 闭包应用:
- 模块化: 封装一些数据以及操作数据的函数, 向外暴露一些行为
- 循环遍历加监听
- JS框架(jQuery)大量使用了闭包
- 缺点:
- 变量占用内存的时间可能会过长
- 可能导致内存泄露
- 解决:
- 及时释放 : f = null; //让内部函数对象成为垃圾对象
内存溢出与内存泄露
- 内存溢出
- 一种程序运行出现的错误
- 当程序运行需要的内存超过了剩余的内存时, 就出抛出内存溢出的错误
- 内存泄露
- 占用的内存没有及时释放
- 内存泄露积累多了就容易导致内存溢出
- 常见的内存泄露:
- 意外的全局变量
- 没有及时清理的计时器或回调函数
- 闭包
立即执行函数
- 定义:声明一个函数,并立即调用这个函数
- 作用:创建一个独立的作用域,这个作用域内的变量,外面访问不到,避免全剧污染
promise的理解
- Promise 是异步编程的一种解决方案,其实是一个构造函数,自己身上有all、reject、resolve这几个方法,有then、catch、finally等方法
- 特点:
- 对象的状态不受外界影响
- 一旦状态改变,就不会再变,任何时候都可以得到这个结果
- promise的其他api
- promise.all
- promise.race
async/await
- 捕获异常: try ... catch
- ().then 后面可以捕获异常
浅拷贝和深拷贝
- 浅拷贝
- 浅拷贝是拷贝一层,深层次的对象级别的就拷贝引用;
- 浅拷贝的时候如果数据是基本数据类型,直接赋值,会拷贝其本身;
- 如果除了基本数据类型之外还有一层对象,那么对于浅拷贝而言就只能拷贝其引用,对象的改变会反应到拷贝对象上;
- 浅拷贝的方法:
- Object.assign(target, ...sources)
- target:目标对象, sources:任意多个源对象,返回值:目标对象会被返回
- Object.assign(target, ...sources)
- 浅拷贝是拷贝一层,深层次的对象级别的就拷贝引用;
- 深拷贝
- 深拷贝是拷贝多层,每一级别的数据都会拷贝出来
- 深拷贝就会拷贝多层,即使是嵌套了对象,也会都拷贝出来。
- 方法
- 对象只有一层的话: Object.assign()函数
- JSON.parse(JSON.stringify(obj))
- 缺点:会抛弃对象的constructor。也就是深拷贝之后,不管这个对象原来的构造函数是什么,在深拷贝之后都会变成Object。
- 递归拷贝
- 使用Object.create()方法
- 直接使用var newObj = Object.create(oldObj),可以达到深拷贝的效果。
- 深拷贝是拷贝多层,每一级别的数据都会拷贝出来
js的垃圾回收机制
- js的内存管理是自动的,无形的,创建的原始值,对象,函数,,,都是会占用内存。
- js的内存管理的可达性:是以某种方式可访问的值,一定存在内存中;
- 可达性分类:
* 固有的可达值的基本集合,明显不会被释放
- 函数的局部变量、函数根(roots)
- 嵌套调用时,调用连上所有的函数的变量与参数根(roots)
- 全局变量
- 内部的根(roots) * 一个值可以通过引用和引用连从根访问任何值,该值也是可达的
- 全局变量中有个属性,该对象的一个属性引用了另一个对象,该对象也是可达的
- 例子1
let user = { name: 'John'};
John = null;
- 不可达,没有引用,不能访问,垃圾回收器会认为是垃圾数据并进行回收,释放内存
- 例子2
let user = { name: 'John'};
let admin = user;
user = null;
- 对象可以通过admin访问,对象还存在内存中,若admin= null,对象就会被删除
- 例子1
let user = { name: 'John'};
John = null;
- 垃圾会是的内部算法 ---》 定期执行垃圾回收 * 垃圾回收器找到所有的根,并标记 * 然后标记来自他们的所有引用 * 便利标记的对象,并标记他们的引用,所有遍历到的对象都会被记住,以免将来遍历到同一个对象 * 。。。直到所有可达的从根部的引用都被访问到 * 没有被标记的对象都会被删除 例子: 一个油桶,流经所有引用并标记所有可达的对象,移除没有标记的
- js的优化: * 分代收集: 对象分成新的,旧的。有些对象出现完成他们的工作并很快死去,他们可以被很快清理,长期存活的对象会变得老旧,被查的频率减少 * 增量收集: 一次性太耗时,垃圾收集分成几部分去完成,逐一进行处理,需要他们之间有额外的标记 * 闲时收集: 在cpu闲时尝试运行,减少对代码的执行影响
- 总结: * 1. 垃圾回收时自动完成的,不能强制执行或阻止执行 * 2. 当对象时可达状态时,一定存在内存中 * 3. 被引用与可访问不同,一组相互链接的对象可能整体都时不可达的 牽著幸福的小豬:
原型与原型链
- 所有函数都有一个特别的属性:
prototype: 显式原型属性
- 所有实例对象都有一个特别的属性:
__proto__: 隐式原型属性
- 显式原型与隐式原型的关系
- 函数的prototype: 定义函数时被自动赋值, 值默认为{}, 即用为原型对象
- 实例对象的__proto__: 在创建实例对象时被自动添加, 并赋值为构造函数的prototype值
- 原型对象即为当前实例对象的父对象
- 原型链
- 所有的实例对象都有__proto__属性, 它指向的就是原型对象
- 这样通过__proto__属性就形成了一个链的结构---->原型链
- 当查找对象内部的属性/方法时, js引擎自动沿着这个原型链查找
- 当给对象属性赋值时不会使用原型链, 而只是在当前对象中进行操作
执行上下文与执行上下文栈
- 变量提升与函数提升
- 变量提升: 在变量定义语句之前, 就可以访问到这个变量(undefined)
- 函数提升: 在函数定义语句之前, 就执行该函数
- 先有变量提升, 再有函数提升
- 理解
- 执行上下文: 由js引擎自动创建的对象, 包含对应作用域中的所有变量属性
- 执行上下文栈: 用来管理产生的多个执行上下文
- 分类:
- 全局: window
- 函数: 对程序员来说是透明的
- 生命周期
- 全局 : 准备执行全局代码前产生, 当页面刷新/关闭页面时死亡
- 函数 : 调用函数时产生, 函数执行完时死亡
- 包含哪些属性:
- 全局 :
- 用var定义的全局变量 ==>undefined
- 使用function声明的函数 ===>function
- this ===>window
- 函数
- 用var定义的局部变量 ==>undefined
- 使用function声明的函数 ===>function
- this ===> 调用函数的对象, 如果没有指定就是window
- 形参变量 ===>对应实参值
- arguments ===>实参列表的伪数组
- 全局 :
- 执行上下文创建和初始化的过程
- 全局:
- 在全局代码执行前最先创建一个全局执行上下文(window)
- 收集一些全局变量, 并初始化
- 将这些变量设置为window的属性
- 函数:
- 在调用函数时, 在执行函数体之前先创建一个函数执行上下文
- 收集一些局部变量, 并初始化
- 将这些变量设置为执行上下文的属性
- 全局:
作用域与作用域链
- 理解:
- 作用域: 一块代码区域, 在编码时就确定了, 不会再变化
- 作用域链: 多个嵌套的作用域形成的由内向外的结构, 用于查找变量
- 分类:
- 全局
- 函数
- js没有块作用域(在ES6之前)
- 作用
- 作用域: 隔离变量, 可以在不同作用域定义同名的变量不冲突
- 作用域链: 查找变量
- 区别作用域与执行上下文
- 作用域: 静态的, 编码时就确定了(不是在运行时), 一旦确定就不会变化了
- 执行上下文: 动态的, 执行代码时动态创建, 当执行结束消失
- 联系: 执行上下文环境是在对应的作用域中的
闭包
- 理解:
- 当嵌套的内部函数引用了外部函数的变量时就产生了闭包
- 通过chrome工具得知: 闭包本质是内部函数中的一个对象, 这个对象中包含引用的变量属性
- 作用:
- 延长局部变量的生命周期
- 让函数外部能操作内部的局部变量
- 写一个闭包程序
function fn1() { var a = 2; function fn2() { a++; console.log(a); } return fn2; } var f = fn1(); f(); f(); - 闭包应用:
- 模块化: 封装一些数据以及操作数据的函数, 向外暴露一些行为
- 循环遍历加监听
- JS框架(jQuery)大量使用了闭包
- 缺点:
- 变量占用内存的时间可能会过长
- 可能导致内存泄露
- 解决:
- 及时释放 : f = null; //让内部函数对象成为垃圾对象
内存溢出与内存泄露
- 内存溢出
- 一种程序运行出现的错误
- 当程序运行需要的内存超过了剩余的内存时, 就出抛出内存溢出的错误
- 内存泄露
- 占用的内存没有及时释放
- 内存泄露积累多了就容易导致内存溢出
- 常见的内存泄露:
- 意外的全局变量
- 没有及时清理的计时器或回调函数
- 闭包
牽著幸福的小豬:
HTML, CSS
- html的语义化:
- 用正确的标签做正确的事情,根据内容的结构化,选择合适的标签
- 便于开发者阅读和写出优雅的代码,便于浏览器的爬虫更好的解析
- 原因:用户体验;有利于seo,便于团队开发
- postion的理解:
- relative:相对于自身原来的位置定位,不脱离文档流
- absolute: a)父元素(relative) - 相对于父元素定位,脱离文档流 b)父元素:无 - 相对于body定位,脱离文档流
- static: 默认
- fixed: 固定定位,相对于浏览器定位,脱离文档流
- inherit:继承父级的positon属性
- initial: 默认值
- 盒模型:
- 标准盒模型:content-box:width = div的宽度
- 怪异盒模型: boxder-box: width = content + padding + border
- 获取元素的宽度: dom.offsetWidth = dom.getBoundingClientRect().width;
- 行内元素和块级元素:
- 行内元素:不能设置宽,高,与其他行内元素位于同一行,一般不在里面嵌套块级元素
- 例如:span, input, label, select, img, textarea, em, strong, i
- 块级元素: 排斥其他元素同行,可设置狂傲,可容纳块,行内元素
- 例如: h1--h6, p, div, dl, dt, dv, ol, ul, li, table, td, th
- 区别:
- 块级元素独占一行,行内元素多个可排成一排;
- 块级元素可设置狂傲,行内元素不能设置宽高;
- 块级元素可以包含块级,行内, 行内元素一般包含行内的和文本
- 块级元素可以设置padding,margin, 行内元素只能设置padding和margin的left/right
- 行内元素:不能设置宽,高,与其他行内元素位于同一行,一般不在里面嵌套块级元素
- BFC(块级格式化上下文)
- 概念:页面的一个独立的渲染区域,容器里面的自元素不会在布局上影响外面的元素,决定块级盒子的浮动,布局的因素
- 触发条件:
- float浮动
- 绝对定位(absolute, fixed)
- 行内块元素(inline-block, table-cell)
- overflo的值不为visible的块元素
- 弹性元素,display:flex/inline-flex
- BFC作用
- 解决上下两个相邻元素的重叠问题(垂直margin合并的问题)
- 正数时:两者之前取最大
- 负数时:绝对值取较大的
- 一正一负: 两者的和
- 清除内部浮动问题
- 解决上下两个相邻元素的重叠问题(垂直margin合并的问题)
- BFC的原理
- BFC不会与float的元素重叠,BFC下的编剧也不会重叠,BFC是一个独立的容器和外面的容器互不干扰,计算BFC的高度,浮动的子元素也会参与
- CSS的动画效果animation
- @keyframes 'loop' {0% {}; 50% {}; 100% {}}
- 伪类的元素: nth-child(even) / nth-child(old)
- css的选择器的优先级:
- 如果多重样式: 外部样式 < 内部样式 < 内联样式
- 注意: 外部样式放在内部样式的后面,则会覆盖;
- 选择器的优先级:
- 内联样式 > id选择器 > 类选择器 > 元素选择器
- 总结
- 越具体优先级越高
- 同样优先级写在后面的覆盖前面的
- !important的优先级最高,但是少用
- 清除浮动的方法:
- overflow: hidden
- clearfix:after { content: '', display: block, clear: both } }
- 父元素给个固定高度
牽著幸福的小豬:
闭包
- 定义:
- 函数和函数内部能访问的变量的总和,就是闭包;
- 当嵌套的内部函数引入用了外部函数的变量
- 本质:内部函数中的一个对象,这个对象中包含了引用的变量属性
- 从技术的角度讲,所有的JavaScript函数都是闭包:它们都是对象,它们都关联到作用域链。
- 作用
- 让函数外部能操作内部的局部变量
- 延长局部变量的生命周期
- 闭包应用:
- 模块化: 封装一些数据以及操作数据的函数, 向外暴露一些行为
- 循环遍历加监听
- JS框架(jQuery)大量使用了闭包
- 缺点:
- 变量占用内存的时间可能会过长
- 可能导致内存泄露
- 解决:
- 及时释放 : f = null; //让内部函数对象成为垃圾对象
内存溢出与内存泄露
- 内存溢出
- 一种程序运行出现的错误
- 当程序运行需要的内存超过了剩余的内存时, 就出抛出内存溢出的错误
- 内存泄露
- 占用的内存没有及时释放
- 内存泄露积累多了就容易导致内存溢出
- 常见的内存泄露:
- 意外的全局变量
- 没有及时清理的计时器或回调函数
- 闭包
立即执行函数
- 定义:声明一个函数,并立即调用这个函数
- 作用:创建一个独立的作用域,这个作用域内的变量,外面访问不到,避免全剧污染
promise的理解
- Promise 是异步编程的一种解决方案,其实是一个构造函数,自己身上有all、reject、resolve这几个方法,有then、catch、finally等方法
- 特点:
- 对象的状态不受外界影响
- 一旦状态改变,就不会再变,任何时候都可以得到这个结果
- promise的其他api
- promise.all
- promise.race
async/await
- 捕获异常: try ... catch
- ().then 后面可以捕获异常
浅拷贝和深拷贝
- 浅拷贝
- 浅拷贝是拷贝一层,深层次的对象级别的就拷贝引用;
- 浅拷贝的时候如果数据是基本数据类型,直接赋值,会拷贝其本身;
- 如果除了基本数据类型之外还有一层对象,那么对于浅拷贝而言就只能拷贝其引用,对象的改变会反应到拷贝对象上;
- 浅拷贝的方法:
- Object.assign(target, ...sources)
- target:目标对象, sources:任意多个源对象,返回值:目标对象会被返回
- Object.assign(target, ...sources)
- 浅拷贝是拷贝一层,深层次的对象级别的就拷贝引用;
- 深拷贝
- 深拷贝是拷贝多层,每一级别的数据都会拷贝出来
- 深拷贝就会拷贝多层,即使是嵌套了对象,也会都拷贝出来。
- 方法
- 对象只有一层的话: Object.assign()函数
- JSON.parse(JSON.stringify(obj))
- 缺点:会抛弃对象的constructor。也就是深拷贝之后,不管这个对象原来的构造函数是什么,在深拷贝之后都会变成Object。
- 递归拷贝
- 使用Object.create()方法
- 直接使用var newObj = Object.create(oldObj),可以达到深拷贝的效果。
- 深拷贝是拷贝多层,每一级别的数据都会拷贝出来
js的垃圾回收机制
- js的内存管理是自动的,无形的,创建的原始值,对象,函数,,,都是会占用内存。
- js的内存管理的可达性:是以某种方式可访问的值,一定存在内存中;
- 可达性分类:
* 固有的可达值的基本集合,明显不会被释放
- 函数的局部变量、函数根(roots)
- 嵌套调用时,调用连上所有的函数的变量与参数根(roots)
- 全局变量
- 内部的根(roots) * 一个值可以通过引用和引用连从根访问任何值,该值也是可达的
- 全局变量中有个属性,该对象的一个属性引用了另一个对象,该对象也是可达的
- 例子1
let user = { name: 'John'};
John = null;
- 不可达,没有引用,不能访问,垃圾回收器会认为是垃圾数据并进行回收,释放内存
- 例子2
let user = { name: 'John'};
let admin = user;
user = null;
- 对象可以通过admin访问,对象还存在内存中,若admin= null,对象就会被删除
- 例子1
let user = { name: 'John'};
John = null;
- 垃圾会是的内部算法 ---》 定期执行垃圾回收 * 垃圾回收器找到所有的根,并标记 * 然后标记来自他们的所有引用 * 便利标记的对象,并标记他们的引用,所有遍历到的对象都会被记住,以免将来遍历到同一个对象 * 。。。直到所有可达的从根部的引用都被访问到 * 没有被标记的对象都会被删除 例子: 一个油桶,流经所有引用并标记所有可达的对象,移除没有标记的
- js的优化: * 分代收集: 对象分成新的,旧的。有些对象出现完成他们的工作并很快死去,他们可以被很快清理,长期存活的对象会变得老旧,被查的频率减少 * 增量收集: 一次性太耗时,垃圾收集分成几部分去完成,逐一进行处理,需要他们之间有额外的标记 * 闲时收集: 在cpu闲时尝试运行,减少对代码的执行影响
- 总结: * 1. 垃圾回收时自动完成的,不能强制执行或阻止执行 * 2. 当对象时可达状态时,一定存在内存中 * 3. 被引用与可访问不同,一组相互链接的对象可能整体都时不可达的 牽著幸福的小豬:
原型与原型链
- 所有函数都有一个特别的属性:
prototype: 显式原型属性
- 所有实例对象都有一个特别的属性:
__proto__: 隐式原型属性
- 显式原型与隐式原型的关系
- 函数的prototype: 定义函数时被自动赋值, 值默认为{}, 即用为原型对象
- 实例对象的__proto__: 在创建实例对象时被自动添加, 并赋值为构造函数的prototype值
- 原型对象即为当前实例对象的父对象
- 原型链
- 所有的实例对象都有__proto__属性, 它指向的就是原型对象
- 这样通过__proto__属性就形成了一个链的结构---->原型链
- 当查找对象内部的属性/方法时, js引擎自动沿着这个原型链查找
- 当给对象属性赋值时不会使用原型链, 而只是在当前对象中进行操作
执行上下文与执行上下文栈
- 变量提升与函数提升
- 变量提升: 在变量定义语句之前, 就可以访问到这个变量(undefined)
- 函数提升: 在函数定义语句之前, 就执行该函数
- 先有变量提升, 再有函数提升
- 理解
- 执行上下文: 由js引擎自动创建的对象, 包含对应作用域中的所有变量属性
- 执行上下文栈: 用来管理产生的多个执行上下文
- 分类:
- 全局: window
- 函数: 对程序员来说是透明的
- 生命周期
- 全局 : 准备执行全局代码前产生, 当页面刷新/关闭页面时死亡
- 函数 : 调用函数时产生, 函数执行完时死亡
- 包含哪些属性:
- 全局 :
- 用var定义的全局变量 ==>undefined
- 使用function声明的函数 ===>function
- this ===>window
- 函数
- 用var定义的局部变量 ==>undefined
- 使用function声明的函数 ===>function
- this ===> 调用函数的对象, 如果没有指定就是window
- 形参变量 ===>对应实参值
- arguments ===>实参列表的伪数组
- 全局 :
- 执行上下文创建和初始化的过程
- 全局:
- 在全局代码执行前最先创建一个全局执行上下文(window)
- 收集一些全局变量, 并初始化
- 将这些变量设置为window的属性
- 函数:
- 在调用函数时, 在执行函数体之前先创建一个函数执行上下文
- 收集一些局部变量, 并初始化
- 将这些变量设置为执行上下文的属性
- 全局:
作用域与作用域链
- 理解:
- 作用域: 一块代码区域, 在编码时就确定了, 不会再变化
- 作用域链: 多个嵌套的作用域形成的由内向外的结构, 用于查找变量
- 分类:
- 全局
- 函数
- js没有块作用域(在ES6之前)
- 作用
- 作用域: 隔离变量, 可以在不同作用域定义同名的变量不冲突
- 作用域链: 查找变量
- 区别作用域与执行上下文
- 作用域: 静态的, 编码时就确定了(不是在运行时), 一旦确定就不会变化了
- 执行上下文: 动态的, 执行代码时动态创建, 当执行结束消失
- 联系: 执行上下文环境是在对应的作用域中的
闭包
- 理解:
- 当嵌套的内部函数引用了外部函数的变量时就产生了闭包
- 通过chrome工具得知: 闭包本质是内部函数中的一个对象, 这个对象中包含引用的变量属性
- 作用:
- 延长局部变量的生命周期
- 让函数外部能操作内部的局部变量
- 写一个闭包程序
function fn1() { var a = 2; function fn2() { a++; console.log(a); } return fn2; } var f = fn1(); f(); f(); - 闭包应用:
- 模块化: 封装一些数据以及操作数据的函数, 向外暴露一些行为
- 循环遍历加监听
- JS框架(jQuery)大量使用了闭包
- 缺点:
- 变量占用内存的时间可能会过长
- 可能导致内存泄露
- 解决:
- 及时释放 : f = null; //让内部函数对象成为垃圾对象
内存溢出与内存泄露
- 内存溢出
- 一种程序运行出现的错误
- 当程序运行需要的内存超过了剩余的内存时, 就出抛出内存溢出的错误
- 内存泄露
- 占用的内存没有及时释放
- 内存泄露积累多了就容易导致内存溢出
- 常见的内存泄露:
- 意外的全局变量
- 没有及时清理的计时器或回调函数
- 闭包
牽著幸福的小豬:
HTML, CSS
- html的语义化:
- 用正确的标签做正确的事情,根据内容的结构化,选择合适的标签
- 便于开发者阅读和写出优雅的代码,便于浏览器的爬虫更好的解析
- 原因:用户体验;有利于seo,便于团队开发
- postion的理解:
- relative:相对于自身原来的位置定位,不脱离文档流
- absolute: a)父元素(relative) - 相对于父元素定位,脱离文档流 b)父元素:无 - 相对于body定位,脱离文档流
- static: 默认
- fixed: 固定定位,相对于浏览器定位,脱离文档流
- inherit:继承父级的positon属性
- initial: 默认值
- 盒模型:
- 标准盒模型:content-box:width = div的宽度
- 怪异盒模型: boxder-box: width = content + padding + border
- 获取元素的宽度: dom.offsetWidth = dom.getBoundingClientRect().width;
- 行内元素和块级元素:
- 行内元素:不能设置宽,高,与其他行内元素位于同一行,一般不在里面嵌套块级元素
- 例如:span, input, label, select, img, textarea, em, strong, i
- 块级元素: 排斥其他元素同行,可设置狂傲,可容纳块,行内元素
- 例如: h1--h6, p, div, dl, dt, dv, ol, ul, li, table, td, th
- 区别:
- 块级元素独占一行,行内元素多个可排成一排;
- 块级元素可设置狂傲,行内元素不能设置宽高;
- 块级元素可以包含块级,行内, 行内元素一般包含行内的和文本
- 块级元素可以设置padding,margin, 行内元素只能设置padding和margin的left/right
- 行内元素:不能设置宽,高,与其他行内元素位于同一行,一般不在里面嵌套块级元素
- BFC(块级格式化上下文)
- 概念:页面的一个独立的渲染区域,容器里面的自元素不会在布局上影响外面的元素,决定块级盒子的浮动,布局的因素
- 触发条件:
- float浮动
- 绝对定位(absolute, fixed)
- 行内块元素(inline-block, table-cell)
- overflo的值不为visible的块元素
- 弹性元素,display:flex/inline-flex
- BFC作用
- 解决上下两个相邻元素的重叠问题(垂直margin合并的问题)
- 正数时:两者之前取最大
- 负数时:绝对值取较大的
- 一正一负: 两者的和
- 清除内部浮动问题
- 解决上下两个相邻元素的重叠问题(垂直margin合并的问题)
- BFC的原理
- BFC不会与float的元素重叠,BFC下的编剧也不会重叠,BFC是一个独立的容器和外面的容器互不干扰,计算BFC的高度,浮动的子元素也会参与
- CSS的动画效果animation
- @keyframes 'loop' {0% {}; 50% {}; 100% {}}
- 伪类的元素: nth-child(even) / nth-child(old)
- css的选择器的优先级:
- 如果多重样式: 外部样式 < 内部样式 < 内联样式
- 注意: 外部样式放在内部样式的后面,则会覆盖;
- 选择器的优先级:
- 内联样式 > id选择器 > 类选择器 > 元素选择器
- 总结
- 越具体优先级越高
- 同样优先级写在后面的覆盖前面的
- !important的优先级最高,但是少用
- 清除浮动的方法:
- overflow: hidden
- clearfix:after { content: '', display: block, clear: both } }
- 父元素给个固定高度
牽著幸福的小豬:
闭包
- 定义:
- 函数和函数内部能访问的变量的总和,就是闭包;
- 当嵌套的内部函数引入用了外部函数的变量
- 本质:内部函数中的一个对象,这个对象中包含了引用的变量属性
- 从技术的角度讲,所有的JavaScript函数都是闭包:它们都是对象,它们都关联到作用域链。
- 作用
- 让函数外部能操作内部的局部变量
- 延长局部变量的生命周期
- 闭包应用:
- 模块化: 封装一些数据以及操作数据的函数, 向外暴露一些行为
- 循环遍历加监听
- JS框架(jQuery)大量使用了闭包
- 缺点:
- 变量占用内存的时间可能会过长
- 可能导致内存泄露
- 解决:
- 及时释放 : f = null; //让内部函数对象成为垃圾对象
内存溢出与内存泄露
- 内存溢出
- 一种程序运行出现的错误
- 当程序运行需要的内存超过了剩余的内存时, 就出抛出内存溢出的错误
- 内存泄露
- 占用的内存没有及时释放
- 内存泄露积累多了就容易导致内存溢出
- 常见的内存泄露:
- 意外的全局变量
- 没有及时清理的计时器或回调函数
- 闭包
立即执行函数
- 定义:声明一个函数,并立即调用这个函数
- 作用:创建一个独立的作用域,这个作用域内的变量,外面访问不到,避免全剧污染
promise的理解
- Promise 是异步编程的一种解决方案,其实是一个构造函数,自己身上有all、reject、resolve这几个方法,有then、catch、finally等方法
- 特点:
- 对象的状态不受外界影响
- 一旦状态改变,就不会再变,任何时候都可以得到这个结果
- promise的其他api
- promise.all
- promise.race
async/await
- 捕获异常: try ... catch
- ().then 后面可以捕获异常
浅拷贝和深拷贝
- 浅拷贝
- 浅拷贝是拷贝一层,深层次的对象级别的就拷贝引用;
- 浅拷贝的时候如果数据是基本数据类型,直接赋值,会拷贝其本身;
- 如果除了基本数据类型之外还有一层对象,那么对于浅拷贝而言就只能拷贝其引用,对象的改变会反应到拷贝对象上;
- 浅拷贝的方法:
- Object.assign(target, ...sources)
- target:目标对象, sources:任意多个源对象,返回值:目标对象会被返回
- Object.assign(target, ...sources)
- 浅拷贝是拷贝一层,深层次的对象级别的就拷贝引用;
- 深拷贝
- 深拷贝是拷贝多层,每一级别的数据都会拷贝出来
- 深拷贝就会拷贝多层,即使是嵌套了对象,也会都拷贝出来。
- 方法
- 对象只有一层的话: Object.assign()函数
- JSON.parse(JSON.stringify(obj))
- 缺点:会抛弃对象的constructor。也就是深拷贝之后,不管这个对象原来的构造函数是什么,在深拷贝之后都会变成Object。
- 递归拷贝
- 使用Object.create()方法
- 直接使用var newObj = Object.create(oldObj),可以达到深拷贝的效果。
- 深拷贝是拷贝多层,每一级别的数据都会拷贝出来
js的垃圾回收机制
- js的内存管理是自动的,无形的,创建的原始值,对象,函数,,,都是会占用内存。
- js的内存管理的可达性:是以某种方式可访问的值,一定存在内存中;
- 可达性分类:
* 固有的可达值的基本集合,明显不会被释放
- 函数的局部变量、函数根(roots)
- 嵌套调用时,调用连上所有的函数的变量与参数根(roots)
- 全局变量
- 内部的根(roots) * 一个值可以通过引用和引用连从根访问任何值,该值也是可达的
- 全局变量中有个属性,该对象的一个属性引用了另一个对象,该对象也是可达的
- 例子1
let user = { name: 'John'};
John = null;
- 不可达,没有引用,不能访问,垃圾回收器会认为是垃圾数据并进行回收,释放内存
- 例子2
let user = { name: 'John'};
let admin = user;
user = null;
- 对象可以通过admin访问,对象还存在内存中,若admin= null,对象就会被删除
- 例子1
let user = { name: 'John'};
John = null;
- 垃圾会是的内部算法 ---》 定期执行垃圾回收 * 垃圾回收器找到所有的根,并标记 * 然后标记来自他们的所有引用 * 便利标记的对象,并标记他们的引用,所有遍历到的对象都会被记住,以免将来遍历到同一个对象 * 。。。直到所有可达的从根部的引用都被访问到 * 没有被标记的对象都会被删除 例子: 一个油桶,流经所有引用并标记所有可达的对象,移除没有标记的
- js的优化: * 分代收集: 对象分成新的,旧的。有些对象出现完成他们的工作并很快死去,他们可以被很快清理,长期存活的对象会变得老旧,被查的频率减少 * 增量收集: 一次性太耗时,垃圾收集分成几部分去完成,逐一进行处理,需要他们之间有额外的标记 * 闲时收集: 在cpu闲时尝试运行,减少对代码的执行影响
- 总结: * 1. 垃圾回收时自动完成的,不能强制执行或阻止执行 * 2. 当对象时可达状态时,一定存在内存中 * 3. 被引用与可访问不同,一组相互链接的对象可能整体都时不可达的 牽著幸福的小豬:
原型与原型链
- 所有函数都有一个特别的属性:
prototype: 显式原型属性
- 所有实例对象都有一个特别的属性:
__proto__: 隐式原型属性
- 显式原型与隐式原型的关系
- 函数的prototype: 定义函数时被自动赋值, 值默认为{}, 即用为原型对象
- 实例对象的__proto__: 在创建实例对象时被自动添加, 并赋值为构造函数的prototype值
- 原型对象即为当前实例对象的父对象
- 原型链
- 所有的实例对象都有__proto__属性, 它指向的就是原型对象
- 这样通过__proto__属性就形成了一个链的结构---->原型链
- 当查找对象内部的属性/方法时, js引擎自动沿着这个原型链查找
- 当给对象属性赋值时不会使用原型链, 而只是在当前对象中进行操作
执行上下文与执行上下文栈
- 变量提升与函数提升
- 变量提升: 在变量定义语句之前, 就可以访问到这个变量(undefined)
- 函数提升: 在函数定义语句之前, 就执行该函数
- 先有变量提升, 再有函数提升
- 理解
- 执行上下文: 由js引擎自动创建的对象, 包含对应作用域中的所有变量属性
- 执行上下文栈: 用来管理产生的多个执行上下文
- 分类:
- 全局: window
- 函数: 对程序员来说是透明的
- 生命周期
- 全局 : 准备执行全局代码前产生, 当页面刷新/关闭页面时死亡
- 函数 : 调用函数时产生, 函数执行完时死亡
- 包含哪些属性:
- 全局 :
- 用var定义的全局变量 ==>undefined
- 使用function声明的函数 ===>function
- this ===>window
- 函数
- 用var定义的局部变量 ==>undefined
- 使用function声明的函数 ===>function
- this ===> 调用函数的对象, 如果没有指定就是window
- 形参变量 ===>对应实参值
- arguments ===>实参列表的伪数组
- 全局 :
- 执行上下文创建和初始化的过程
- 全局:
- 在全局代码执行前最先创建一个全局执行上下文(window)
- 收集一些全局变量, 并初始化
- 将这些变量设置为window的属性
- 函数:
- 在调用函数时, 在执行函数体之前先创建一个函数执行上下文
- 收集一些局部变量, 并初始化
- 将这些变量设置为执行上下文的属性
- 全局:
作用域与作用域链
- 理解:
- 作用域: 一块代码区域, 在编码时就确定了, 不会再变化
- 作用域链: 多个嵌套的作用域形成的由内向外的结构, 用于查找变量
- 分类:
- 全局
- 函数
- js没有块作用域(在ES6之前)
- 作用
- 作用域: 隔离变量, 可以在不同作用域定义同名的变量不冲突
- 作用域链: 查找变量
- 区别作用域与执行上下文
- 作用域: 静态的, 编码时就确定了(不是在运行时), 一旦确定就不会变化了
- 执行上下文: 动态的, 执行代码时动态创建, 当执行结束消失
- 联系: 执行上下文环境是在对应的作用域中的
闭包
- 理解:
- 当嵌套的内部函数引用了外部函数的变量时就产生了闭包
- 通过chrome工具得知: 闭包本质是内部函数中的一个对象, 这个对象中包含引用的变量属性
- 作用:
- 延长局部变量的生命周期
- 让函数外部能操作内部的局部变量
- 写一个闭包程序
function fn1() { var a = 2; function fn2() { a++; console.log(a); } return fn2; } var f = fn1(); f(); f(); - 闭包应用:
- 模块化: 封装一些数据以及操作数据的函数, 向外暴露一些行为
- 循环遍历加监听
- JS框架(jQuery)大量使用了闭包
- 缺点:
- 变量占用内存的时间可能会过长
- 可能导致内存泄露
- 解决:
- 及时释放 : f = null; //让内部函数对象成为垃圾对象
内存溢出与内存泄露
- 内存溢出
- 一种程序运行出现的错误
- 当程序运行需要的内存超过了剩余的内存时, 就出抛出内存溢出的错误
- 内存泄露
- 占用的内存没有及时释放
- 内存泄露积累多了就容易导致内存溢出
- 常见的内存泄露:
- 意外的全局变量
- 没有及时清理的计时器或回调函数
- 闭包
牽著幸福的小豬:
HTML, CSS
- html的语义化:
- 用正确的标签做正确的事情,根据内容的结构化,选择合适的标签
- 便于开发者阅读和写出优雅的代码,便于浏览器的爬虫更好的解析
- 原因:用户体验;有利于seo,便于团队开发
- postion的理解:
- relative:相对于自身原来的位置定位,不脱离文档流
- absolute: a)父元素(relative) - 相对于父元素定位,脱离文档流 b)父元素:无 - 相对于body定位,脱离文档流
- static: 默认
- fixed: 固定定位,相对于浏览器定位,脱离文档流
- inherit:继承父级的positon属性
- initial: 默认值
- 盒模型:
- 标准盒模型:content-box:width = div的宽度
- 怪异盒模型: boxder-box: width = content + padding + border
- 获取元素的宽度: dom.offsetWidth = dom.getBoundingClientRect().width;
- 行内元素和块级元素:
- 行内元素:不能设置宽,高,与其他行内元素位于同一行,一般不在里面嵌套块级元素
- 例如:span, input, label, select, img, textarea, em, strong, i
- 块级元素: 排斥其他元素同行,可设置狂傲,可容纳块,行内元素
- 例如: h1--h6, p, div, dl, dt, dv, ol, ul, li, table, td, th
- 区别:
- 块级元素独占一行,行内元素多个可排成一排;
- 块级元素可设置狂傲,行内元素不能设置宽高;
- 块级元素可以包含块级,行内, 行内元素一般包含行内的和文本
- 块级元素可以设置padding,margin, 行内元素只能设置padding和margin的left/right
- 行内元素:不能设置宽,高,与其他行内元素位于同一行,一般不在里面嵌套块级元素
- BFC(块级格式化上下文)
- 概念:页面的一个独立的渲染区域,容器里面的自元素不会在布局上影响外面的元素,决定块级盒子的浮动,布局的因素
- 触发条件:
- float浮动
- 绝对定位(absolute, fixed)
- 行内块元素(inline-block, table-cell)
- overflo的值不为visible的块元素
- 弹性元素,display:flex/inline-flex
- BFC作用
- 解决上下两个相邻元素的重叠问题(垂直margin合并的问题)
- 正数时:两者之前取最大
- 负数时:绝对值取较大的
- 一正一负: 两者的和
- 清除内部浮动问题
- 解决上下两个相邻元素的重叠问题(垂直margin合并的问题)
- BFC的原理
- BFC不会与float的元素重叠,BFC下的编剧也不会重叠,BFC是一个独立的容器和外面的容器互不干扰,计算BFC的高度,浮动的子元素也会参与
- CSS的动画效果animation
- @keyframes 'loop' {0% {}; 50% {}; 100% {}}
- 伪类的元素: nth-child(even) / nth-child(old)
- css的选择器的优先级:
- 如果多重样式: 外部样式 < 内部样式 < 内联样式
- 注意: 外部样式放在内部样式的后面,则会覆盖;
- 选择器的优先级:
- 内联样式 > id选择器 > 类选择器 > 元素选择器
- 总结
- 越具体优先级越高
- 同样优先级写在后面的覆盖前面的
- !important的优先级最高,但是少用
- 清除浮动的方法:
- overflow: hidden
- clearfix:after { content: '', display: block, clear: both } }
- 父元素给个固定高度
牽著幸福的小豬:
闭包
- 定义:
- 函数和函数内部能访问的变量的总和,就是闭包;
- 当嵌套的内部函数引入用了外部函数的变量
- 本质:内部函数中的一个对象,这个对象中包含了引用的变量属性
- 从技术的角度讲,所有的JavaScript函数都是闭包:它们都是对象,它们都关联到作用域链。
- 作用
- 让函数外部能操作内部的局部变量
- 延长局部变量的生命周期
- 闭包应用:
- 模块化: 封装一些数据以及操作数据的函数, 向外暴露一些行为
- 循环遍历加监听
- JS框架(jQuery)大量使用了闭包
- 缺点:
- 变量占用内存的时间可能会过长
- 可能导致内存泄露
- 解决:
- 及时释放 : f = null; //让内部函数对象成为垃圾对象
内存溢出与内存泄露
- 内存溢出
- 一种程序运行出现的错误
- 当程序运行需要的内存超过了剩余的内存时, 就出抛出内存溢出的错误
- 内存泄露
- 占用的内存没有及时释放
- 内存泄露积累多了就容易导致内存溢出
- 常见的内存泄露:
- 意外的全局变量
- 没有及时清理的计时器或回调函数
- 闭包
立即执行函数
- 定义:声明一个函数,并立即调用这个函数
- 作用:创建一个独立的作用域,这个作用域内的变量,外面访问不到,避免全剧污染
promise的理解
- Promise 是异步编程的一种解决方案,其实是一个构造函数,自己身上有all、reject、resolve这几个方法,有then、catch、finally等方法
- 特点:
- 对象的状态不受外界影响
- 一旦状态改变,就不会再变,任何时候都可以得到这个结果
- promise的其他api
- promise.all
- promise.race
async/await
- 捕获异常: try ... catch
- ().then 后面可以捕获异常
浅拷贝和深拷贝
- 浅拷贝
- 浅拷贝是拷贝一层,深层次的对象级别的就拷贝引用;
- 浅拷贝的时候如果数据是基本数据类型,直接赋值,会拷贝其本身;
- 如果除了基本数据类型之外还有一层对象,那么对于浅拷贝而言就只能拷贝其引用,对象的改变会反应到拷贝对象上;
- 浅拷贝的方法:
- Object.assign(target, ...sources)
- target:目标对象, sources:任意多个源对象,返回值:目标对象会被返回
- Object.assign(target, ...sources)
- 浅拷贝是拷贝一层,深层次的对象级别的就拷贝引用;
- 深拷贝
- 深拷贝是拷贝多层,每一级别的数据都会拷贝出来
- 深拷贝就会拷贝多层,即使是嵌套了对象,也会都拷贝出来。
- 方法
- 对象只有一层的话: Object.assign()函数
- JSON.parse(JSON.stringify(obj))
- 缺点:会抛弃对象的constructor。也就是深拷贝之后,不管这个对象原来的构造函数是什么,在深拷贝之后都会变成Object。
- 递归拷贝
- 使用Object.create()方法
- 直接使用var newObj = Object.create(oldObj),可以达到深拷贝的效果。
- 深拷贝是拷贝多层,每一级别的数据都会拷贝出来
js的垃圾回收机制
- js的内存管理是自动的,无形的,创建的原始值,对象,函数,,,都是会占用内存。
- js的内存管理的可达性:是以某种方式可访问的值,一定存在内存中;
- 可达性分类:
* 固有的可达值的基本集合,明显不会被释放
- 函数的局部变量、函数根(roots)
- 嵌套调用时,调用连上所有的函数的变量与参数根(roots)
- 全局变量
- 内部的根(roots) * 一个值可以通过引用和引用连从根访问任何值,该值也是可达的
- 全局变量中有个属性,该对象的一个属性引用了另一个对象,该对象也是可达的
- 例子1
let user = { name: 'John'};
John = null;
- 不可达,没有引用,不能访问,垃圾回收器会认为是垃圾数据并进行回收,释放内存
- 例子2
let user = { name: 'John'};
let admin = user;
user = null;
- 对象可以通过admin访问,对象还存在内存中,若admin= null,对象就会被删除
- 例子1
let user = { name: 'John'};
John = null;
- 垃圾会是的内部算法 ---》 定期执行垃圾回收 * 垃圾回收器找到所有的根,并标记 * 然后标记来自他们的所有引用 * 便利标记的对象,并标记他们的引用,所有遍历到的对象都会被记住,以免将来遍历到同一个对象 * 。。。直到所有可达的从根部的引用都被访问到 * 没有被标记的对象都会被删除 例子: 一个油桶,流经所有引用并标记所有可达的对象,移除没有标记的
- js的优化: * 分代收集: 对象分成新的,旧的。有些对象出现完成他们的工作并很快死去,他们可以被很快清理,长期存活的对象会变得老旧,被查的频率减少 * 增量收集: 一次性太耗时,垃圾收集分成几部分去完成,逐一进行处理,需要他们之间有额外的标记 * 闲时收集: 在cpu闲时尝试运行,减少对代码的执行影响
- 总结: * 1. 垃圾回收时自动完成的,不能强制执行或阻止执行 * 2. 当对象时可达状态时,一定存在内存中 * 3. 被引用与可访问不同,一组相互链接的对象可能整体都时不可达的 牽著幸福的小豬:
原型与原型链
- 所有函数都有一个特别的属性:
prototype: 显式原型属性
- 所有实例对象都有一个特别的属性:
__proto__: 隐式原型属性
- 显式原型与隐式原型的关系
- 函数的prototype: 定义函数时被自动赋值, 值默认为{}, 即用为原型对象
- 实例对象的__proto__: 在创建实例对象时被自动添加, 并赋值为构造函数的prototype值
- 原型对象即为当前实例对象的父对象
- 原型链
- 所有的实例对象都有__proto__属性, 它指向的就是原型对象
- 这样通过__proto__属性就形成了一个链的结构---->原型链
- 当查找对象内部的属性/方法时, js引擎自动沿着这个原型链查找
- 当给对象属性赋值时不会使用原型链, 而只是在当前对象中进行操作
执行上下文与执行上下文栈
- 变量提升与函数提升
- 变量提升: 在变量定义语句之前, 就可以访问到这个变量(undefined)
- 函数提升: 在函数定义语句之前, 就执行该函数
- 先有变量提升, 再有函数提升
- 理解
- 执行上下文: 由js引擎自动创建的对象, 包含对应作用域中的所有变量属性
- 执行上下文栈: 用来管理产生的多个执行上下文
- 分类:
- 全局: window
- 函数: 对程序员来说是透明的
- 生命周期
- 全局 : 准备执行全局代码前产生, 当页面刷新/关闭页面时死亡
- 函数 : 调用函数时产生, 函数执行完时死亡
- 包含哪些属性:
- 全局 :
- 用var定义的全局变量 ==>undefined
- 使用function声明的函数 ===>function
- this ===>window
- 函数
- 用var定义的局部变量 ==>undefined
- 使用function声明的函数 ===>function
- this ===> 调用函数的对象, 如果没有指定就是window
- 形参变量 ===>对应实参值
- arguments ===>实参列表的伪数组
- 全局 :
- 执行上下文创建和初始化的过程
- 全局:
- 在全局代码执行前最先创建一个全局执行上下文(window)
- 收集一些全局变量, 并初始化
- 将这些变量设置为window的属性
- 函数:
- 在调用函数时, 在执行函数体之前先创建一个函数执行上下文
- 收集一些局部变量, 并初始化
- 将这些变量设置为执行上下文的属性
- 全局:
作用域与作用域链
- 理解:
- 作用域: 一块代码区域, 在编码时就确定了, 不会再变化
- 作用域链: 多个嵌套的作用域形成的由内向外的结构, 用于查找变量
- 分类:
- 全局
- 函数
- js没有块作用域(在ES6之前)
- 作用
- 作用域: 隔离变量, 可以在不同作用域定义同名的变量不冲突
- 作用域链: 查找变量
- 区别作用域与执行上下文
- 作用域: 静态的, 编码时就确定了(不是在运行时), 一旦确定就不会变化了
- 执行上下文: 动态的, 执行代码时动态创建, 当执行结束消失
- 联系: 执行上下文环境是在对应的作用域中的
闭包
- 理解:
- 当嵌套的内部函数引用了外部函数的变量时就产生了闭包
- 通过chrome工具得知: 闭包本质是内部函数中的一个对象, 这个对象中包含引用的变量属性
- 作用:
- 延长局部变量的生命周期
- 让函数外部能操作内部的局部变量
- 写一个闭包程序
function fn1() { var a = 2; function fn2() { a++; console.log(a); } return fn2; } var f = fn1(); f(); f(); - 闭包应用:
- 模块化: 封装一些数据以及操作数据的函数, 向外暴露一些行为
- 循环遍历加监听
- JS框架(jQuery)大量使用了闭包
- 缺点:
- 变量占用内存的时间可能会过长
- 可能导致内存泄露
- 解决:
- 及时释放 : f = null; //让内部函数对象成为垃圾对象
内存溢出与内存泄露
- 内存溢出
- 一种程序运行出现的错误
- 当程序运行需要的内存超过了剩余的内存时, 就出抛出内存溢出的错误
- 内存泄露
- 占用的内存没有及时释放
- 内存泄露积累多了就容易导致内存溢出
- 常见的内存泄露:
- 意外的全局变量
- 没有及时清理的计时器或回调函数
- 闭包
牽著幸福的小豬:
HTML, CSS
- html的语义化:
- 用正确的标签做正确的事情,根据内容的结构化,选择合适的标签
- 便于开发者阅读和写出优雅的代码,便于浏览器的爬虫更好的解析
- 原因:用户体验;有利于seo,便于团队开发
- postion的理解:
- relative:相对于自身原来的位置定位,不脱离文档流
- absolute: a)父元素(relative) - 相对于父元素定位,脱离文档流 b)父元素:无 - 相对于body定位,脱离文档流
- static: 默认
- fixed: 固定定位,相对于浏览器定位,脱离文档流
- inherit:继承父级的positon属性
- initial: 默认值
- 盒模型:
- 标准盒模型:content-box:width = div的宽度
- 怪异盒模型: boxder-box: width = content + padding + border
- 获取元素的宽度: dom.offsetWidth = dom.getBoundingClientRect().width;
- 行内元素和块级元素:
- 行内元素:不能设置宽,高,与其他行内元素位于同一行,一般不在里面嵌套块级元素
- 例如:span, input, label, select, img, textarea, em, strong, i
- 块级元素: 排斥其他元素同行,可设置狂傲,可容纳块,行内元素
- 例如: h1--h6, p, div, dl, dt, dv, ol, ul, li, table, td, th
- 区别:
- 块级元素独占一行,行内元素多个可排成一排;
- 块级元素可设置狂傲,行内元素不能设置宽高;
- 块级元素可以包含块级,行内, 行内元素一般包含行内的和文本
- 块级元素可以设置padding,margin, 行内元素只能设置padding和margin的left/right
- 行内元素:不能设置宽,高,与其他行内元素位于同一行,一般不在里面嵌套块级元素
- BFC(块级格式化上下文)
- 概念:页面的一个独立的渲染区域,容器里面的自元素不会在布局上影响外面的元素,决定块级盒子的浮动,布局的因素
- 触发条件:
- float浮动
- 绝对定位(absolute, fixed)
- 行内块元素(inline-block, table-cell)
- overflo的值不为visible的块元素
- 弹性元素,display:flex/inline-flex
- BFC作用
- 解决上下两个相邻元素的重叠问题(垂直margin合并的问题)
- 正数时:两者之前取最大
- 负数时:绝对值取较大的
- 一正一负: 两者的和
- 清除内部浮动问题
- 解决上下两个相邻元素的重叠问题(垂直margin合并的问题)
- BFC的原理
- BFC不会与float的元素重叠,BFC下的编剧也不会重叠,BFC是一个独立的容器和外面的容器互不干扰,计算BFC的高度,浮动的子元素也会参与
- CSS的动画效果animation
- @keyframes 'loop' {0% {}; 50% {}; 100% {}}
- 伪类的元素: nth-child(even) / nth-child(old)
- css的选择器的优先级:
- 如果多重样式: 外部样式 < 内部样式 < 内联样式
- 注意: 外部样式放在内部样式的后面,则会覆盖;
- 选择器的优先级:
- 内联样式 > id选择器 > 类选择器 > 元素选择器
- 总结
- 越具体优先级越高
- 同样优先级写在后面的覆盖前面的
- !important的优先级最高,但是少用
- 清除浮动的方法:
- overflow: hidden
- clearfix:after { content: '', display: block, clear: both } }
- 父元素给个固定高度
牽著幸福的小豬:
闭包
- 定义:
- 函数和函数内部能访问的变量的总和,就是闭包;
- 当嵌套的内部函数引入用了外部函数的变量
- 本质:内部函数中的一个对象,这个对象中包含了引用的变量属性
- 从技术的角度讲,所有的JavaScript函数都是闭包:它们都是对象,它们都关联到作用域链。
- 作用
- 让函数外部能操作内部的局部变量
- 延长局部变量的生命周期
- 闭包应用:
- 模块化: 封装一些数据以及操作数据的函数, 向外暴露一些行为
- 循环遍历加监听
- JS框架(jQuery)大量使用了闭包
- 缺点:
- 变量占用内存的时间可能会过长
- 可能导致内存泄露
- 解决:
- 及时释放 : f = null; //让内部函数对象成为垃圾对象
内存溢出与内存泄露
- 内存溢出
- 一种程序运行出现的错误
- 当程序运行需要的内存超过了剩余的内存时, 就出抛出内存溢出的错误
- 内存泄露
- 占用的内存没有及时释放
- 内存泄露积累多了就容易导致内存溢出
- 常见的内存泄露:
- 意外的全局变量
- 没有及时清理的计时器或回调函数
- 闭包
立即执行函数
- 定义:声明一个函数,并立即调用这个函数
- 作用:创建一个独立的作用域,这个作用域内的变量,外面访问不到,避免全剧污染
promise的理解
- Promise 是异步编程的一种解决方案,其实是一个构造函数,自己身上有all、reject、resolve这几个方法,有then、catch、finally等方法
- 特点:
- 对象的状态不受外界影响
- 一旦状态改变,就不会再变,任何时候都可以得到这个结果
- promise的其他api
- promise.all
- promise.race
async/await
- 捕获异常: try ... catch
- ().then 后面可以捕获异常
浅拷贝和深拷贝
- 浅拷贝
- 浅拷贝是拷贝一层,深层次的对象级别的就拷贝引用;
- 浅拷贝的时候如果数据是基本数据类型,直接赋值,会拷贝其本身;
- 如果除了基本数据类型之外还有一层对象,那么对于浅拷贝而言就只能拷贝其引用,对象的改变会反应到拷贝对象上;
- 浅拷贝的方法:
- Object.assign(target, ...sources)
- target:目标对象, sources:任意多个源对象,返回值:目标对象会被返回
- Object.assign(target, ...sources)
- 浅拷贝是拷贝一层,深层次的对象级别的就拷贝引用;
- 深拷贝
- 深拷贝是拷贝多层,每一级别的数据都会拷贝出来
- 深拷贝就会拷贝多层,即使是嵌套了对象,也会都拷贝出来。
- 方法
- 对象只有一层的话: Object.assign()函数
- JSON.parse(JSON.stringify(obj))
- 缺点:会抛弃对象的constructor。也就是深拷贝之后,不管这个对象原来的构造函数是什么,在深拷贝之后都会变成Object。
- 递归拷贝
- 使用Object.create()方法
- 直接使用var newObj = Object.create(oldObj),可以达到深拷贝的效果。
- 深拷贝是拷贝多层,每一级别的数据都会拷贝出来
js的垃圾回收机制
- js的内存管理是自动的,无形的,创建的原始值,对象,函数,,,都是会占用内存。
- js的内存管理的可达性:是以某种方式可访问的值,一定存在内存中;
- 可达性分类:
* 固有的可达值的基本集合,明显不会被释放
- 函数的局部变量、函数根(roots)
- 嵌套调用时,调用连上所有的函数的变量与参数根(roots)
- 全局变量
- 内部的根(roots) * 一个值可以通过引用和引用连从根访问任何值,该值也是可达的
- 全局变量中有个属性,该对象的一个属性引用了另一个对象,该对象也是可达的
- 例子1
let user = { name: 'John'};
John = null;
- 不可达,没有引用,不能访问,垃圾回收器会认为是垃圾数据并进行回收,释放内存
- 例子2
let user = { name: 'John'};
let admin = user;
user = null;
- 对象可以通过admin访问,对象还存在内存中,若admin= null,对象就会被删除
- 例子1
let user = { name: 'John'};
John = null;
- 垃圾会是的内部算法 ---》 定期执行垃圾回收 * 垃圾回收器找到所有的根,并标记 * 然后标记来自他们的所有引用 * 便利标记的对象,并标记他们的引用,所有遍历到的对象都会被记住,以免将来遍历到同一个对象 * 。。。直到所有可达的从根部的引用都被访问到 * 没有被标记的对象都会被删除 例子: 一个油桶,流经所有引用并标记所有可达的对象,移除没有标记的
- js的优化: * 分代收集: 对象分成新的,旧的。有些对象出现完成他们的工作并很快死去,他们可以被很快清理,长期存活的对象会变得老旧,被查的频率减少 * 增量收集: 一次性太耗时,垃圾收集分成几部分去完成,逐一进行处理,需要他们之间有额外的标记 * 闲时收集: 在cpu闲时尝试运行,减少对代码的执行影响
- 总结: * 1. 垃圾回收时自动完成的,不能强制执行或阻止执行 * 2. 当对象时可达状态时,一定存在内存中 * 3. 被引用与可访问不同,一组相互链接的对象可能整体都时不可达的