草庐IT

ES6新特性----面试

粉饼xin 2024-05-10 原文

ES6新特性


ES6新特性

文章参考:阮一峰老师的ECAMScript6入门

关键字

let关键字

与var相比:

  • 不存在变量提升,即声明的变量一定要在声明后使用;“变量提升”可以在声明之前使用,值为undefined;
  • 暂时性死区,在代码块内,使用let声明变量之前,该变量都是不可用的,把这种现象称为“暂时性死区”;
  • 不允许重复声明,不允许在相同作用域内,重复声明一个变量;
  • 块级作用域;全局作用域存在的问题:内层变量可能会覆盖外层变量;用来计数的循环变量泄露为全局变量;

const关键字

声明一个只读的常量,一旦声明,常量的值不能发生改变;

本质上来说,实际上并不是常量的值不能改变,而是指向的那个内存地址不能改变;对于简单数据类型来说,值就保存在变量所指向的那个内存地址中,因此就说值不能发生改变;但引用数据类型变量指向的是内存地址,保存的是一个指针,const只能保证这个指针是固定的。

解构赋值

变量的解构赋值

从数组和对象中提取值,对变量进行赋值,这种被称为解构;

数组的解构赋值

let a = 1;
let b = 2;
let c = 3;
let [a,b,c] = [1,2,3];

let [x,,y] = [1,2,3]
// x=1 y=3

对象的解构赋值

对象的解构与数组有一个重要的不同,数组的元素是按照次序排列的,变量的取值取决于它的位置;

而对象的属性是没有次序的,变量必须于属性同名;

let {foo, bar} = {foo:"aaa", bar:"bbb"}
foo//"aaa"   bar:"bbb"

字符串的解构赋值

const [a,b,c,d,e] = 'hello'
//a "h"  b "e" c "l" d "l" e "o"

数值和布尔值的解构赋值

解构赋值的规则:只要等号右边的值不是对象或者数组,就先将其转为对象。由于undefined和null无法转为对象,所以,对它们进行结构赋值都会报错。

let {toString:s} = 123;
s === Number.prototype.toString //true

函数参数的解构赋值

[[1,2],[3,4]].map(([a,b])=>a+b)

用途

  1. 交换变量的值
let x = 1;
let y = 2;
[x,y] = [y,x]
  1. 从函数返回多个值
//返回一个数组
function example(){
    return [1,2,3]
}
let [a,b,c] = example()
  1. 函数参数的定义
function f([x,y,z]){...}
f([1,2,3])
  1. 提取JSON数据
let jsonData = {
    id:42,
    status:'ok',
    data:[123,234]
}
let {id, status,data:number} = jsonData;
console.log(id,status,number)
// 42,"ok",[123,234]
  1. 遍历Map结构

任何部署了Iterator接口的对象,都可以使用for...of循环遍历。Map结构原生支持Iterator接口,配合变量的解构赋值,获取键名和键值非常方便

const map = new Map();
map.set('first','hello')
map.set('second','world')

for(let [key,value] of map){
    console.log(key+"is"+value)
}
// first is hello
// second is world
  1. 输入模块的指定方法

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

const {SourceMapConsumer, SourceNode} = require("source-map")

模板字符串

