前端面试题让前端飞

前端面试:ES6 基础知识点 & ES6 相关面试题

2021-06-21  本文已影响0人  前小小

前言

ECMAScript 6.0(简称ES6)是 JavaScript 语言的下一代标准。它的目标,是使得 JavaScript 语言可以用来编写复杂的大型应用程序,成为企业级开发语言。

let const

在es6之前,定义变量都是使用var,但是var存在一些问题,比如可以重复声明,仅支持函数作用域问题。所以es6设计了let和const来弥补不足的地方。let和const具备哪些特性?

let

const

块级作用域

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

var temp = new Date();

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

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

// 块级作用域写法
{
  let temp = ...;
  ...
}
// ES6严格模式
'use strict';
if (true) {
  function f() {}
}
// 不报错
// 不报错
'use strict';
if (true) {
  function f() {}
}

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

扩展运算符:

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

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 = `abcdefgh`;
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

箭头函数:

//省略写法
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!";
  }
};

set数据结构

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)}
)

async await

async其实就是对Generator的封装,只不过async可以自动执行next()。

async function read () {
    let data1= await new Promise(resolve => {
        resolve('100')
    })
    let data2 = await 200
    
    return 300
}

(1)async 返回值

async 默认返回一个 Promise,如果 return 不是一个 Promise 对象,就会被转为立即 resolve 的 Promise,可以在 then 函数中获取返回值。

async 必须等到里面所有的 await 执行完,async 才开始 return,返回的 Promise状态才改变。除非遇到 return 和错误。

async function fn () {
    await 100
    await 200
    return 300
}
fn().then(res => {
    console.log9(res) // 300
})

(2)await

await 也是默认返回 Promise 对象,如果 await 后面不是一个 Promise 对象,就会转为立即 resolve 的 Promise

如果一个 await 后面的 Promise 如果为 reject,那么整个 async 都会中断执行,后面的awiat都不会执行,并且抛出错误,可以在 async的catch中捕获错误

async function f() {
  await Promise.reject('error');
  await Promise.resolve('hello world'); // 不会执行
}
f().then(res =>{

}).catch(err=>{
    console.log(err)  // error
})

如果希望一个await失败,后面的继续执行,可以使用try...catch或者在await后面的Promise跟一个catch方法:

// try...catch
async function f() {
  try {
    await Promise.reject('出错了');
  } catch(e) {
  }
  return await Promise.resolve('hello world');
}

f()
.then(v => console.log(v))   // hello world

// catch
async function f() {
  await Promise.reject('出错了')
    .catch(e => console.log(e));   // 出错了
  return await Promise.resolve('hello world');
}

f()
.then(v => console.log(v))  // hello world

箭头函数

箭头函数在写法上对es5做了一些修整,代码看起来更显得简洁

// 定义一个箭头函数
let a = (arg)=>{ //  这里=>符号就相当于function关键字
    return arg+=1
}
// 也可以简写为
let a = arg => arg+=1

箭头函数也对 this 的指向做了修整

es6 之前的函数的 this 指向调用函数时所在的对象,而箭头函数的 this 指向函数定义时所在的对象

// 普通函数
 var obj = {
   say: function () {
     setTimeout(function() {
       console.log(this)
     });
   }
 }
// 箭头函数
var obj = {
    say: function () {
        setTimeout(() => {
            console.log(this)
        });
    }
}
obj.say(); // obj

模板字符串

模板字符串是为了解决使用+号拼接字符串的不便利而出现的。它的功能非常强大,但是我们大多数时候使用它则非常简单。

// es6
const a = 20;
const b = 30;
const string = `${a}+${b}=${a+b}`;

// es5
var a = 20;
var b = 30;
var string = a + "+" + b + "=" + (a + b);

使用 `` 将整个字符串包裹起来,而在其中使用 ${} 来包裹一个变量或者一个表达式。

class

ES6 提供了更接近传统语言的写法,引入了 Class(类)这个概念,作为对象的模板。通过class关键字,可以定义类。

先看如何定义一个class类:

class User {
    constructor(name) {          // 构造器,相当于es5中的构造函数
        this.name = name         // 实例属性
    }
    showName(){                  // 定义类的方法,不能使用function关键字,不能使用逗号分隔
        console.log(this.name)   
    }
}
var foo = new User('foo')

(1)constructor

es6 中 class 类专用的构造器,相当于之前定义的构造函数,每个类都必须有constructor,如果没有则自动添加一个空的 constructor 构造器。
创建实例的时候自动执行 constructor 函数
constructor 中的 this 指向实例,并且默认返回 this(实例)

(2)class 类的 prototype

其实 class 的基本类型就是函数(typeof User = "function"),既然是函数,那么就会有 prototype 属性。

类的所有方法都是定义在 prototype上

class User {
  constructor() {
    // ...
  }

  toString() {
    // ...
  }

  toValue() {
    // ...
  }
}
User.toValue()             // err User.toValue is not a function
User.prototype.toValue()   // 可以调用toValue方法

// 等同于

User.prototype = {
  constructor() {},
  toString() {},
  toValue() {},
};

(3)类的实例

//定义类
class Point {

  constructor(x, y) {
    this.x = x;
    this.y = y;
  }

  toString() {
    return '(' + this.x + ', ' + this.y + ')';
  }
}

var point = new Point(2, 3);

point.toString() // (2, 3)

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

(4)静态方法

如果在类中定义一个方法的前面加上 static 关键字,就表示定义一个静态方法,静态方法不会被实例继承,但会被子类继承,所以不能通过实例使用静态方法,而是通过类直接调用。

class User {
    constructor(name){
        this.name = name
    }
    static show(){
        console.log('123')
    }
}
class VipUser extends User{}
VipUser.show()                    // 123
User.show()                       // 123
var foo = new User('foo')
foo.show()                        // foo.show is not a function

(5)静态属性

class User{}
User.name = 'foo' // 为class定义一个静态属性

class VipUser extends User{}
console.log(VipUser.name)         // foo

var foo = new User()
console.log(foo.name)             // undefined

最后

附赠一份【117页】前端面试题大全,内容包括:HTML相关、CSS相关、JavaScript相关、JQuery相关,数据请求相关,Vue相关、ES6相关,React相关、微信小程序相关,兼容性问题,浏览器适配问题 等等

其中 ES6 相关面试题如下:

ES6相关面试题

需要【117页】前端面试题大全完整版(含解析)PDF文档的朋友 可以加入这边的Q裙:【624369675】,免费领取!
上一篇下一篇

猜你喜欢

热点阅读