ES6详解

一 let 和 const

  • ES6中可以使用let和const声明变量,用法类似于var

  • const声明的为常量,不可修改(但声明对象,对象中的属性可以修改),由于这个特性,它需要在声明的同时就赋值,否则报错

  • 实际开发中建议用const,当知道变量值需要被修改的情况下使用let

1.1 块级作用域

暂时性死区: 在代码块内,使用let命令声明变量之前,该变量都是不可用的。这在语法上,称为暂时性死区(temporal dead zone,简称 TDZ)

  • let声明的变量,只在let命令所在的代码块内有效
{
    let a = 10;
    var b = 20;
}
console.log(a); 	//a is not defined
console.log(b); 	//20

1.2 不存在变量提升

  • var命令会发生变量提升现象,即变量可以在声明之前使用,值为undefined

  • ES6 中let命令改变了语法行为,它所声明的变量一定在声明后使用,否则报错

//var的情况
console.log(c);			//输出undefined
var c = 30;

//let的情况
console.log(c);			// 报错ReferenceError
let c = 30;

1.3 不允许重复声明

  • let不允许在相同作用域内,重复声明同一个变量
let c = 10;
let c = 30;
console.log(c); 	//报错

function func(arg) {
	let arg; 		//报错
}

1.4 块级作用域的作用

  • 防止外层变量覆盖内层变量
function fc(a){
    console.log(a);
    if(1===2){	//全真关系
        var a = 'hello 猫';
    }
}
var a = 10;
fc(a);		//输出10
  • 防止用来计数的循环遍历泄露为全局变量
var arr = [];
for(var i = 0; i < 10; i++){
    arr[i] = function(){
        return i;
    }
}
console.log(arr[5]());	//希望输出5,但是输出10,这是因为循环结束后,i并没有消失,而用于变量提升,泄露成了全局变量。

解决循环计数问题

//解决方式一:使用闭包
var arr = []
for(var i = 0; i < 10; i++){
    arr[i] = (function(n){        
        return function(){
            return n;
        }
    })(i)
}
//解决方式二:使用let声明i

var arr = []
for(let i = 0; i < 10; i++){
    arr[i] = function () {
        return i;
    }
}

二 运算符

2.1 模板运算符

ES6之前输出模板通常这么写

const oBox = document.querySelector('.box');
// 模板字符串
let id = 1,
   name = '做一只猫';
   
let htmlTel = "<ul><li><p>id:" + id + "</p><p>name:" + name + "</p></li></ul>";	//这么写比较麻烦
oBox.innerHTML = htmlTel;

ES6引入了模板字符串解决这个问题

const oBox = document.querySelector('.box');
//将文本用反单引号整个括起来
let htmlTel = `<ul>
    <li>
    <p>id:${id}</p>
    <p>name:${name}</p>
    </li>
</ul>`;
oBox.innerHTML = htmlTel;

2.2 剩余运算符 / 剩余参数

剩余运算符: 将多个独立的项合并到一个数组中
ES5传统写法:

