前端ES6+面试八股常考题

1. letconstvar 的区别

  • var
    • 作用域:函数作用域。
    • 重复声明:允许重复声明。
    • 变量提升:变量会被提升到函数或全局作用域的顶部,但初始化不会被提升。
    • 适用场景:ES6 之前的标准,现在不推荐使用。
  • let
    • 作用域:块级作用域。
    • 重复声明:不允许重复声明。
    • 变量提升:不会被提升,使用前必须声明。
    • 适用场景:变量值会改变的场景。
  • const
    • 作用域:块级作用域。
    • 重复声明:不允许重复声明。
    • 变量提升:不会被提升,使用前必须声明。
    • 适用场景:变量值不会改变的场景。

示例代码

if (true) {
    var variable = "var variable";
    let letVariable = "let variable";
    const constVariable = "const variable";
    console.log(variable); // "var variable"
    console.log(letVariable); // "let variable"
    console.log(constVariable); // "const variable"
}
console.log(variable); // "var variable"(变量提升)
console.log(letVariable); // ReferenceError: letVariable is not defined
console.log(constVariable); // ReferenceError: constVariable is not defined

2. ES6 箭头函数和普通函数的区别

  • 定义方式
    • 普通函数:function functionName() {}
    • 箭头函数:const functionName = () => {}
  • 参数处理
    • 箭头函数可以省略括号,如果只有一个参数。
    • 箭头函数可以省略花括号和 return,如果函数体只有一条语句。
  • this 指向
    • 普通函数的 this 指向取决于调用方式。
    • 箭头函数的 this 指向在定义时就已经确定,继承自外层作用域的 this
  • arguments 对象
    • 普通函数有 arguments 对象。
    • 箭头函数没有自己的 arguments 对象,但可以访问外层函数的 arguments
  • new 关键字
    • 普通函数可以用 new 关键字调用。
    • 箭头函数不能用 new 关键字调用。

示例代码

const obj = {
    id: "OBJ",
    a: function () {
        console.log(this.id); // "OBJ"
    },
    b: () => {
        console.log(this.id); // "undefined"(在严格模式下)
    },
};

obj.a(); // "OBJ"
obj.b(); // "undefined"(在严格模式下)

3. ES6 箭头函数能当构造函数吗?

不能。箭头函数没有自己的 this,没有 arguments,没有 prototype 属性,且无法通过 new 关键字调用。

示例代码

let fun = () => {
    console.log("我是箭头函数");
};
new fun(); // TypeError: fun is not a constructor

4. ES6 新增的 Symbol 基础数据类型有什么作用?

Symbol 是一个唯一的、不可变的数据类型,主要用于定义对象的唯一属性名,避免属性名冲突。

示例代码

let mySymbol = Symbol('mySymbol');
let obj = {
    [mySymbol]: 'value'
};
console.log(obj[mySymbol]); // "value"

5. ES Module 与 CommonJS 模块方案有什么异同?

  • 相同点
    • 都是 JavaScript 的模块化规范,都可以用来导入导出模块。
  • 不同点
    • CommonJS
      • 语法:使用 require() 导入,module.exportsexports 导出。
      • 加载机制:同步加载,运行时加载。
      • 适用场景:主要用于 Node.js。
    • ES Module
      • 语法:使用 import 导入,export 导出。
      • 加载机制:支持异步加载,编译时加载。
      • 适用场景:现代浏览器和 Node.js。

示例代码

// CommonJS
// module.js
const cjsFun = () => {
    console.log("CommonJS");
};
module.exports = { cjsFun };

// app.js
const { cjsFun } = require("./module.js");
cjsFun(); // "CommonJS"

// ES Module
// module.js
export const esFun = () => {
    console.log("ES Module");
};

// app.js
import { esFun } from "./module.js";
esFun(); // "ES Module"

6. ES6 箭头函数的 this 指向哪里?

箭头函数的 this 指向在定义时就已经确定,继承自外层作用域的 this

示例代码

function Outer() {
    this.name = 'Outer';

    const InnerArrow = () => {
        console.log(this.name); // "Outer"
    };

    this.innerArrow = InnerArrow;
}

