大厂HR面试必备ES6中的深入浅出面试题知识点

ESMAScript6简介,ES6是JavaScript语言的下一代标准,目的是让JavaScript语言可以写复杂的大型应用程序,成为企业级语言。那么ECMAScript和JavaScript的关系到底是什么呢?两者有着什么样的联系?

JavaScript的创造者Netscape公司,将JavaScript提交给国际标准化组织ECMA,希望这种语言可以成为国际标准,次年,ECMA决定了浏览器脚本语言的标准,并称为ECMAScript。

因某些原因,一是商标,二是这门语言制定者是ECMA,不是Netscape。ECMAScript和JavaScript的关系是前者是后者的规格,后者是前者的一种实现。

ES6 let和const命令

let命令:

基本用法,ES6新增let命令,用来声明变量,用法类似于var,但所声明的变量,只在let命令所在的代码块内有效。

{
 let a = 10;
 var b = 1;
}

a // ReferenceError: a is not defined
b // 1

let和var声明了两个变量,然后在代码块之外调用这两个变量,结果let声明的变量报了错,var声明的变量返回了正确的值。说明,let声明的变量只在它所在的代码块有效。

for(let i = 0; i<10; i++) {
}
console.log(i);
// ReferenceError: i is not defined
var a = [];
for(var i = 0; i<10; i++) {
 a[i] = function() {
  console.log(i);
 };
}
a[6](); // 10

使用let,声明的变量仅仅在块级作用域内有效:

var a = [];
for(let i = 0; i<10; i++){
 a[i] = function() {
  console.log(i);
 };
}
a[6](); // 6

变量i是let声明的,当前的i只在本轮循环有效,所以每一次循环的i其实都是一个新的变量,所以最后输出6。

不存在变量提升

var存在变量提升,let不会发生“变量提升”的现象,所以,变量一定要在声明后使用,不然会报错。

console.log(a); // 输出undefined
console.log(b); // 报错ReferenceError

var a = 1;
let b = 1;

var声明的变量会发生变量提升,该变量没用赋值就已经存在了,但是没有值,就会输出undefined,变量用let命令声明,不会发生变量提升,声明变量之前,变量是不存在的,如果用它,就会报错。

用let声明的变量是可以修改的,而用const一般用来声明常量,声明之后不能更改了。

let a = 1;
const b = 2;
a = 3;
b = 3; // 报错

var命令声明的变量会发生变量提升的现象,变量在声明之前使用,其值为undefined,而let命令声明的变量没有变量提升,如果在声明之前使用,会报错的。

暂时性死区,在一个块级作用域中对一个变量使用let声明前,该变量是不可使用,称为暂时性死区。

da = 'coding';
if(true) {
 // 在之前就定义 一个全局变量da,块内重新定义了一个da
 console.log(da); // 报错ReferenceError
 let da;
}

不允许重复声明:

let命令是不允许重复声明同一个变量的

if(true) {
 let da;
 let da; // 报错
}

function func(coding) {
 // 已经有个变量名的形参了
 let coding;
}
func() // 报错

在代码块内,使用let命令声明变量之前,该变量都是不可用的,称为暂时性死区。

if(true) {
 temp = 'da'; // ReferenceError
 console.log(temp); // ReferenceError

 let temp; // TDZ结束
 console.log(temp); // undefined

 temp = 12;
 console.log(temp); // 12
}

暂时性死区表明typeof不再是一个安全的操作

typeof x; // ReferenceError
let x;

变量x使用了let命令声明,所以存在死区,用到该变量就会报错,作为对比,如果一个变量根本没有被声明,使用typeof就不会报错

typeof dacoding // undefined

ES6:

var arr = [];
for(var i=0; i<10; i++) {
 arr.push(function() { console.log(i) })
}