let book = {
  title : 'ES6笔记汇集',
  author: '做一只猫'
}
function pick(obj){
  let result = Object.create(null);
  for(let i = 0; i < aruguments.length; i++){
  		result[arguments[i]] = obj[keys[arguments[i]];
  		//console.log(arguments[i]);
  }
  return result;
};
let bookData = pick(book, 'author', 'year');
console.log(bookData);

ES6提供了剩余参数的写法

function pick(obj,...keys){
   let result = Object.create(null);
   for(let i = 0; i < keys.length; i++){
   		result[keys[i]] = obj[keys[i]];
   }
   return result;
};
let bookData = pick(book, 'author', 'year');
console.log(bookData);

这么看起来可能感觉这个剩余参数好像只是方便了点,但其实本质有很大区别,可以写一个函数调用看一下

function check(...args){
   console.log(args);
   console.log(arguments);
};
check('a','b','c');

返回结果:

在这里插入图片描述
可以看到,剩余参数返回的是一个数组,而arguments返回的是一个伪数组。

2.3 扩展运算符

扩展运算符: 将一个数组进行分割,并将各个项作为参数传递给函数

例: 找出数组中的最大值

const arr = [10, 20, 50, 60, 100];
//ES5写法:
console.log(Math.max.apply(null,arr));
//ES6写法:
//...将arr数组作分隔,并传回作为函数参数
consoloe.log(Math.max(...arr));

三 箭头函数

3.1 箭头函数的基本运用

//1常规写法(省略了function)
let add = (a, b) =>{
	return a + b;
}

//2 小括号()代替return
let add = val => val;						 //只有一个参数,一个返回值时不需要加小括号
let add = (val1, val2) => (val1 + val2);
let fn = () => 'hello world' + 123;			//串起来也是一个字符串,所以返回值还是只有一个

//返回对象
let po = id => {
    return{
    	id: id,
    	name: '做一只猫'
    }
}
//简便写法:
 let po = id => ({id: id,name: '做一只猫'})

3.2 箭头函数的注意事项

3.2.1 箭头函数没有this指向,其内部的this只能通过查找作用域链的方法来确定作用域,即一旦使用箭头函数,当前不存在作用域

指向问题

let test = {
     id: 123,
      //构造函数
      init: function () {
          document.addEventListener('click', function () {
          	console.log(this);
              this.sayHi();
          })
         
      },
      saiHi: function () {
              console.log('hi');
      }
}
test.init();

输出:
在这里插入图片描述
可以发现,this指向的是document对象,所以无法调用test作用域中的saiHi()

ES5处理方法

let test = {
       id: 123,
        //构造函数
        init: function () {
            document.addEventListener('click', function () {
            	console.log(this);
                this.sayHi();
            }.bind(this),false)
           
        },
        saiHi: function () {
                console.log('hi');
        }
}
test.init();

用箭头函数改进

let test = {
     id: 123,
      //构造函数
      init: function () {
          document.addEventListener('click', () => {
          	console.log(this);
              this.sayHi();
          })
         
      },
      saiHi: function () {
              console.log('hi');
      }
}
test.init();

这是因为箭头函数没有this指向,作用域链向上,找到init作为其作用域,所以init指向的this就是test

3.2.2 构造函数不能使用箭头函数
let test = {
     id: 123,
      //构造函数
      init: ()=>{
          document.addEventListener('click', () => {
          	console.log(this);
              this.sayHi();
          })
         
      },
      saiHi: function () {
              console.log('hi');
      }
}
test.init();

输出:
在这里插入图片描述
由于使用箭头函数,此时init向上寻找作用域,找到window,this指向Window

3.2.3 箭头函数内部不存在arguments
let getVal = (a, b) => {
  console.log(arguments);
  return a + b;
}
console.log(getVal(1, 3));

输出:

在这里插入图片描述
因为此时this指向Window

3.2.4 箭头函数内部不能使用new关键字来实例化对象

因为function函数是一个对象,而箭头函数不是一个对象,只相当于一个语法槽

let Person = () => {};
let p = new Person();

输出

在这里插入图片描述

四 解构赋值

  • 解构赋值是对赋值运算符的一种扩展
  • 通常对针对数组和对象进行操作
  • 优点:代码书写简洁且易读性高

4.1 数组解构

在以前,为变量赋值,只能直接指定值

let a = 1;
let b = 2;
let c = 3;

ES6允许我们这样写:

let [a,b,c] = [1,2,3];
//这样就可以把a, c, c分别拿出来用了

如果解构不成功,变量的值就等于undefined,如下 aimer的值都会等于undefined

let [aimer] = [];
let [bar, aiemr] = [1];

4.2 对象解构

对象解构

let node = {
  type: 'identifier',
  name: '做一只猫'
}

//之前的写法
let type = node.type;
let name = node.name;

//ES6写法
let {type, name} = node;
console.log(type, name);	//输出 identifier 做一只猫

对象的解构赋值时,可以对属性忽略和使用剩余运算符

let obj = {
    a:{
        name:'张三'
    },
    b:[],
    c:'hello world'
}
//可忽略 忽略b,c属性
let {a} = obj;

//剩余运算符 使用此法将其它属性展开到一个对象中存储
let {a,...res} = obj;
console.log(a,res);

4.3 解构函数参数 / 赋默认值

let {a, b = 10} = {a: 20};

//函数参数解构赋值
//本例中函数参数为一个数组
function add([x, y]){
  	return x + y;
}
add([1, 2]); 		//解构数组,分别赋给x1, y2,再调用x + y,最终输出结果为3

//默认值作参数
function addCart(n, num = 0){    
  	return n + num;
}
addCart(10);		//输出10
addCart(10, 20); 	//输出30

4.4 用途

4.4.1 交换变量的值
let x = 1;
let y = 2;
let [x, y] = [y, x];

上面代码交换变量x和y的值,这样的写法不仅简洁,而且易读,语义非常清晰。

4.4.2 从函数返回多个值

函数只能返回一个值,如果要返回多个值,只能将它们放在数组或对象里返回,而有了解构赋值,取出这些值就非常方便。

// 返回一个数组
function example() {
  return [1, 2, 3];
}
let [a, b, c] = example();

// 返回一个对象
function example() {
  return {
   		foo: 1,
    	bar: 2
  };
}
let {foo, bar} = example();
4.4.3 为函数参数解构赋值

解构赋值可以方便地将一组参数与变量名对应起来

// 参数是一组有次序的值
function f([x, y, z]) { ... }
f([1, 2, 3]);

// 参数是一组无次序的值
function f({x, y, z}) { ... }
f({z: 3, y: 2, x: 1});
4.4.4 提取JSON数据

解构赋值对提取 JSON 对象中的数据,尤其有用

let jsonData = {
	id: 42,
	status: "OK",
	data: [867, 5309]
};

let { id, status, data: number } = jsonData;
//对象的解构赋值的内部机制,是先找到同名属性,然后再赋给对应的变量。
//这里data起了一个别名为number,真正被赋值的是后者,而不是前者
console.log(id, status, number);	// 输出42, "OK", [867, 5309]
4.4.5 输入模块的指定方法

加载模块时,往往需要指定输入哪些方法。解构赋值使得输入语句非常清晰。

const {ajax} = require('xxx')
ajax()

五 函数的扩展

5.1

let man{
	name: name,
	age: age
}
//ES6中,键值对一样可以简写为:
let man{
	name,
	age
}
//函数返回对象简写
function(x, y){
  return{x, y};	//本来是x: x,
}
//函数简写
let cart = {
	wheel: 4,
	//省去function
	set(newVal){
		if(newVal < this.wheel){
				//抛出错误
				throw new Error('轮子太少');
		}
		this.wheel = newVal;
	}
	get(){
		return this.wheel;
	}
}  		
cart.set(3);			

(本文未完结,从草稿箱里翻出来的,索性发了)

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/356838.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

SpringBoot+SqlServer查询接口

SpringBootSqlServer查询接口 文章目录 SpringBootSqlServer查询接口1. pom环境配置2. common工具包3. 实体类接口映射4. Service层Controller层 需求&#xff1a;根据站号查询前一个小时的所有数据&#xff0c;将数据返回格式为Map<String,List<Map<String,String>…

双非本科准备秋招(9.2)——力扣哈希

1、383. 赎金信 跟昨天的题大同小异&#xff0c;因为只有26个字母&#xff0c;所以可以建个有26个坑位的数组。 做完昨天的题目&#xff0c;这个题没啥新意。 class Solution {public boolean canConstruct(String ransomNote, String magazine) {int[] hashTable new int[…

语言模型大战:GPT、Bard与文心一言,谁才是王者?

如何对GPT-3.5、GPT-4、Bard、文心一言、通义千问的水平进行排序&#xff1f; 在聊技术原理之前我们来先看看几个产品的团队背景 一、团队背景 1.1、ChatGPT ChatGPT团队的成员大多具有计算机科学、人工智能、自然语言处理、机器学习等相关领域的高等教育背景&#xff0c;有…

十分钟发布自己的NFT

概述 本文将以一个例子来说明如何在opensea快速发布自己的NFT智能合约&#xff08;ERC721&#xff09;。本着DRY&#xff08;Dont Repeat Yourself&#xff09;原则&#xff0c;我们需要站在巨人的肩膀上来搭建自己的应用&#xff0c;使用经过社区审计和实践检验的代码可以有效…

【Netty技术专题】「原理分析系列」Netty强大特性之ByteBuf零拷贝技术原理分析

零拷贝Zero-Copy 我们先来看下它的定义&#xff1a; “Zero-copy” describes computer operations in which the CPU does not perform the task of copying data from one memory area to another. This is frequently used to save CPU cycles and memory bandwidth when t…

Cubase 13.0下载安装教程,附安装包和工具,轻松解决安装问题

前言 Cubase是一款专业级的高级音乐创作软件&#xff0c;凭借其无与伦比的灵活工具&#xff0c;您可以快速和直观地创造任何类型的音&#xff0c;充满了各种各样的虚拟仪器、效果和数干种声音。 准备工作 1、Win7及以上系统 2、提前准备好 Cubase 13.0 安装包 没有的可以参…

Kafka高级_生产者ACk机制数据一致性问题

Kafka高级_生产者ACk机制&数据一致性问题 目录需求&#xff1a; 设计思路实现思路分析1.Kafka高级_生产者ACk机制2.Kafka高级数据一致性问题 参考资料和推荐阅读 Survive by day and develop by night. talk for import biz , show your perfect code,full busy&#xff0c…

基于51单片机天大的滚动显示Protues仿真设计

一、设计背景 数码管是一种常见的数字显示设备&#xff0c;它主要由发光二极管&#xff08;LED&#xff09;和控制电路组成。LED数码管可以分为共阳&#xff08;公共阳极&#xff09;和共阴&#xff08;公共阴极&#xff09;两种类型。在共阳数码管中&#xff0c;每个数码管的阳…

【性能测试】常见适用场景以及策略

面对日益复杂的业务场景和不同的系统架构&#xff0c;前期的需求分析和准备工作&#xff0c;需要耗费很多的时间。而不同的测试策略&#xff0c;也对我们的测试结果是否符合预期目标至关重要。 这篇博客&#xff0c;聊聊我个人对常见的性能测试策略的理解&#xff0c;以及它们…

RabbitMQ中死信交换机的应用,工作原理,实现案例

目录 一、介绍 1. 概述 2. 应用场景 3. 工作原理 二、应用 1. 讲述 2. 运用 三、案例 1. 实践 2. 代码整合 每篇一获 一、介绍 1. 概述 死信交换机是用来处理消息队列中无法被消费者正确处理的消息的交换机。当消息在队列中变成死信时&#xff0c;它会被重新发送…

指针的深入理解(一)

这一节主要复习数组指针&#xff0c;int (* )[ ] 就是数组指针类型的标志。 因为有&#xff08;&#xff09;将*括起来&#xff0c;所以&#xff08;*&#xff09;表示一个指针。[ ] 表示数组&#xff0c;所以&#xff08;*&#xff09;[ ]就表示一个指向数组的指针&#xff…

Day02-课后练习2-参考答案(数据类型和运算符)

文章目录 巩固题1、案例&#xff1a;今天是周2&#xff0c;100天以后是周几&#xff1f;2、案例&#xff1a;求三个整数x,y,z中的最大值3、案例&#xff1a;判断今年是否是闰年4、分析如下代码的计算结果5、分析如下代码的计算结果6、分析如下代码的计算结果7、分析如下代码的计…

STM32以太网接口的配置和使用方法详解

STM32 微控制器提供了多种系列和型号&#xff0c;不同型号的芯片可能有不同的以太网接口&#xff0c;包括MAC&#xff08;媒体访问控制器&#xff09;和PHY&#xff08;物理层接口&#xff09;等组件。在这里&#xff0c;我们以STM32F4系列为例来详细介绍以太网接口的配置和使用…

【精品教程】如何查看iOS崩溃日志

简介 当一个应用程序崩溃&#xff0c;会产生一个崩溃报告&#xff08;crash report&#xff09;&#xff0c;并存储到设备中。崩溃报告描述了应用程序崩溃的条件&#xff0c;通常包含每个执行线程的完整回溯。查看崩溃报告可以帮助我们了解应用程序的崩溃情况&#xff0c;并尝…

大数据学习之Redis、从零基础到入门(三)

目录 三、redis10大数据类型 1.哪十个&#xff1f; 1.1 redis字符串&#xff08;String&#xff09; 1.2 redis列表&#xff08;List&#xff09; 1.3 redis哈希表&#xff08;Hash&#xff09; 1.4 redis集合&#xff08;Set&#xff09; 1.5 redis有序集合&#xff08…

幻兽帕鲁越玩越卡,内存溢出问题如何解决?

近期幻兽帕鲁游戏大火&#xff0c;在联机组队快乐游玩的同时&#xff0c;玩家们也发现了一些小问题。由于游戏有随机掉落材料的设定&#xff0c;服务器在加载掉落物的过程中很容易会出现掉帧、卡顿的情况。某些玩家甚至在游戏1&#xff5e;2时后就出现服务器崩溃的情况&#xf…

dvwa,xss反射型lowmedium

xss&#xff0c;反射型&#xff0c;low&&medium low发现xss本地搭建实操 medium作为初学者的我第一次接触比较浅的绕过思路 low 发现xss 本关无过滤 <script>alert(/xss/)</script> //或 <script>confirm(/xss/)</script> //或 <script&…

解锁潜在价值:服装定制小程序在提升用户忠诚度上的作用

随着科技的不断进步和消费者日益追求个性化的需求&#xff0c;服装定制已成为时尚界的新宠。而在这个快节奏的时代&#xff0c;小程序作为一个方便、实用的工具&#xff0c;为服装品牌打造个性化定制的平台提供了新的可能性。通过利用小程序&#xff0c;服装品牌可以轻松地与消…

使用 FHEW-like 自举 BV-like

参考文献&#xff1a; [CDKS21] Chen H, Dai W, Kim M, et al. Efficient homomorphic conversion between (ring) LWE ciphertexts[C]//International Conference on Applied Cryptography and Network Security. Cham: Springer International Publishing, 2021: 460-479.[K…

关于类加载器的双亲委派机制

什么是双亲委派机制 双亲委派机制指的是&#xff1a;当一个类加载器接收到加载类的任务时&#xff0c;会自底向上的去检查这个类是不是被加载过&#xff0c;如果没有加载过再自上到下进行加载。 如果在向上检查是否加载过的过程中发现已经加载过&#xff0c;那么直接返回这个C…