前端面试题[ES6]

一、let, var, const 区别

 在 JavaScript 中,`let`,`var`和`const`都用于声明变量,但是它们有一些不同:

1. `var`是 ES5 的关键字,`let`和`const`是 ES6 引入的关键字。

2. `var` 变量声明是函数作用域,而 `let` 和 `const` 变量声明是块作用域。因此,可以使用 `let` 或 `const` 代替 `var` 来声明变量,有效地强制在块级作用域中声明变量。

3. `var` 可以重复声明同一个变量,而 `let` 和 `const` 不允许在同一个作用域内重复声明同一个变量。

4. `var` 变量可以被重新赋值,而 `const` 变量不能被重新赋值,但是它们都可以修改其值属性。

5. `let` 和 `const` 都有暂时性死区的概念,也就是在声明前使用变量会导致 `ReferenceError` 错误。

总之,`let` 和 `const` 是更加安全和可控的变量声明方式,推荐在代码中使用它们。`var` 还是存在的一些场景,但通常 `let` 和 `const` 是更好的选择。

二、es6解构赋值

ES6解构赋值是一种从数组或对象中提取值并赋值给变量的语法。可以通过解构赋值将数组或对象的值赋值给变量,也可以将多个变量赋值给数组或对象的属性。

数组解构赋值示例:

let arr = [1, 2, 3];
let [a, b, c] = arr;
console.log(a); // 输出1
console.log(b); // 输出2
console.log(c); // 输出3

对象解构赋值示例:

let obj = {name: 'Tom', age: 18};
let {name, age} = obj;
console.log(name); // 输出'Tom'
console.log(age); // 输出18

可以在解构赋值中使用默认值:

let [a, b = 2] = [1];
console.log(a); // 输出1
console.log(b); // 输出2

也可以嵌套使用解构赋值:

let arr = [1, [2, 3], 4];
let [a, [b, c], d] = arr;
console.log(a); // 输出1
console.log(b); // 输出2
console.log(c); // 输出3
console.log(d); // 输出4

除了数组和对象的解构赋值,还可以使用剩余参数和展开运算符:

// 剩余参数
let arr = [1, 2, 3, 4];
let [a, b, ...rest] = arr;
console.log(a); // 输出1
console.log(b); // 输出2
console.log(rest); // 输出[3, 4]

// 展开运算符
let arr1 = [1, 2];
let arr2 = [3, 4];
let arr3 = [...arr1, ...arr2];
console.log(arr3); // 输出[1, 2, 3, 4]

let obj1 = {name: 'Tom'};
let obj2 = {age: 18};
let obj3 = {...obj1, ...obj2};
console.log(obj3); // 输出{name: 'Tom', age: 18}

 三、箭头函数与普通函数区别

箭头函数与普通函数的区别主要有以下几点:

  1. 箭头函数没有自己的 this,它的 this 指向的是定义时所在的作用域中的 this,而不是运行时所在的作用域中的 this。因此,在箭头函数中不能通过 this 来访问到它所在的函数的 this

  2. 箭头函数不能用作构造函数,不能使用 new 关键字调用。因为箭头函数没有自己的 this,也没有 prototype 属性。

  3. 箭头函数没有自己的 arguments 对象,也不能使用 arguments 变量获取参数列表。箭头函数的参数只能通过显式命名参数或使用剩余参数来获取。

  4. 箭头函数不能使用 yield 关键字,因此不能用作生成器函数。

  5. 箭头函数的语法更加简洁,可以省略 {}return 关键字。当函数体只有一条语句时,可以直接将语句作为返回值。

例如,普通函数和箭头函数的写法对比如下:

普通函数:

function add(x, y) {
  return x + y;
}

箭头函数:

let add = (x, y) => x + y;

可以看到,箭头函数的语法更加简洁,代码量更少。但是需要注意,箭头函数的使用场景和普通函数并不完全相同,需要根据具体情况进行选择。

四、class与class继承 promise使用及实现

  1. class与class继承

class是ES6中一个新增的关键字,用于定义类。它可以用来声明一个类,类中可以包含构造函数、属性和方法。示例代码如下:

class Person {
  constructor(name, age) {
    this.name = name;
    this.age = age;
  }

  sayHello() {
    console.log(`Hello, my name is ${this.name}, I am ${this.age} years old.`);
  }
}

const person = new Person('Tom', 18);
person.sayHello(); // 输出:Hello, my name is Tom, I am 18 years old.

class继承则是基于现有类创建新类的一种方式,新类会继承原有类的属性和方法。可以通过关键字extends实现。示例代码如下:

class Student extends Person {
  constructor(name, age, grade) {
    super(name, age); // 调用父类的构造函数
    this.grade = grade;
  }

  sayHello() {
    console.log(`Hello, my name is ${this.name}, I am ${this.age} years old. I am in grade ${this.grade}.`);
  }
}