arr.forEach(function(func) {
 func()
});
// ES5
var arr = [];
for(var i=0; i<10; i++){
 func.push((function(value){
  return function() {
   console.log(value);
  }
 }(i))
}
// ES6
for(let i = 0; i<10; i++) {
 func.push(function(){
  console.log(i)
 })
}

箭头函数的特点:不需要function关键字来创建函数,省略return关键字,继承当前上下文的this关键字。

let声明变量和const声明常量,两个都有块级作用域

ES5中没有块级作用域,var有变量提升,在let中,使用的变量一定要进行声明。箭头函数,定义不在使用关键字function(),而是用箭头 ()=> 来表示。模板字符串,是增强版的字符串,用反引号(`)表示,可以当作普通字符串使用,同时可以定义多行字符串。

解构赋值,ES6允许按照一定模式,从数组和对象中提取值,对变量进行赋值,for...of循环可以遍历数组,set和map结构。

set数据结构类似数组一样的,所有的数据都是唯一,没有重复的值,它本身是一个构造函数,class类的继承,ES6中不像ES5中使用原型链实现继承,引入了class概念可以用来继承了

// 基础用法
const da1 = function (参数1, 参数2, …, 参数N) { 函数声明 }
const da1 = (参数1, 参数2, …, 参数N) => { 函数声明 }

// 当只有一个参数时,圆括号是可选
const da2 = (单一参数) => { 函数声明 }
const da2 = 单一参数 => { 函数声明 }

// 没有参数时,圆括号不能省略
const da3 = () => { 函数声明 }

// 当函数体只是 return 一个单一表达式时,可以省略花括号和 return 关键词
const da4 = () => { return 表达式(单一) }
const da4 = () => 表达式(单一)

// 函数体返回对象字面表达式时,如果省略花括号和 return 关键词,返回值需要加括号
const da5 = () => { return {foo: 'bar'} }

const da5 = () => ({foo: 'bar'})
// 输出 {foo: 'bar'}

const da6 = () => {foo: 'bar'}
// 输出 undefined,大括号被识别为代码块

块级作用域:

es5只有全局作用域和函数作用域,没有块级作用域:

var temp = new Date();

function f() {
  console.log(temp);
  if (false) {
    var tmp = "hello world";
  }
}

f(); // undefined

es6的块级作用域:

function f1() {
  let n = 5;
  if (true) {
    let n = 10;
  }
  console.log(n); // 5
}
// IIFE 写法
(function () {
  var temp = ...;
  ...
}());

// 块级作用域写法
{
  let temp = ...;
  ...
}

es5中,函数只能在顶层作用域和函数作用域之中声明,不能在块级作用域中声明。

// 情况一
if (true) {
  function f() {}
}

// 情况二
try {
  function f() {}
} catch(e) {
}

// ES5的规定都是非法的
// ES5严格模式
'use strict';
if (true) {
  function f() {}
}
// 报错

在es6中引入了块级作用域,明确允许在块级作用域之中声明函数

// ES6严格模式
'use strict';
if (true) {
  function f() {}
}
// 不报错

es6的块级作用域声明函数只在使用大括号的情况下成立

// 不报错
'use strict';
if (true) {
  function f() {}
}

// 报错
'use strict';
if (true)
  function f() {}

箭头函数:

用了箭头函数,this就不是在指向window,而是父级了,不能够使用arguments对象了,不能用构造函数了,就是不能使用new命令了,否则会报错,不能使用yield命令,所以箭头函数不能用作Generator函数了。

map和set的区别:

set用于数据重组,map用于数据储存

set中元素不能重复,只有键值没有键名,类似数组,可以遍历,有方法add,delete,has等。

map的本质是键值对的集合,可以遍历,可以跟各种数据转换。

class类的出现:

//定义类
class Point {
  constructor(x,y) {
      //构造方法
       this.x = x; //this关键字代表实例对象
       this.y = y;
  }
  toString() {
       return '(' + this.x + ',' + this.y + ')';
  }
}

promise构造函数是同步执行的,then方法是异步执行的。

function Person(){
  this.age = 10;

  setInterval(() => {
    this.age++;    // this 正确地指向 p 实例
  }, 100);
}

var p = new Person();  // 1s后打印出 10
this.param = 1

const func1 = () => console.log(this.param)

const func2 = function() {
    console.log(this.param)
}

func1.apply({ param: 2 })   // 输出: 1
func2.apply({ param: 2 })   // 输出: 2

解构赋值:

let [a, b, c] = [1, 2, 3]
// a:1 b:2 c:3

let [a, [[b], c]] = [1, [[2], 3]]
// a:1 b:2 c:3

let [a, , b] = [1, 2, 3]
// a:1 b:3

let [a,...b] = [1, 2, 3]
// a:1 b:[2, 3]

let [a, b,...c] = [1]
// a:1 b:undefined c:[]

let [a, b = 4] = [null, undefined]
// a:null b:4

let [a, b = 4] = [1]
// a:1 b:4

let [a, b = 4] = [1, null]
// a:1 b:null

解构不成功的,其变量的值为undefined,解构指定默认值,如果该被解构变量的对应位置没有值,为空或者是undefined,默认值才有效。

let { a, b } = { a: 1, b: 2 }
// a:1 b:2

let { c } = { a: 1, b: 2 }
// c:undefined

let { c = 4 } = { a: 1, b: 2 }
// c:4

let { a: c } = { a: 1, b: 2 }
// c:1

let { a: c = 4, d: e = 5 } = { a: 1, b: 2 }
// c:1 e:5

let { length } = [1, 2]
// length:2

扩展运算符:

将一个数组转化为逗号分隔的参数序列

console.log(...[1, 2, 3])
// 1 2 3

console.log(1, ...[2, 3, 4], 5)
// 1 2 3 4 5

[...document.querySelectorAll('div')]
// [<div>, <div>, <div>]

{...{a: 1}, ...{a: 2, b: 3}}
// {a: 2, b: 3}

[...[1], ...[2, 3]]
// [1, 2, 3]

const arr = [1]
arr.push(...[2, 3])
// arr:[1, 2, 3

默认参数:

function log(x, y = 'World') {
    console.log(x, y)
}

log('Hello')
// Hello World

log('Hello', undefined)
// Hello World

log('Hello', 'China')
// Hello China

log(undefined, 'China')
// undefined China

log(, 'China')
// 报错 SyntaxError

log('Hello', '')
// Hello

log('Hello', null)
// Hello null

参数不传递或是传递undefined会让参数等于默认值,如果参数不是最后一个,不传递参数就会报错。

传递null不会让函数参数等于默认值。

// 获取函数所有的参数,rest 为数组
function func1(...rest){ /* ... */}

// 获取函数第一个参数外其他的参数,rest 为数组
function func1(val, ...rest){ /* ... */}

模板字符串:

var str = `abc
def
gh`;
console.log(str);
let name = "小明";
function a() {
    return "ming";
}
console.log(`我的名字叫做${name},年龄${17+2}岁,性别${'男'},游戏ID:${a()}`);

函数的默认参数:

function A(a,b=1){
    console.log(a+b);
}
A(1);    //2
A(2+3);  //5
function A(a,b=1){
    console.log(a+b);
}
A(1);    //2
A(2+3);  //5

箭头函数:

//省略写法
var people = name => 'hello' + name;

var getFullName = (firstName, lastName) => {
    var fullName = firstName + lastName;
    return fullName;
}

对象的扩展:

var foo = 'bar';
var baz = {foo};
//等同于  var baz = {foo: foo};
var o = {
  method() {
    return "Hello!";
  }
};

// 等同于
var o = {
  method: function() {
    return "Hello!";
  }
};

Promise对象

它有三种状态,分别是pending-进行中、resolved-已完成、rejected-已失败。

var promise = new Promise((resolve, reject) => {
    var success = true;
    if (success) {
        resolve('成功');
    } else {
        reject('失败');
    }
}).then(
    (data) => { console.log(data)},
    (data) => { console.log(data)}
)

set数据结构

size 数据的长度
add() 添加某个值,返回 Set 结构本身。
delete() 删除某个值,返回一个布尔值,表示删除是否成功。
has() 查找某条数据,返回一个布尔值。
clear() 清除所有成员,没有返回值。

Spread Operator 展开运算符(...)

将字符串转成数组

var str="abcd";
console.log([...str]) // ["a", "b", "c", "d"]

将集合转成数组

var set = new Set([1,2,3,4,5])
console.log([...set]) // [1, 2, 3, 4, 5]

数组的合并

var a1=[1,2,3];
var a2=[4,5,6];

console.log([...a1,...a2]);
//[1, 2, 3, 4, 5, 6]

rest参数 …变量名称

function func(...args){
    console.log(args);
    //[1, 2, 3, 4]
}
func(1, 2, 3, 4);

function f(x, ...y) {
    console.log(x);
    console.log(y);
}

f('a', 'b', 'c');     //a 和 ["b","c"]
f('a')                //a 和 []
f()                   //undefined 和 []

经典

var val = "全局变量";

{
  let val = "局部变量";
  console.log(val);
  // 局部变量
}

console.log(val);
// 全局变量

const val = "常量";
val = "123";
// Uncaught TypeError: Assignment to constant variable.

迭代器iterator、for...of和for...in

//for in 会继承
for (let i in iterable) {
    console.log(i);
    // 依次打印 0, 1, 2, "foo", "arrCustom", "objCustom"
}

for (let i in iterable) {
    if (iterable.hasOwnProperty(i)) {
        console.log(i);
        // 依次打印 0, 1, 2, "foo"
    }
}

// for of
for (let i of iterable) {
    console.log(i);
    // 依次打印 3, 5, 9
}

forEach,for in,for of三者区别:

forEach来遍历数组,for in 遍历对象或json,for of数组对象都可以遍历,for in 循环出的是key,for of 循环出的是value。

const promise = new Promise((resolve, reject) => {
    console.log(1);
    resolve();
    console.log(2);
})

promise.then(() => {
    console.log(3);
})

console.log(4);
1 2 4 3

Promise.then() 内部的代码在 当次 事件循环的 结尾 立刻执行

关于目前文章内容即涉及前端,PHP知识点,如果有兴趣即可关注,很荣幸,能被您发现,真是慧眼识英!也感谢您的关注,在未来的日子里,希望能够一直默默的支持我,我也会努力写出更多优秀的作品。我们一起成长,从零基础学编程,将 Web前端领域、数据结构与算法、网络原理等通俗易懂的呈现给小伙伴。分享 Web 前端相关的技术文章、工具资源、精选课程、热点资讯。

推荐阅读

1、你知道多少this,new,bind,call,apply?那我告诉你

2、为什么学习JavaScript设计模式,因为它是核心

3、一篇文章把你带入到JavaScript中的闭包与高级函数



意见反馈:
若本号内容有做得不到位的地方(比如:涉及版权或其他问题),请及时联系我们进行整改即可,会在第一时间进行处理。



感谢阅读,原创不易,喜欢就点个赞吧,这是我写作最大的动力。

欢迎关注达达的简书!

这是一个有质量,有态度的博客

原文地址:https://www.cnblogs.com/dashucoding/p/11875370.html

时间: 2024-11-08 23:38:02

大厂HR面试必备ES6中的深入浅出面试题知识点的相关文章

es6 中一些常见的新知识点

1,箭头函数,基本语法:()=>{}; 2,cookie的应用 3,页面重定向 4,void关键字 5,生成器function* () {},yield关键字,.next()方法,不能用箭头函数来创建生成器. 所谓"生成器",其实是一个函数,但是这个函数的行为会比较特殊: 它并不直接执行逻辑,而是用来生成另一个对象(这也正是"生成器"的含义) 它所生成的对象中的函数可以把逻辑拆开来,一片一片调用执行,而不是像普通的函数,只能从头到尾一次执行完毕 生成器的语法和

Java大厂笔试&amp;&amp;面试集合大全目录

面试技巧 掌握面试技巧,提升自身软实力! HR面试都会问什么问题?(上) HR面试都会问什么问题?(下) 作为一技术人员,面试前都需要做哪些准备? 面试题 Java各个阶段面试题,帮你提升自我,拿到高薪! Java面试集锦:25道线程类相关面试题与答案(一) Java面试集锦:集合思维导图与30道集合面试题 通过面试题,让我们来了解Collection 跳槽季,金三已过,银四你准备好了吗? 面试必备的数据库悲观锁与乐观锁 框架类 Spring面试题集锦(精选) 笔试题 JAVA相关笔试题,祝各位

Java常用英语汇总(面试必备)

Java常用英语汇总(面试必备) abstract (关键字)             抽象 ['.bstr.kt] access                            vt.访问,存取 ['.kses]‘(n.入口,使用权) algorithm                     n.算法 ['.lg.riem] annotation                     [java]代码注释 [.n.u'tei..n] anonymous                

ES6中的let和const关键字

  ES5中只有var能够定义变量,作用域是在function中. ES6中可以用let来定义变量,定义是块级作用域变量. { let a = 10; var b = 20; } console.log(a); //报错 console.log(b); //20 let的声明范围就是{}内部. 比如循环语句中定义函数,此时var: var arr = []; for(let i = 0 ; i < 10 ; i++){ arr[i] = function(){ console.log(i); }

面试必备:ArrayList源码解析(JDK8)

面试必备:ArrayList源码解析(JDK8) https://blog.csdn.net/zxt0601/article/details/77281231 概述很久没有写博客了,准确的说17年以来写博客的频率降低到一个不忍直视的水平.这个真不怪我,给大家解释一下. 一是自从做了leader,整天各种事,开会,过需求,无限循环.心很累,时间也被无线压榨 二 我本身也在学习一些其他的技术,比如ReactNative,也看了半天的kotlin,撸了几个groovy脚本.gradle插件. 三 是打

面试必备之悲观锁与乐观锁

悲观锁 总是假设最坏的情况,每次去拿数据的时候都认为别人会修改,所以每次在拿数据的时候都会上锁,这样别人想拿这个数据就会阻塞直到它拿到锁(共享资源每次只给一个线程使用,其它线程阻塞,用完后再把资源转让给其它线程).传统的关系型数据库里边就用到了很多这种锁机制,比如行锁,表锁等,读锁,写锁等,都是在做操作之前先上锁.Java中synchronized和ReentrantLock等独占锁就是悲观锁思想的实现. 乐观锁 总是假设最好的情况,每次去拿数据的时候都认为别人不会修改,所以不会上锁,但是在更新

MySQL的又一神器-锁,MySQL面试必备

原文链接:blog.ouyangsihai.cn >> MySQL的又一神器-锁,MySQL面试必备 1 什么是锁 1.1 锁的概述 在生活中锁的例子多的不能再多了,从古老的简单的门锁,到密码锁,再到现在的指纹解锁,人脸识别锁,这都是锁的鲜明的例子,所以,我们理解锁应该是非常简单的. 再到MySQL中的锁,对于MySQL来说,锁是一个很重要的特性,数据库的锁是为了支持对共享资源进行并发访问,提供数据的完整性和一致性,这样才能保证在高并发的情况下,访问数据库的时候,数据不会出现问题. 1.2 锁

面试必备的10道MySQL题

MySQL 事务,是我们去面试中高级开发经常会被问到的问题,很多人虽然经常使用 MySQL,SQL 语句也写得很溜,但是面试的时候,被问到这些问题,总是不知从何说起.下面我们先来了解一下什么是 MySQL事务,再给大家分享10道面试必备的MySQL题. MySQL事务是数据处理的最小操作单元,是一组不可在分割的操作集合,这个操作单元里的一系列操作要么都成功,要么都失败. 1.MySQL主从复制的原理.(1).主库必须开启二进制日志(2).当有增删改的语句时,会记录到主库的binlog中(3).主

前端面试之ES6篇(高产似母猪)

这也是前端面试经常询问的问题,经常问你es6出现了哪些新的特性,平时又使用过那些.在编写此教程的时候,第一句话往往就是面试常常问到的地方,然后后面就是他的详细解释,面试要求的内容我会用*标记出来.写技术文档是真的累啊,虽然是看别人的文档,但是你得看很多,而且还得自己总结啊.所以说要是觉得对你有用还是帮我点个star吧https://github.com/skychenbo 1.箭头函数需要注意的地方 2.ES6 let.const 3.set数据结构 4.promise对象的用法,手写一个pro