100. ES6新特性有哪些
- let、const关键字,let声明变量、const声明常量
- 变量的解构赋值
- 模板字符串
- 简化对象写法,可以直接写入变量和方法
- 箭头函数
- rest参数,用于获取函数的实参,代替arguments
- 扩展运算符,相当于rest参数的逆运算
- Symbol基本数据类型,表示唯一的值,Symbol还有内置值iterator、replace等
- 迭代器Iterator,为一种机制、接口,为各种不同的数据结构提供统一的访问机制,只要部署了Iterator接口,就可以完成遍历操作,新增for…of循环,Iterator只要拱for…of消费
- 生成器,新增的一种异步编程解决方案,它的语法行为与传统函数完全不同
- Promise,新增异步编程的解决方案,解决了地狱回调的问题
- Set,类似于数组,但它的成员的值都是唯一的
- Map,类似于对象,但它的键可以是各种类型的值(包括对象)
- Class类,作为对象的模板,可以看作一个语法糖,绝大部分功能ES5也能做到,但是使用class实现更加清晰、更像面向对象编程
- 数值扩展
- 二进制和八进制:前缀:0b–二进制、0o–八进制
- Number.isFinite()检查一个数值是否为有限的、Number.isNaN()检查一个值是否为NaN
- Number.parseInt()把字符串解析成整数、Number.parseFloat()把字符串解析成浮点数
- Math.trunc去除一个数的小数部分,返回整数部分
- Number.isInteger()判断一个数是否为整数
- 对象扩展
- Object.is(,)比较两个值是否严格相等,与===行为基本一致
- Object.assign(,)对象的合并,将源对象所有可枚举属性,复制到目标对象
__proto__
、setPrototypeOf可以直接设置对象的原型- 模块化,指将一个大的程序文件,拆分成许多小的文件,然后将小文件组合起来
- export命令用于规定模块的对外接口
- import命令用于输入其他模块提供的功能
101. JS垃圾回收机制
-
概述:
JS的垃圾回收机制就是不停歇的寻找那些不再使用的变量,释放掉它所指向的内存,从而防止内存泄漏
-
回收方式
标记清除
-
大部分浏览器使用这种垃圾回收方式,当变量进入执行环境,即声明变量的时候,垃圾回收器就将该变量打上了标记,当该变量离开环境的时候,将其再度进行标记,进而删除
-
示例:
function test(){ var a=0 //进入环境 } test() //离开环境
引用计数
-
这种方式常常会引起内存的泄漏,主要存在于低版本的浏览器。它的机制为跟踪某一个值的引用次数,例如,声明一个变量并且将一个引用类型赋值给这个变量,这时候引用类型的引用次数加1,当这个变量指向另一个引用类型时,原来那个引用类型的引用次数减1,当引用次数为0时就会触发回收机制进行垃圾回收
-
示例:
function test(){ var a=new Object() //a=1 var b=new Object() //b=1 var c=a //a=2 var c=b //a=1 }
-
102.事件冒泡、事件捕获
-
DOM事件流
事件发生时会在元素节点之间按照特定的顺序传播,传播过程即为DOM事件流
按照DOM事件流的传播过程分为:事件捕获阶段、处于目标阶段、事件冒泡阶段
-
事件捕获
事件从外层document开始往里一层一层的传播,直到元素标签
-
事件冒泡
事件从里层元素标签开始往外一层一层的传播,直到document
-
注
-
JS代码只能执行捕获或者冒泡的其中一个阶段
-
onclick和attachEvent只能看到冒泡阶段
-
addEventListener第三个参数若为true,则表示在事件捕获阶段调用处理程序,若为false(默认为false),表示在事件冒泡阶段调用事件处理程序
-
有些事件没有冒泡,如:onblur、onfocus、onmouseenter、onmouseleave
-
阻止冒泡的方式
event.stopPropagation():只阻止了事件冒泡
return false:不仅阻止了事件冒泡,也阻止了事件本身
-
实际开发中很少使用事件捕获,更关注事件冒泡
-
103. for…of、for…in的区别
-
for…of为ES6新增的遍历命令
-
区别
- for…in和for…of都可以循环数组,for…in输出的key是数组的index下标,for…of输出的key是数组中的值
- for…in可以遍历对象,for…of不能遍历对象,for…of只能遍历带有生成器Iterator接口的数据类型,例如Array、String、Set、Map、Arguments、TypedArray、NodeList
104. async函数、await表达式
-
async函数
async函数的返回值为promise对象
promise对象的结果由async函数执行的返回值决定
-
await表达式
await必须写在async函数中
await右侧的表达式一般为promise对象
await返回的是promise成功的值
await的promise失败了,会抛出异常,需要通过try…catch捕获处理
-
async/await:
基于promise实现的JS异步方法
优点:使用方法清晰明了
缺点:await将异步代码改成了同步代码,若多个异步代码没有依赖性却使用了await会导致性能上的降低,没有依赖性的话,完全可以使用promise.all的方式
105. Iterator
-
Iterator为一种机制、一种接口,为各种不同的数据结构提供统一的访问机制,任何数据结构只要部署了Iterator接口,就可以完成遍历操作
-
ES6新增了遍历命令for…of,Iterator接口主要供for…of进行消费
-
具有Iterator接口的数据类型:Array、String、Map、Set、Arguments、TypedArray、NodeList
-
工作原理
创建一个指针对象,指向当前数据结构的起始位置
第一次调用对象的next方法,指针自动指向数据结构的第一个成员
接下来不断调用next方法,指针一直往后移动,直到指向最后一个成员
每调用next方法返回一个包含value和done属性的对象
-
需要自定义遍历数据时,可以使用迭代器,例如在对象里部署一个迭代器,使得对象也可以用for…of遍历
106.Generator
-
生成器函数Generator是ES6新增的一种异步编程解决方案,语法行为和传统函数完全不同
-
符号*的位置没有限制
-
生成器函数返回的的结果是迭代器对象,调用迭代器对象的next方法可以得到yield语句后的值
-
yield相当于函数的暂停标记,也可认为是函数的分隔符,每调用一次next方法,执行一段代码
-
next方法可以传递实参,作为yield语句的返回值
107. JS类型转换
-
显示转换
parseInt()、Number.parseInt():转换为整数,非数字都会输出NaN,只转换第一个无效字符之前的字符串,可以指定第二个参数指定进制数转换
parseFloat()、Number.parseFloat():转换为浮点数,非数字都会输出NaN,只转换第一个无效字符之前的字符串,可以指定第二个参数指定进制数转换
toString():转换为字符串,可以指定参数进行指定进制数的转换
强制类型转换:
Number():整个强制转换,若不能整个强制转换,则返回NaN,例如Number(4.5.6)返回NaN,能强制转换的话内部会判断是调用parseInt()还是调用parseFloat()
String():把给定的值转换成字符串,与调用toString()方法唯一不同之处在于,对null或undefined值强制类型转换可以生成字符串而不引发错误
Boolean():要转换的值至少有一个字符的字符串、非0数字或对象时,返回true;若为空字符串、数字0、undefined或null,返回false
-
隐式转换
10+'true’→10true
以下结果都为true
100==’100‘ 、0==’‘ 、false==‘’ 、0false 、nullundefined
注:100转换为了‘100’,0、‘’、都转换为了false
108. 0.1+0.2 !==0.3
- 原因
由于浮点数运算时的精度问题。在计算机运算过程中,需要将数据转换成二进制,然后再进行计算。二进制数按照IEEE754标准转换成双精度浮点数时,由于其小数位长度的限制,发生了精度丢失,当两者进行相加时又因为小数位长度的限制,再次发生了精度丢失,相加后的浮点数转换为十进制数为0.30000000000000004,所以产生了误差,0.1+0.2!=0.3
-
解决方案
通用的解决方法,将计算数字提升10的N次方,计算结果再除以10的N次方
(0.1*1000+0.2*1000)/1000==0.3 //true
109.{},new Object() ,Object.creat的区别
字面量和new关键字创建的对象是Object的实例,原型指向Object.protytype,继承了Object原型链上的属性或者方法;Object.create(arg,pro)创建的对象的原型取决于arg,若arg为null,新对象为空对象,没有原型,不继承任何对象,若arg为指定对象,新对象的原型指向指定对象,继承指定对象