var a = []
for (var i = 0; i < 10; i++) {
a[i] = function () {
console.log(i)
}
}
a[6]()
// 在执行a[]()函数for循环已经执行结束,此时i结果是10,不管a[]()数组第几项执行结果都是10
var temp = 123
if (true) {
console.log(temp)
let temp
}
// 会报错在函数作用域let声明的变量不允许声明之前访问
var arr = [12, 34, 32, 89, 4]
arr.sort((a, b) => {
return a - b
})
console.log(arr[0])
- var 声明的变量会发生变量提升
- let 声明的变量只在当前作用域内被访问,不会发生变量提升,不能再声明之前被访问
- const 声明的变量是只读的且不可修改,但是 const 声明的对象是可以修改内部属性的
var a = 10
var obj = {
a: 20,
fn() {
setTimeout(() => {
console.log(this.a)
})
},
}
obj.fn() //20
//obj.fn()得知fn中的this指向 obj在箭头函数中引用this实际上指向上一层作用域的 this(fn),fn的this指向obj,所以这里的this指向obj
- 由于每一个 Symbol 的值都是不相等的,所以 Symbol 作为对象的属性名,可以保证属性不重名
- 读取到一个对象的 Symbol 属性,可以通过 Object.getOwnPropertySymbols()和 Reflect.ownKeys()取到
- 使用 Symbol 定义常量,这样就可以保证这一组常量的值都不相等
- 浅拷贝是创建一个新对象,这个对象有着原始对象属性值的一份精确拷贝
- 如果属性是基本类型,拷贝的就是基本类型的值,如果属性是引用类型,拷贝的就是内存地址,所以如果其中一个对象改变了这个地址,就会影响到另一个对象
深拷贝是将一个对象从内存中完整的拷贝一份出来,从堆内存中开辟一个新的区域存放新对象,且修改新对象不会影响原对象
TypeScript 是 JavaScript 的超集,TypeScript 可以使用 JavaScript 中的所有代码和编码概念,TypeScript 是为了使 JavaScript 的开发变得更加容易而创建的
- 增强代码的可读性和可维护性,强类型的系统相当于最好的文档,在编译时即可发现大部分的错误,增强编辑器的功能
- 包容性,js 文件可以直接改成 ts 文件,不定义类型可自动推论类型,可以定义几乎一切类型,ts 编译报错时也可以生成 js 文件,兼容第三方库,即使不是用 ts 编写的
- 有活跃的社区,大多数的第三方库都可提供给 ts 的类型定义文件,完全支持 es6 规范
- 增加学习成本,需要理解接口(Interfaces)和泛型(Generics),类(class),枚举类型(Enums)
- 短期增加开发成本,增加类型定义,但减少维护成本
- ts 集成到构建流程需要一定的工作量
- 和有些库结合时不是很完美
优点: 发现垃圾立即回收,最大限度减少程序暂停
缺点: 无法回收循环引用的对象,时间消耗大
- 标记整理可以看成标记清除的增强
- 标记阶段的操作和标记清除一致
- 清除阶段会执行整理移动对象位置
- 回收过程采用复制算法和标记整理
- 新生代内存分为大小等大的两个内存
- 使用空间 from,空闲空间 to
- 活动对象存属于 from 空间
- 标记整理后将活动对象拷贝至 to
- from 与 to 交换空间完成释放
使用场景: 标记增量算法在老生代垃圾回收使用
工作原理: V8 引擎将原本要一口气停顿完成的动作改成增量标记,也就是拆分为许多小“步进”,每做完一“步进”就让 JavaScript 应用逻辑执行一小会儿,垃圾回收和应用逻辑交替执行,直到标记阶段完成增量标记,允许堆的标记发生在几次 5-10 毫秒(移动设备)的小停顿中。增量标记在堆的大小达到一定的阈值时启用,启用之后每当一定量的内存分配后,脚本的执行就会停顿并进行一次增量标记。就像普通的标记一样,增量标记也是一个深度优先搜索,并同样采用白灰黑机制来分类对象。