欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  科技

ES6部分新特性

程序员文章站 2022-03-22 10:28:02
letconstlet在es6中,我们可以用let来声明变量替换var,那么let声明的变量有什么特性呢?使用let声明的变量具有块级作用域在一个大括号中,使用let声明的变量才具有块级作用域,var不具备这个特点防止循环变量成为全局变量不存在变量提升,也就是说我们必须先声明,再使用暂时性死区,和当前块级作用域绑定var a = []; for (var i = 0;i<2;i++){ a[i] = function () { co...

目录

写在前面的话:

如果想要了解更多ES6相关的新特性,建议看一看阮一峰老师的ES6
这篇博客只是一个前端菜鸟在学习路上的笔记,如果对你有帮助,那是最好的
当然本篇博客还会持续更新

let    ^

在es6中,我们可以用let来声明变量替换var,那么let声明的变量有什么特性呢?

  • 使用let声明的变量具有块级作用域
  • 在一个大括号中,使用let声明的变量才具有块级作用域,var不具备这个特点
  • 防止循环变量成为全局变量
  • 不存在变量提升,也就是说我们必须先声明,再使用
  • 暂时性死区,和当前块级作用域绑定
var a = [];
    for (var i = 0;i<2;i++){
        a[i] = function () {
            console.log(i)
        }
    }
    console.log(a[0]()); // 2
    console.log(a[1]()); // 2

上面代码因为var存在变量提升的问题,这里的i其实是全局变量,输出的i其实是全局变量下的i,全局变量的i此时已经循环完成,所以输出的是2,这时我们只要将var换成let便可解决,代码如下。

var a = [];
    for (leti = 0;i<2;i++){
        a[i] = function () {
            console.log(i)
        }
    }
    console.log(a[0]()); // 0
    console.log(a[1]()); // 1

再来看一下let的其他功能,代码如下

var num = 0;
    if(true){
        console.log(num); // 报错
        num = 123;  // 报错
        let num;
        console.log(num); // undefined
    }

上面代码我们要输出num,但是,因为let的原因,没有声明先调用,所以报错,说明num不存在变量提升,我们再看 num= 123,为什么这行语句也报错呢?,因为用let声明的变量会和当前块级作用域绑定。当前的块级作用域是if的{}。所以没有声明变量怎么能给num赋值呢。

let在同一作用域下,不允许重复声明同一变量

const    ^

在es6中,我们可以用const声明常量,但我认为并不能说是声明常量,只能说是声明一个不能重新赋值的变量,也就是说它的值(内存地址)不能变化,为了方便,我们还是叫它常量,那么const声明的常量有什么特点呢?

  • 声明的常量,就是他的值(内存地址)不能改变
  • 具有块级作用域
  • 声明常量时必须赋值
  • 常量赋值后,如果声明的是基本数据类型,并且在同一作用域下,它的值不能更改
  • 声明的是引用数据类型,内部的值可以更改,但是不能重新赋值

我们来看个例子

if(true){
        const a = 10;
        if(true){
            const a = 20;
            console.log(a);  // 20
        }
        console.log(a) // 10
    }
    const ary = [100,200];
    ary[0] = 1;
    ary[1] = 2;
    console.log(ary) // [1,2]

解构赋值    ^

在es6里面,允许从数组中提取值,按照对应的位置,对变量赋值,对象也可以实现解构。

我们先来看一下数组解构

	let ary = [1,2,3];
	let [a,b,c,d,e] = ary;
	console.log(a,b,c,d,e); // 1,2,3,undefined,undefined

通过上面的代码,我们能明白,如果解构不成功,变量的值为undefined

再看一下对象解构,对象解构允许我们使用变量的名字匹配对象的属性,匹配成功将对象属性的值赋值给变量

	let person = {name: 'beiBei', age: 18, sex: '男'};
    let {name,age,sex} = person;
    console.log(name,age,sex);

下面的代码然后还有第二种写法,左边的name只用于匹配,右边的myName才是变量

	let {name:myName,age:myAge} = person;
    console.log(myName,myAge);

箭头函数    ^

es6中,提供了一种新的创建函数的方法,用来简化函数的定义语法
语法:const = fn = () => {}

  • 如果函数体中只有一句代码,且代码执行的结果就是返回值,可以省略大括号
  • 如果形参只有一个,可以省略小括号
  • 箭头函数不绑定this,箭头函数没有自己的this关键字,箭头函数中的this,指向是函数定义位置的上下文this

我们先来看第一个省略大括号

const fn = (num1,num2) => num1+num2
console.log(fn(1,2)); // 3

在看一个省略小括号的例子,下面的代码小括号和大括号都省略了,但是并不影响输出结果,简化了函数的定义方式

	const fn2 = num => console.log(num);
    fn2(2);

我们再来看关于箭头函数this指向的问题,代码如下

	let obj = {
	age:20,
	say:() => {
	alert(this.age); // undefined
	console.log(this); // window
	}
}
	obj.say();

这边我们可以看到,因为使用了箭头函数。alert()方法并没有弹出我们obj.age的值,弹出的是undefined,因为这里的this指向window,window下面并没有age这个属性,所以是undefined。并且通过console(this)我们我们也可以看到,this指向window。

然后再看下面这个例子

	function fn() {
	console.log(this); // obj
	return ()=>{
		console.log(this); // obj
	}
}
	const obj = {name:'beibei'};
	const resfn = fn.call(obj);
	resfn();

我们知道call方法可以改变this的指向,上面的代码通过call方法,让函数fn的this指向改为了obj,那么为什么return里面的箭头函数的this也指向obj呢?
这时我们要回到上面这句话:
箭头函数不绑定this,箭头函数没有自己的this关键字,箭头函数中的this,指向是函数定义位置的上下文this

剩余参数    ^

在ES6中允许我们将一个不定量的参数表示为数组

	function sum(first,...args){
	console.log(first); // 1
	console.log(args); // 2,3,4,5
}
	sum(1,2,3,4,5);	

打个比方,我们要封装一个加法的函数,但是我们不知道要传递多少个参数,比如三个,比如四个,这个时候剩余参数就派上用场了代码如下

	const sum = (...nums) => {
		let sums = 0;
		nums.forEach(items => sums += itmes);
		return sums;
	}
	console.log(sum(1,2)); // 3
	console.log(sum(1,2,3,4)); // 10

我们的剩余参数还可以配合解构赋值配合使用,代码如下

	let students = ['beibei','andy','red'];
	let [s1,...s2] =  students;
	console.log(s1); // beibei
	console.log(s2); // ['andy','red']

注意,上面代码的s2变量,实际上是一个数组

Array    ^

扩展运算符(展开语法)

  1. 扩展运算符可以将数组或者对象转为用逗号分隔的参数序列
	let arr = [1,2,3];
	// ...arr 参数序列 1,2,3
	console.log(...arr); // 实际上就是把参数序列放进去,逗号刚好成了console.log()的分隔符
	console.log(1,2,3) // 这两者的效果是一样的
  1. 扩展运算符可以应用于合并数组
	// 方法 1
	let arr1 = [1,2,3];
	let arr2 = [4,5,6];
	let arr3 = [...arr1,...arr2];
	console.log(arr3); // 1,2,3,4,5,6
	// 方法 2
	arr1.push(...arr2);
	console.log(arr1); // 1,2,3,4,5,6
  1. 可以将类数组或可遍历对象转换为真正的数组,然后调用数组的一些方法
	<ul>
    	<li></li>
    	<li></li>
    	<li></li>
	</ul>
	<script>
		let lis = document.querySelectorAll('ul li');
		console.log(lis); // 这里的lis是类数组
		lis = [...lis]; // 加上中括号
		console.log(lis); // 这里就成立真正的数组了,可以去调用方法了
	</script>

这里将类数组转换成真正数组的方法还有一种,也就是Array.form(),这个方法还可以接受第二个参数,类似于map方法,用来对每个数组进行处理,将处理后的值放入数组,我们看下面代码

	let arraylike = {
	0:'1',
	1:'2',
	2:'3',
	length:3	
}
let array = Array.form(arraylike,item => item * 2);
console.log(array); // [2,4,6]

上面的代码将类数组进行了处理,把类数组里面的每个值乘以2,再将他放回新数组,并且这个新数组array已经被转换成了真正的一个数组,可以调用数组的方法。

本文地址:https://blog.csdn.net/Kavii_a/article/details/107529389