const obj = new Outer();
obj.innerArrow(); // "Outer"

7. ES6 扩展运算符的作用及使用场景

扩展运算符 (...) 用于将数组或对象展开成一系列参数,或合并多个参数为一个数组。

示例代码

// 数组展开
const arr1 = [1, 2, 3];
const arr2 = [4, 5, 6];
const combinedArray = [...arr1, ...arr2]; // [1, 2, 3, 4, 5, 6]

// 对象展开
const obj1 = { a: 1 };
const obj2 = { b: 2 };
const mergedObj = { ...obj1, ...obj2 }; // { a: 1, b: 2 }

// 字符串展开
const str = 'Hello';
const letters = [...str]; // ['H', 'e', 'l', 'l', 'o']

// 函数调用中的参数
function myFunction(x, y, z) {
    console.log(x, y, z);
}
const args = [1, 2, 3];
myFunction(...args); // 1 2 3

8. ES6 的 Proxy(代理)可以实现什么功能?

Proxy 是一个强大的工具,允许我们创建一个对象的代理,并拦截对该对象的各种操作,从而实现自定义行为。

示例代码

const handler = {
    get: (target, prop) => {
        if (prop in target) {
            return target[prop];
        } else {
            throw new Error(`Property ${prop} does not exist.`);
        }
    }
};

const proxy = new Proxy({}, handler);
proxy.a = 1;
console.log(proxy.a); // 1

9. ES6 中的数组解构和对象解构

  • 数组解构

    const [a, b, c] = [1, 2, 3];
    console.log(a); // 1
    console.log(b); // 2
    console.log(c); // 3
    
  • 对象解构

    const user = { name: 'Alice', age: 25 };
    const { name, age } = user;
    console.log(name); // "Alice"
    console.log(age); // 25
    

10. ES6 中,如何提取深度嵌套的对象的指定属性?

使用对象解构赋值来提取深度嵌套的对象属性。

示例代码

const deepObject = {
    level1: {
        level2: {
            level3: {
                targetProp: 'desired value'
            }
        }
    }
};

const { level1: { level2: { level3: { targetProp } } } } = deepObject;
console.log(targetProp); // "desired value"

11. ES6 中的 Rest 参数

Rest 参数用于表示不确定数量的参数,将传入的多个参数包装成一个数组。

示例代码

function sum(...numbers) {
    return numbers.reduce((acc, curr) => acc + curr, 0);
}
console.log(sum(1, 2, 3, 4)); // 10

12. ES6 新增的模板语法

模板字符串使用反引号 () 包裹字符串,支持插值表达式 ${}`。

示例代码

const name = "Alice";
const greeting = `Hello, ${name}!`;
console.log(greeting); // "Hello, Alice!"

13. ES6 新增的字符串处理函数

  • includes():判断是否包含另一个字符串。
  • trim():去除字符串两端的空格。
  • repeat():将原字符串重复 n 次。
  • replaceAll():将所有匹配的字符串替换为新字符串。
  • split():根据指定的分隔符,将字符串分割成数组。
  • slice():截取指定位置的字符串。
  • substring():截取指定位置的字符串。
  • startsWith():判断是否以某个字符串开头。
  • endsWith():判断是否以某个字符串结尾。

示例代码

let str = "Hello, world!";
console.log(str.includes("world")); // true
console.log(str.trim()); // "Hello, world!"
console.log(str.repeat(2)); // "Hello, world!Hello, world!"
console.log(str.replaceAll("Hello", "Hi")); // "Hi, world!"
console.log(str.split(',')); // ["Hello", " world!"]
console.log(str.slice(7, 12)); // "world"
console.log(str.substring(7, 12)); // "world"
console.log(str.startsWith("Hello")); // true
console.log(str.endsWith("world!")); // true

总结

ES6 引入了许多新特性,包括 letconst、箭头函数、模板字符串、解构赋值、扩展运算符、Proxy 等,这些特性极大地提升了 JavaScript 的开发效率和代码可读性。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值