【ES6】的新特性

229 阅读5分钟

(一)ES6 新增了哪些数据类型,说一下用法。

  • Symbol
    • Symbol是一种唯一且不可变的数据类型,用于创建独一无二的标识符。可以使用全局Symbol注册表或调用Symbol()函数来创建Symbol值。
  • Map、Set
    • Map是一种键值对的有序列表,其中键和值可以是任意类型,并且保持插入顺序。
    • Set是一种存储唯一值的集合,其中值可以是任何类型,并且不会重复。重复的值不会被添加
  • WeakMap 和 WeakSet
    • WeakMap和WeakSet类似于Map和Set,但其中的键只能是对象,并且不会阻止垃圾回收。

(一)块作用域构造 Let and Const 变量提升

1. 声明函数作用提升?声明变量和声明函数的提升有什么区别?

  • 变量声明提升:变量申明在进入执行上下文就完成了。
    只要变量在代码中进行了声明,无论它在哪个位置上进行声明, js引擎都会将它的声明放在范围作用域的顶部
  • 函数声明提升:执行代码之前会先读取函数声明,意味着可以把函数申明放在调用它的语句后面
    只要函数在代码中进行了声明,无论它在哪个位置上进行声明, js引擎都会将它的声明放在范围作用域的顶部
  • 变量or函数声明:函数声明会覆盖变量声明,但不会覆盖变量赋值。

同一个名称标识a,即有变量声明var a,又有函数声明function a() {}
不管二者声明的顺序,函数声明会覆盖变量声明,也就是说,此时a的值是声明的函数function a(){}
注意:如果在变量声明的同时初始化a,或是之后对a进行赋值,此时a的值变量的值。

var a; 
var c = 1; a = 1; 
function a() { return true; } 
console.log(a);//true

2. var、let、const 的区别 ⭐⭐⭐⭐⭐

区别varletconst
是否会变量提升必须先声明后使用同let
是否能重复声明与前面的let,var,conset声明的变量不能重名同let
作用域在非函数作用域中定义是挂在到window上的声明的变量只在局部起作用同let
是否必须初始化① const声明变量的同时必须赋值进行初始化,一旦初始化完毕就不允许修改
② const定义的对象\数组中的属性值可以修改,基础数据类型不可以

[ 延伸问题 ]

(1)如何使const声明的对象内属性不可变,只可读?

如果const声明了一个对象,对象里面的属性是可以改变的。

const obj={name:'laona'}
obj.name='lili'
console.log(obj.name)//lili
//因为const声明的obj,只是保存其对象的引用地址,只要地址不变,就不会出错。

使用Object.freeze(obj)冻结obj,就能使其内部的属性不可变,但有局限,就是obj对象中要是有属性是对象,该对象内属性还能改变,要全不可变的话,就需要使用递归等方式一层一层全部冻结。

(2)变量和函数怎么进行提升的?优先级是怎么样的?⭐⭐⭐

  • 对所有函数声明进行提升(除了函数表达式和箭头函数),引用类型的赋值
    • 开辟堆空间
    • 存储内容
    • 将地址赋给变量
  • 对变量进行提升,只声明,不赋值,值为undefined

(二)默认参数

在 ES6,我们可以直接把默认值放在函数申明里:

var link = function(height = 50,  url = 'http://azat.co') {  
    ...
}

(三)模板文本

(四)多行字符串

(五)解构赋值

(六)增强的对象字面量

允许在大括号里面,直接写入变量和函数,作为对象的属性和方法
如:在 ES6 的对象文本中,既可以直接分配 getAccounts: getAccounts, 也可以只需用一个 getAccounts

(七)箭头函数(三没有、三不能)

1. 箭头函数的特点

  • 没有arguments实参集合,取而代之用...剩余运算符解决 ;
  • 箭头函数没有自己的this。他的this是继承当前上下文中的this ;
  • 箭头函数没有函数原型;
  • 箭头函数相当于匿名函数,是不能作为构造函数的,不能被new 箭头函数;
  • 不能使用call、apply、bind改变箭头函数中this指向 ;
  • 箭头函数不能当做Generator函数,不能使用yield关键字;

[ 延伸问题 ]

(1)箭头函数和普通函数的区别?箭头函数可以当做构造函数 new 吗?⭐⭐⭐⭐⭐

箭头函数是普通函数的简写,但是它不具备很多普通函数的特性

  • 第一点,this指向问题,箭头函数的this指向它定义时所在的对象,而不是调用它的对象
  • 不会进行函数提升
  • 没有arguments对象,不能使用arguments,如果要获取参数的话可以使用rest运算符
  • 没有yield属性,不能作为生成器Generator使用
  • 不能new
    • 没有自己的this,不能调用call和apply
    • 没有prototype,new关键字内部需要把新对象的_proto_指向函数的prototype

(八)Promises

(九)Classes(类)

(十)Modules(模块)

为什么要使用模块化?都有哪几种方式可以实现模块化,各有什么特点?⭐⭐⭐

  • 防止命名冲突
  • 更好的分离,按需加载
  • 更好的复用性
  • 更高的维护性

exports和module.exports有什么区别? ⭐⭐⭐

  • 导出方式不一样
    使用exports只暴露自定义部分,大白话的意思就是按需导出,而使用module.exports暴露完整对象。
    • exports.xxx='xxx'
    • module.export = {}
  • exports是module.exports的引用,两个指向的是用一个地址,而require能看到的只有module.exports