# part1-module2 **Repository Path**: ren_wei_1/part1-module2 ## Basic Information - **Project Name**: part1-module2 - **Description**: 作业提交 - **Primary Language**: JavaScript - **License**: Not specified - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2020-07-26 - **Last Updated**: 2020-12-19 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README ## 作业提交 #### 1.请说出下列最终的执行结果,并解释为什么 ``` var a = []; for (var i = 0; i < 10; i++) { a[i] = function() { console.log(i); }; } a[6](); //打印结果为10 ``` > 这段代码的执行结果是10,因为定义了两个全局变量a[]和i,当我们调用`a[6]()`的时候,这个时候的i已经是10了,所以打印的是10. > 如果我们想打印是6的话,把var换成let即可 #### 2.请说出下列代码的执行结果,并解释为什么 ``` var temp = 123; if(true){ console.log(temp); //error 报错 let temp; } ``` > 这段代码会报错,因为在当前作用域里面存在let声明的temp变量,所以只会在当前作用域里面寻找,但是由于let和const是没有变量提升的,即声明变量必须要放在使用变量前面,所以会报错。 #### 3.结合es6新语法,用最简单的方式找出数组中的最小值 ``` var arr = [12,34,32,89,4] ``` > 可以直接用reduce来实现 代码如下 ``` const min = arr.reduce((prev, current) => { return prev < current ? prev : current; //判断当前的值如果小于前面的值就返回当前的值 否则就返回前面的值 }); ``` #### 4.请详细说明var,let,const三种生命变量方式之间的具体区别 1. var申明的是全局变量(会挂载到window上),而let和const不会挂载到window上 2. var申明的变量存在变量提升,let 和 const不存在变量提升(即必须要先声明才可以使用) 3. let 和 const声明的变量会形成块作用域(作用在{}中),而var声明的变量没有块作用域 4. 同一作用域下let和const不能声明重复的变量名,但是var是可以的 5. let声明的属性可以修改值,并且可以不赋初值 6. const声明的属性,必须要赋初值,并且后续不可能修改(这里面的修改是不能修改指向的内存区域),如果是个对象,我们还是可以修改对象里面的属性 #### 5.请说出下列代码输出的最终结果,并解释为什么 ``` var a = 10; var obj={ a:20, fn(){ setTimeout(() => { console.log(this.a) //20 }); } } obj.fn(); ``` > 因为箭头函数是没有this的,所以会寻找最近作用域的this,即fn的this,fn的this就是obj对象的this,所以this.a ===> obj.a 所以结果是20 #### 6.简述Symbol类型的用途 ###### 1.使用Symbol来作为对象的属性名 > 由于Symbol类型的key是无法通过Object.keys()或者for in 来获取的,所以我们可以把一些不需要外界访问的属性使用Symbol来定义。 ###### 2.使用Symbol来定义常量 > 我们经常会定义很多的常量来代表不同的状态或者类型,并且通常这些常量都是唯一的,所以我们可以利用Symbol唯一的特性来用Symbol定义,这样我们就不用担心定义了重复的。(我觉得对于redux中的type可以用Symbol来定义) ###### 3.使用Symbol来进行权限控制,定义类的私有属性 > 由于在js中不存在private,public等权限控制的,所以类里面的属性外面都是可以访问的,这时候我们可以用Symbol来定义那些我们不希望别人访问的私有变量(由于Symbol都是唯一的,外部是无法生成一个相同的Symbol的),通过这种方式,我们是可以定义类的私有属性。 #### 7.说说什么是浅拷贝,什么是深拷贝 ###### 1.浅拷贝 > 我理解的浅拷贝就是,我们只是定义了一个指针来指向了当前对象的内存区域,所以两个访问的都还是同一个内存对象,只要其中一个对象的值改变了,另一个的值也跟着改变了。 ###### 2.深拷贝 > 我理解的深拷贝,就是在内存中拷贝了一份当前这个对象,并用一个新的指针指向新的这个对象的内存区域,所以改变其中任意一个,不会影响到另外一个。 #### 8.简述typescript和javascript的关系 1. 如typescript官网说的一样,ts是js的超集,ts是在js上面添加了一些新的功能或者特性(类型检查等等) 2. typescript最后会编译成js来运行,关系就好像java会编译成字节码来运行一样 #### 9.请谈谈你所认为的typescript的优缺点 ###### 优点 1. 有类型检查系统,增强了代码的可读性,和可维护性。在编码的时候就可以发现大量的错误,不需要在运行的时候才能发现 2. 支持es6的新特性 3. 强大的类型推断 ###### 缺点 1. 开发成本增加,因为我们还要写类型定义文件 2. 集成typescript到项目中需要一定的配置 3. 不是所有第三方库都支持ts 4. 由于增加了ts编译成js的过程,打包速度会受到一定影响 #### 10.描述引用计数的工作原理和优缺点 ###### 原理 ``` const obj1={}; function test() { const a = new obj1(); //生成一个a指向obj1的对象,此时obj1这个对象的引用计数+1, } test(); //当执行这个会进入test方法 //当test执行完毕之后,由于已经离开了a的作用域,所以a会被销毁,此时obj1的引用计数-1,为0 所以obj1的对象会被立即释放 ``` > 引用计数就是判断当前有多少指针指向当前的这个内存区域,当个数为0的时候,就会立即回收当前的这个内存区域里面的内容 ###### 优点 1. 可以立即回收引用计数为0的内存区域,实时性强 ###### 缺点 1. 无法回收两个循环引用的对象 2. 需要消耗资源来维护一个计数器 #### 11.描述标记整理算法的工作流程 1. 遍历所有对象,将当前的可达对象进行标记 2. 对标记的可达对象进行整理,将所有可达对象放到连续的地址上(从地址的最前面开始) 3. 回收掉整理过后可达对象后面的内存区域 #### 12.描述v8中新生代存储区垃圾回收的流程 1. 首先新生代分为了两个同样大小的区域---From 和 To 2. 在gc刚开始的时候To中的内存区域是空的,所有的对象都存在From区 3. 当要执行GC的时候,首先会遍历From区里面的对象,将当前的活动对象全部复制到To区域中 4. 将From区域直接全部回收 5. 将前面的To区域标志为From区域,From区域标志为To区域 #### 13.描述增量标记算法在何时使用及工作原理 > 增量标记是在回收老生代区域的时候用来优化垃圾回收使用的 ###### 工作原理 > 增量标记的原理是在遍历标记的时候不一次性直接遍历全部对象,而是分多次来进行遍历(执行一会儿代码,再执行一下GC),这样就可以将一次完整的遍历所耗的时间分摊到各个小块中,并且因为时间比较短,对用户的体验没有任何影响。 > 当增量标记完成之后,此时可以明确知道有多少的空间可以释放,此时可以根据自己的需要来清理,当延迟清理完成之后优惠开始增量标记