用反引号(`)标识;

模板字符串嵌入变量,需要将变量名写在${}之中

箭头函数

箭头函数省去了function关键字,采用=>来定义函数;

与普通函数的区别:

  • 从结构上来说,箭头函数更简洁
  • 箭头函数没有自己的this,它会捕获自己在定义时所处的外层执行环境的this,所以它的this指向在它被定义的时候就已经确定了,之后不会改变;
  • 无法使用call()apply()bind()等方法去改变this的指向;
  • 箭头函数不能作为构造函数使用;因为箭头函数里面没有this;
  • 箭头函数没有自己的arguments对象;
  • 不可以使用yield命令,因此箭头函数不能用作Generator函数;

扩展运算符(…)

数组的扩展

Array.from()

数组实例的find()、数组实例的includes()

对象的扩展

Object.assign()

基本数据类型Symbol

表示独一无二的值,通过Symbol函数生成,可以保证不会与其他属性名冲突

Set和Map数据结构

基本用法

ES6提供了新的数据结构Set,类似于数组,但成员的值是唯一的,没有重复的值;

set实例的属性和方法

  • add()
  • has()
  • delete()
  • clear()

遍历操作

  • eys() 返回键名的遍历器
  • values() 返回键值的遍历器
  • entries() 返回键值对的遍历器
  • forEach() 使用回调函数遍历每个成员

Weakset

与set结构类似,也是不重复的值的集合,但是与Set有两个区别:

  • WeakSet的成员只能是对象,而不能是其他类型的值
  • WeakSet中的对象都是弱引用,即垃圾回收机制不考虑WeakSet对该对象的引用,也就是如果其他对象都不再引用该对象,那么垃圾回收机制会自动回收该对象所占用的内存,不考虑该对象还存在于WeakSet之中。

Map

ES6提供了Map数据结构,它类似于对象,也是键值对的集合。

WeakMap

WeakMap结构与Map结构类似,也是用于生成键值对的集合;

区别:

  • WeakMap只接受对象作为键名(null除外),不接受其他类型的值作为键名;
  • WaekMap的键名所指向的对象,不计入垃圾回收机制;

Promise对象

概念

  • promise是异步编程的一种解决方案,较好的解决了回调地狱的问题,允许将回调函数嵌套改成链式调用;

回调函数本身没有什么问题,问题是多个回调函数的多层嵌套,代码朝横向发展,不易于维护;

多个异步操作形成了强耦合,只要有一个操作需要修改,它的上层回调函数和下层回调函数,可能都需要跟着修改,这种情况就称为"回调地狱";

结构:

fs.readFile(fileA,'utf-8',function(err,data){
  fs.readFile(fileB,'utf-8',function(err,data){
      // ...
  })
})

使用Promise后:

var readFile = require('fs-redfile-promise');
readFile(fileA)
.then(function (data){
    console.log(data.toString())
})
.then(function(){
    return readFile(fileB)
})
.then(function (data){
    console.log(data.toString())
})
.catch(function(err){
    console.log(err)
})
  • 通过new Promise()的方法,创建一个Promise实例,Promise构造函数接收一个函数作为参数,这个函数有两个参数分别为rejectresolve
  • resolve函数的作用:将Promise的状态从“未完成”变成“成功”(即从pending变为resolved),在异步操作成功时调用,并将异步操作的结果,作为参数传递出去;
  • reject函数的作用:将Promise的状态从“未完成”变成“失败”(即从pending变为rejected),在异步操作失败时调用,并将异步操作报出的错误作为参数传递出去;
  • then()方法:
    • Promise实例生成以后,可以用then方法分别指定resolved状态和rejected状态的回调函数;
    • then()方法可以接收两个回调函数作为参数,第一个回调函数是Promise对象的装填变为resolved时调用,第二个回调函数是Promise对象的状态变为rejected时调用。这两个函数都接二手Promise对象传出的值作为参数。
    • then方法返回的是一个新的Promise实例(注意:不是原来的那个Promise实例),因此可以采用链式法则,即then犯法后面再调用另一个then方法。

状态

  • promise有三种状态:pending(进行中)、fulfilled(已成功)、rejected(已失败);

  • Promise状态改变只有两种可能:从pending变为fulfilled和从pending变为rejected;

  • 而且一单状态发生改变,就不会再变了。

方法

Promise实例的方法

  • Promise.prototype.then()
  • Promise.prototype.catch()

Promise

  • Promise.all()

    • const p = Promise.all([p1,p2,p3])
      //其中p1 p2 p3都是Promise实例
      
    • p的状态,由p1,p2,p3决定

      • 只有p1、p2、p3的状态都变成fulfilled,p的状态才会变成fulfilled
      • 只要p1、p2、p3中有一个被rejected,p的状态就会变成rejected,此时第一个被rejected的实例的返回值,会传递给p的回调函数
  • Promise.race()

    • const p = Promise.race([p1,p2,p3])
      
    • 只要p1、p2、p3中有一个实例率先改变状态,p的状态就会跟着改变,那个率先改变的Promise实例返回值,就传递给p的回调函数

  • Promise.resolve()

  • Promise.reject()

  • Promise.try()

缺点

  • 首先,无法取消promise,一旦创建会立即执行,无法中途取消;
  • 其次,如果不设置回调函数,Promise内部抛出的错误,不会反应到外部;
  • 第三,如果当前处于pending状态时,无法得知目前进展到哪一个阶段(刚刚开始还是即将完成)

Generator函数

概念

  • ES6提供的一种异步编程解决方案;
  • 最大的特点是可以交出函数的执行权(即暂停执行)
  • Generator函数可以把它理解为一个状态机,封装了多个内部状态,执行该函数会返回一个遍历器对象,返回的遍历器对象可以依次遍历Generator函数内部的每一个状态;
function *helloWorldGenerator(){
    yield 'hello';
    yield 'world';
    return 'ending';
}
var hw = helloWorldGenerator()
//该函数有三个状态:hello、world和ending

特征

  • function关键字与函数名之间有一个星号(*);
  • 函数体内部使用yield表达式,定义不同的内部状态

调用过程

  • 调用generator函数后,该函数并不执行,返回的也不是函数的运行结果,而是一个遍历器对象(Iterator Object)代表Generator函数的内部指针,只有调用next方法才会遍历下一个内部状态;

next()

  • 每次调用next方法,内存指针就从函数头部或者上一次停下来的地方开始执行,直到遇到下一个yield表达式(或return语句)为止。也就是说Generator是分段执行的,yield表达式是暂停执行的标记,而next方法可以恢复执行;
  • 每次调用遍历器对象的next方法,就会返回一个有着value和done两个属性的对象,value属性表示当前的内部状态的值,是yield表达式后面的那个值;done属性是一个布尔值,表示是否遍历结束。
hw.next()
// {value:'hello',done:false}
hw.next()
// {value:'world',done:false}
hw.next()
// {value:undefined,done:true}

yield表达式

yield 表达式就是暂停标志;

遇到yield 表达式,就会暂停执行后面的操作,并将紧跟在yield 后面的那个表达式的值,作为返回的对象的属性值;

下一次调用next方法时,再继续往下执行,直到遇到下一个yield 表达式;

yield 与return的区别

**相同点:**都能返回紧跟在语句后面的那个表达式的值;

不同点:

  • 每次遇到yield ,函数暂停执行,下一次再从该位置继续向后执行,而return语句不具备位置记忆的功能;

  • 正常函数只能返回一个值,因为只能执行一次return;Generator函数可以返回一系列的值,因为可以有任意多个yield ;

Async函数

概念

Generator的语法糖;将函数的星号(*)替换成async,将yield替换成await;

与Generator相比的改进:

  • 内置执行器:Generator函数,需要调用next方法,才能真正执行,得到最后的结果;而async函数自带执行器;
  • 更好的语义:aysnc和await,比起星号和yield,语义更清楚了。async表示函数里有异步操作,await表示紧跟在后面的表达式需要等待结果;
  • 更广的适用性:yield命令后面只能是Thunk函数或者Promise对象,而async函数的await命令后面,可以是Promise对象和原始类型的值(数值、字符串和布尔值,但这时等同于同步操作);
  • 返回的值是Promise:async函数的返回值是Promise对象,比Generator函数的返回值是Iterator对象方便多了,可以用then方法指定下一步操作;

基本用法

async函数返回一个Promise对象,可以使用then方法添加回调函数,当函数执行的时候,一旦遇到await就会先返回,等到异步操作完成,再接着执行函数体后面的语句;

async function getStockPriceByName(name){
    const symbol = await getStockSymbol(name);
    const stockPrice = await getStockPrice(symbol);
    return stockPrices;
}
getStockPriceByName('goog').then(function(result){
   console.log(result); 
});

错误处理

如果await后面的异步操作出错,async函数返回的Promise对象被reject,会抛出一个错误的对象,导致catch方法的回调函数被调用,它的参数就是抛出的错误对象。

将函数放在try…catch代码块之中

async functin f(){
    try{
        await new Promise(function(resolve,reject){
            throw new Error('出错了')
        })
    }catch(e){
    }
    return await('hello world')
}

如果有多个await命令。可以统一放在try…catch结构中。

for…of函数

for…of循环可以使用的范围包括数组:Set和Map结构、某些类似数组的对象(比如说arguments对象、DOM NodeList对象)、Generator对象,以及字符串。

JavaScript原有的for…in循环,只能获得对象的键名,不能直接获取键值。ES6提供for…of循环,允许遍历获得键值

var arr = ['a','b','c','d']
for(let a in arr){
    console.log(a); // 0 1 2 3
}
for(let a in arr){
    console.log(a); //a b c d
}

Class

定义类

ES6的class可以看做只是一个语法糖,它的绝大部分功能,ES5都可以做到

function point(x,y){
    this.x = x;
    this.y = y;
}
function.prototype.toString = function(){
    return '('+this.x+','+this.y+')';
}
var p = new Point(1,2)

class改写

class Point{
    constructor(x,y){
        this.x = x;
        this.y = y;
    }
    toString(){
        return '('+this.x+','+this.y+')';
    }
}

事实上,类的所有方法都定义在类的prototype属性上面;

在类的实例上面调用方法,其实就是调用原型上的方法;

class B{}
let b = new B()
b.constructor === B.prototype.constructor //true

constructor方法

constructor是类的默认方法,通过new命令生成对象实例时,自动调用该方法。一个类必须有constructor方法,如果没有显式定义,一个空的constructor方法会被默认添加。

class Point(){}
//等同于
class Point{
    constructor(){}
}

类的实例对象

与ES5一样,实例的属性除非显示的定义在其本身(即定义在this对象上),否则都是定义在原型上(即定义在class上)

class Point{
    constructor(x,y){
        this.x = x;
        this.y = y;
    }
    toString(){
        return '('+this.x+','+this.y+')';
    }
}
var point = new Point();
point.toString() //(2,3)

point.hasOwnProperty('x') //true
point.hasOwnProperty('y') //true
point.hasOwnProperty('toString') //false
point.__proto__.hasOwnProperty('toString') //true                                                                                                                                                                                                                                                   

class的继承

class ColorPoint extends Point{
    constructor(x,y,color){
        super(x,y);
        this.color = color;
    }
    toString(){
        return this.color+' '+super.toString()//调用父类的toString()
    }
}

super关键字

在子类的构造函数中,只有调用super之后,才能使用this关键字,否则会报错。这是因为子类实例的构建,是基于对父类实例加工,只有super方法才能返回父类实例。

super作为函数

super(),代表父类的构造函数,但是返回的子类B的实例,即super内部的this指的是B;

作为函数时,super()只能用在子类的构造函数之中,用在其他地方会报错;

class A{}
class B extend A{
    constructor(){
        super();
    }
}

super作为对象

class A{
    p(){
        return 2;
    }
}
class B extends A{
    constructor(){
        super();
        console.log(super.p()); //2
    }
}

上面代码中,子类B当中super.p(),就是将super当作一个对象使用,这时,super在普通方法之中,指向A.prototype,所以super.p()就相当于A.prototype.p();

注意,由于super指向父类的原型对象,所以定义在父类实例上的方法或属性,是无法通过super调用的。

有关ES6新特性----面试的更多相关文章

  1. 使用canal同步MySQL数据到ES - 2

    文章目录一、概述简介原理模块二、配置Mysql使用版本环境要求1.操作系统2.mysql要求三、配置canal-server离线下载在线下载上传解压修改配置单机配置集群配置分库分表配置1.修改全局配置2.实例配置垂直分库水平分库3.修改group-instance.xml4.启动监听四、配置canal-adapter1修改启动配置2配置映射文件3启动ES数据同步查询所有订阅同步数据同步开关启动4.验证五、配置canal-admin一、概述简介canal是Alibaba旗下的一款开源项目,Java开发。基于数据库增量日志解析,提供增量数据订阅&消费。Git地址:https://github.co

  2. 【Java 面试合集】HashMap中为什么引入红黑树,而不是AVL树呢 - 2

    HashMap中为什么引入红黑树,而不是AVL树呢1.概述开始学习这个知识点之前我们需要知道,在JDK1.8以及之前,针对HashMap有什么不同。JDK1.7的时候,HashMap的底层实现是数组+链表JDK1.8的时候,HashMap的底层实现是数组+链表+红黑树我们要思考一个问题,为什么要从链表转为红黑树呢。首先先让我们了解下链表有什么不好???2.链表上述的截图其实就是链表的结构,我们来看下链表的增删改查的时间复杂度增:因为链表不是线性结构,所以每次添加的时候,只需要移动一个节点,所以可以理解为复杂度是N(1)删:算法时间复杂度跟增保持一致查:既然是非线性结构,所以查询某一个节点的时候

  3. ES基础入门 - 2

    ES一、简介1、ElasticStackES技术栈:ElasticSearch:存数据+搜索;QL;Kibana:Web可视化平台,分析。LogStash:日志收集,Log4j:产生日志;log.info(xxx)。。。。使用场景:metrics:指标监控…2、基本概念Index(索引)动词:保存(插入)名词:类似MySQL数据库,给数据Type(类型)已废弃,以前类似MySQL的表现在用索引对数据分类Document(文档)真正要保存的一个JSON数据{name:"tcx"}二、入门实战{"name":"DESKTOP-1TSVGKG","cluster_name":"elasticsear

  4. 西安华为OD面试体验 - 2

    西安华为OD面试体验开始投简历技术面试进展工作进展开始投简历去年一整年一直在考研和工作之间纠结,感觉自己的状态好像当时的疫情一样差劲。之前刚毕业的时候投了个大厂的简历,结果一面写算法的时候太拉跨了,虽然知道时dfs但是代码熟练度不够,放在平时给足时间自己可以调试通过,但是熟练度不够那面试当时就写不出来被刷了。说真的算法学到后期我感觉最重要的是熟练度和背板子(对于我这种普通玩家来说),面试题如果一上来短时间内想不出思路就完蛋了。然后由于当时找的工作不是很理想就又想考研了。但是考研是有风险的,我自我感觉自己可能冲不上那个学校,而找工作一个没成可以继续找嘛。本着抱着试试看的态度在boss上投了简历,

  5. IDEA 2023.1 正式发布,新特性简介 - 2

     昨晚看到IDEA官推宣布IntelliJIDEA2023.1正式发布了。简单看了一下,发现这次的新版本包含了许多改进,进一步优化了用户体验,提高了便捷性。至于是否升级最新版本完全是个人意愿,如果觉得新版本没有让自己感兴趣的改进,完全就不用升级,影响不大。软件的版本迭代非常正常,正确看待即可,不持续改进就会慢慢被淘汰!根据官方介绍:IntelliJIDEA2023.1针对新的用户界面进行了大量重构,这些改进都是基于收到的宝贵反馈而实现的。官方还实施了性能增强措施,使得Maven导入更快,并且在打开项目时IDE功能更早地可用。由于后台提交检查,新版本提供了简化的提交流程。IntelliJIDEA

  6. [面试直通版]操作系统核心之进程、线程与协程(下) - 2

    点击->操作系统复习的文章集目录操作系统线程线程是什么进程与线程的关系用户态/内核态操作系统资源管理内核态用户态内核态/用户态切换程序运行类型分析计算密集型IO密集型结合进程,线程来理解程序运行类型分析协程基础上下文切换协程协程为什么叫协作式线程?协程的优缺点操作系统线程典型问题:简述进程和线程的区别以下内容带您一步步了解线程是什么比进程更小的独立运行的基本单位-线程(Threads)线程的提出主要是为了提高系统内程序并发执行的程度,从而进一步提升系统的吞吐量,充分发挥多核CPU的优越性而设计的引入进程是为了操作系统更加方便地管理程序,使得多个程序能并发管理和执行而线程则是为了减少程序在并发执

  7. 【华为OD技术面试 | 真八股 】MySQL联合索引,谈springIOC的理解,谈springAOP的理解,Erika和zookeeper等问题 - 2

    文章目录华为OD面试流程1.mysql数据库建了两个字段,且设置了联合索引,如果其中有一个字段为空会出现什么问题?2.谈谈springIOC的理解,有什么好处,解决了什么问题3.谈谈springAOP的理解,切面编程有没有实际应用,有哪些注解,作用是什么,有那些应用场景?4.Erika和zookeeper有了解过吗,作用是什么,主要解决了什么问题5.谈谈JDK、JRE、JVM的理解,区别是什么6.谈谈对泛型的理解7.JVM的组成华为OD面试流程机试:三道算法题,关于机试,橡皮擦已经准备好了各语言专栏,可以直接订阅。性格测试:机试技术一面(本专栏核心)技术二面(本专栏核心)主管面试定级定薪发of

  8. 关于ES集群信息的一些查看 - 2

    文章目录查看ES信息查看节点信息查看分片信息实际场景下ES分片及副本数量应该怎么分关于ES的灵活使用查看ES信息查看版本kibana:GET/查看节点信息GET/_cat/nodes?v解释:ip:集群中节点的ip地址;heap.percent:堆内存的占用百分比;ram.percent:总内存的占用百分比,其实这个不是很准确,因为buff/cache和available也被当作使用内存;cpu:cpu占用百分比;load_1m:1分钟内cpu负载;load_5m:5分钟内cpu负载;load_15m:15分钟内cpu负载;node.role:上图的dilmrt代表全部权限master:*代表

  9. linux查看es节点使用情况,elasticsearch(es) 如何查看当前集群中哪个节点是主节点(master) - 2

    elasticsearch查看当前集群中的master节点是哪个需要使用_cat监控命令,具体如下。查看方法es主节点确定命令,以kibana上查看示例如下:GET_cat/nodesv返回结果示例如下:ipheap.percentram.percentcpuload_1mload_5mload_15mnode.rolemastername172.16.16.188529952.591.701.45mdi-elastic3172.16.16.187329950.990.991.19mdi-elastic2172.16.16.231699940.871.001.03mdi-elastic4172

  10. Vue3的新特性 - 2

    Vue3的新特性包括:CompositionAPI:一种新的API风格,可将有关组件功能的代码逻辑封装在单独的函数中,从而更好地管理和重用代码。Teleport:可以让组件在DOM层次结构中的任何位置渲染。Suspense:一种新的异步渲染模式,可以优化应用程序的性能。更快的渲染速度:Vue3使用了新的虚拟DOM算法,并且对渲染过程进行了优化,因此在渲染大型应用时性能更高。更小的包大小:Vue3的打包大小比Vue2更小,因为它不再需要依赖像vue-template-compiler这样的工具。其他改进:Vue3还具有其他一些改进,例如更好的TypeScript支持、更好的错误提示和更好的调试工

随机推荐