const student = new Student('Alice', 16, 10);
student.sayHello(); // 输出:Hello, my name is Alice, I am 16 years old. I am in grade 10.

  1. promise使用及实现

promise是一种可用于异步编程的机制,它可以让我们更加方便地处理异步操作的结果。promise有三种状态:pending(等待中)、fulfilled(已成功)和rejected(已失败)。promise支持链式调用,每个调用返回的都是一个新的promise对象。示例代码如下:

function fetchData() {
  return new Promise((resolve, reject) => {
    setTimeout(() => {
      resolve('data'); // 异步操作成功后将执行resolve,并将结果作为参数传入
      // reject('error'); // 异步操作失败后将执行reject,并将错误信息作为参数传入
    }, 1000);
  });
}

fetchData()
  .then(result => {
    console.log(result); // 输出:data
    return 'newData';
  })
  .then(result => {
    console.log(result); // 输出:newData
  })
  .catch(error => {
    console.log(error); // 输出:error
  })
  .finally(() => {
    console.log('done'); // 输出:done
  });

上面的代码中,fetchData函数返回一个新的Promise对象,并在异步操作完成后调用resolvereject函数。在调用fetchData函数后,我们通过then方法来指定当异步操作成功时执行的回调函数,并通过catch方法来指定当异步操作失败时执行的回调函数。在最后我们可以通过finally方法指定一个回调函数,在所有promise对象完成后执行。

实现一个简单的promise对象:

class MyPromise {
  constructor(executor) {
    this._status = 'pending'; // 初始状态为等待中
    this._value = undefined; // 成功时的值
    this._reason = undefined; // 失败时的原因

    const resolve = (value) => {
      if (this._status === 'pending') {
        this._status = 'fulfilled';
        this._value = value;
      }
    }

    const reject = (reason) => {
      if (this._status === 'pending') {
        this._status = 'rejected';
        this._reason = reason;
      }
    }

    try {
      executor(resolve, reject);
    } catch (error) {
      reject(error);
    }
  }

  then(onFulfilled, onRejected) {
    if (this._status === 'fulfilled') {
      onFulfilled(this._value);
    } else if (this._status === 'rejected') {
      onRejected(this._reason);
    }
  }

  catch(onRejected) {
    if (this._status === 'rejected') {
      onRejected(this._reason);
    }
  }

  finally(onFinally) {
    onFinally();
  }
}

// 使用示例
const promise = new MyPromise((resolve, reject) => {
  setTimeout(() => {
    resolve('data');
  }, 1000);
});

promise.then(result => {
  console.log(result);
}).finally(() => {
  console.log('done');
});

五、async,await

async和await是JavaScript中的关键字,它们用于处理异步操作。

async用于定义一个异步函数,而await用于等待一个异步操作完成。当我们调用一个返回Promise对象的异步函数时,我们可以在它前面加上await关键字,JavaScript引擎会等待这个异步操作完成并返回结果,然后再继续执行后面的代码。

这样就可以避免使用回调函数或者Promise链等复杂的异步操作处理方式。async/await使得JavaScript代码的可读性和可维护性更好,并且可以避免回调函数地狱的情况。

六、generator函数 Es6中新的数据类型symbol

generator函数是ES6中引入的一种新型的函数类型。它通过生成器函数,可以生成一个迭代器,这个迭代器可以用来迭代一个可迭代对象。在generator函数中,使用yield语句可以暂停函数的执行,并将返回值传递给迭代器;使用next()方法可以继续执行函数,接着执行yield语句后面的代码。

Symbol是ES6中引入的一种新的基本数据类型,它是一种独一无二的标识符,用来表示一个对象的唯一属性名。Symbol值可以作为对象属性的键,并且不会被遍历到,因此它可以用来定义一些私有属性或者方法。在ES6中,通过Symbol()函数可以生成一个全局唯一的Symbol值。

七、Es6中Set、WeakSet、Map、WeakMap数据结构 es6模块规范

  1. Set:Set是一种集合数据结构,可以用来存储一组唯一的值。在Set中,每个值都只能出现一次,重复的值会自动被过滤掉。

  2. WeakSet:WeakSet也是一种集合数据结构,但是它只能存储对象类型的值,并且存储的对象是弱引用。

  3. Map:Map是一种键值对数据结构,它可以用来存储任意类型的值。在Map中,可以使用任何类型的值作为键,而且它们是不重复的。

  4. WeakMap:WeakMap也是一种键值对数据结构,但是它只能使用对象类型的值作为键,并且存储的对象是弱引用。

  5. ES6模块规范:ES6模块规范定义了一套模块化开发的标准,可以让我们方便地将代码拆分成多个模块,以便于维护和复用。在ES6模块规范中,每个模块都是一个独立的文件,它们之间通过importexport语句来实现模块之间的依赖关系。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值