(ES6)前端八股文修炼Day2

news2024/11/18 1:38:35

在这里插入图片描述

1. let const var 的区别

  • var:

var 是在 ES5 中引入的声明变量的关键字。
具有函数作用域,而不是块作用域,这意味着使用 var 声明的变量在函数内部是可见的。
变量可以被重复声明,而且变量的值可以在声明前使用,这可能会导致一些意外的行为。
使用 var声明的变量可以被提升(hoisted),即变量的声明会被提升到作用域的顶部。

  • let:

let 是在 ES6(ES2015)中引入的声明变量的关键字。
具有块级作用域,只在声明它的块(如 {})内部有效,不会污染外部作用域。
变量不能被重复声明,如果尝试重复声明会导致语法错误。
let 声明的变量不会被提升,不存在变量提升的情况。

  • const:

const 也是在 ES6 中引入的声明变量的关键字。
具有块级作用域,类似于 let,不能重复声明,不存在变量提升。
声明一个常量,值在声明后不能被修改。
声明时必须进行初始化,而且初始化后就不能再修改常量的值。

  • 示例比较:
var x = 10;
if (true) {
    var x = 20;
    console.log(x); // 输出: 20
}
console.log(x); // 输出: 20

// 使用 let
let y = 10;
if (true) {
    let y = 20;
    console.log(y); // 输出: 20
}
console.log(y); // 输出: 10

// 使用 const
const z = 10;
// z = 20; // 会导致错误,常量值无法修改

在实际开发中,推荐优先使用 const,除非变量的值需要被修改才使用 let。避免使用 var,因为它存在一些不利于代码维护和调试的特性。希望这个解释对你有帮助!如果有任何其他问题,请随时告诉我。

2.const 对象的属性可以修改吗?

在 JavaScript 中,使用 const 声明的变量是常量,这意味着变量的引用不可变,但并不意味着变量所引用的对象是不可变的。对于对象(包括数组)来说,使用 const 声明的变量可以修改对象的属性,但不能重新赋值一个新的对象给这个变量。

下面是一个示例来说明这一点:

const person = {
    name: 'Alice',
    age: 30
};

// 修改对象属性是允许的
person.age = 31;
console.log(person); // 输出: { name: 'Alice', age: 31 }
// 重新赋值一个新对象会导致错误
// person = { name: 'Bob', age: 25 }; // 这行会导致错误

在上面的示例中,虽然 person 是用 const 声明的,我们仍然可以修改 person 对象的属性,如更改 age 的值。但是,尝试将一个新对象赋值给 person 会导致错误,因为常量变量的引用是不可变的。

3.new一个箭头函数的会怎么样?箭头函数与普通函数的区别?箭头函数的this指向哪⾥?

在 JavaScript 中,箭头函数和普通函数有一些重要的区别,其中包括在使用 new 关键字时的行为以及 this 的指向:

  1. 使用 new 关键字:

    • 普通函数可以使用 new 关键字来创建一个新的对象实例,这时候函数内部的 this 会指向新创建的实例。
    • 箭头函数不能用 new 关键字来创建实例,因为箭头函数没有自己的 this,它会继承外层作用域的 this
  2. 箭头函数与普通函数的区别:

    • 箭头函数没有自己的 thisargumentssupernew.target,它们都由外围最近一层非箭头函数决定。
    • 箭头函数不能用作构造函数,不能使用 new 关键字。
    • 箭头函数没有原型(prototype)属性。
  3. 箭头函数的 this 指向:

    • 箭头函数的 this 指向在函数定义时确定,取决于箭头函数外围作用域的 this
    • 普通函数的 this 则在函数被调用时才确定,取决于函数的调用方式(比如作为方法调用、函数调用、构造函数调用等)。

下面是一个示例来说明箭头函数的 this 指向和普通函数的区别:

function NormalFunction() {
    this.value = 42;
    setTimeout(function() {
        console.log(this.value); // 输出 undefined,普通函数的 this 指向全局对象或 undefined
    }, 1000);
}

const ArrowFunction = () => {
    this.value = 42;
    setTimeout(() => {
        console.log(this.value); // 输出 42,箭头函数的 this 指向外围作用域的 this
    }, 1000);
};

new NormalFunction(); // 输出 undefined
new ArrowFunction(); // 输出 42

在上面的示例中,setTimeout 内部的箭头函数能够访问到外围作用域的 this,而普通函数的 this 则不同,因为普通函数内部的 this 取决于调用方式。

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

扩展运算符(Spread Operator)是 ES6 中引入的一个功能强大的语法,用三个点(...)表示。它可以将一个可迭代对象(比如数组、对象等)拆分为独立的元素,或将多个参数展开为单独的参数。扩展运算符的作用和使用场景有以下几个方面:

  1. 在数组中的使用:

    • 将数组展开为独立的元素:

      const arr1 = [1, 2, 3];
      const arr2 = [4, 5, ...arr1, 6, 7];
      console.log(arr2); // 输出: [4, 5, 1, 2, 3, 6, 7]
      
    • 复制数组:

      const originalArray = [1, 2, 3];
      const copyArray = [...originalArray];
      
    • 合并数组:

      const arr1 = [1, 2];
      const arr2 = [3, 4];
      const combinedArray = [...arr1, ...arr2];
      
  2. 在函数调用中的使用:

    • 将数组作为参数传递给函数:
      const numbers = [1, 2, 3];
      function sum(a, b, c) {
          return a + b + c;
      }
      console.log(sum(...numbers)); // 输出: 6
      
  3. 在对象中的使用:

    • 浅拷贝对象:

      const obj1 = { a: 1, b: 2 };
      const obj2 = { ...obj1 }; // 浅拷贝 obj1 到 obj2
      
    • 合并对象:

      const obj1 = { a: 1 };
      const obj2 = { b: 2 };
      const mergedObj = { ...obj1, ...obj2 };
      
  4. 在函数参数中的使用:

    • 用于传递不定数量的参数:
      function sum(...args) {
          return args.reduce((acc, val) => acc + val, 0);
      }
      console.log(sum(1, 2, 3)); // 输出: 6
      

扩展运算符为 JavaScript 的数据处理提供了更灵活和方便的方式,可以简化代码并提高可读性。它在处理数组、对象、函数参数等方面都有很好的应用场景。希望这个解释对你有帮助!如果有任何其他问题,请随时告诉我。

5. Proxy

Proxy 是 ES6 中引入的一个非常强大且灵活的功能,它可以用来拦截并定义对象上的基本操作,从而可以实现各种功能,例如:

  1. 属性访问控制:通过 getset 拦截器,可以控制对对象属性的访问和赋值操作,实现属性的隐藏、验证等功能。

  2. 函数调用控制:通过 apply 拦截器,可以控制对函数的调用操作,可以在函数调用前后执行额外逻辑。

  3. 数组操作的控制:可以通过拦截数组的操作,例如 pushpopsplice 等,实现对数组的监控、验证等功能。

  4. 动态扩展属性:可以通过 get 拦截器动态生成属性,实现虚拟属性或计算属性。

  5. 数据验证:可以在 set 拦截器中对属性值进行验证,确保数据的合法性。

  6. 数据绑定:可以实现数据的双向绑定,当对象数据发生变化时自动更新相关内容。

  7. 缓存:可以利用 Proxy 实现缓存功能,避免重复计算,提高程序性能。

  8. 日志记录:可以在拦截器中记录对象操作的历史,用于调试和监控。

  9. 实现观察者模式:可以在属性访问和赋值时触发相应操作,实现观察者模式。

  10. 实现权限控制:可以根据需要拦截对象的操作,实现权限控制和安全性增强。

总的来说,Proxy 提供了一种对对象进行拦截和自定义操作的机制,可以实现很多复杂的功能和行为定制。
下面我将简要介绍 Proxy 如何实现观察者模式:

  1. 创建观察者模式的实现:

    • 首先,需要创建一个被观察者对象和一个存储观察者的数组。

    • 使用 Proxy 对被观察者对象进行封装,设置一个 observers 数组来存储观察者。

    • 通过 set 拦截器,在被观察者对象的属性发生变化时,通知所有观察者。

  2. 示例代码:

    // 创建一个被观察者对象
    const subject = new Proxy({ value: 0, observers: [] }, {
        set(target, key, value, receiver) {
            const result = Reflect.set(target, key, value, receiver);
            if (key === 'value') {
                target.observers.forEach(observer => observer());
            }
            return result;
        }
    });
    
    // 创建观察者
    const observer1 = () => console.log('Observer 1 updated: ', subject.value);
    const observer2 = () => console.log('Observer 2 updated: ', subject.value);
    
    // 添加观察者
    subject.observers.push(observer1, observer2);
    
    // 修改被观察者的值,触发通知
    subject.value = 1; // Observer 1 updated: 1, Observer 2 updated: 1
    

在上面的示例中,我们创建了一个简单的观察者模式,使用 Proxy 对被观察者对象进行拦截,在属性值发生变化时通知所有观察者。这样,观察者模式就得以实现。

6.提取高度嵌套对象里的指定属性

要提取高度嵌套对象里的指定属性,可以使用递归和对象解构来实现。下面是一个示例,演示如何提取高度嵌套对象中的指定属性:

// 定义一个高度嵌套的对象
const nestedObject = {
    level1: {
        level2: {
            level3: {
                key: 'value'
            }
        }
    }
};

// 递归函数用于提取指定属性
const extractPropertyValue = (obj, property) => {
    for (let key in obj) {
        if (key === property) {
            return obj[key];
        } else if (typeof obj[key] === 'object') {
            return extractPropertyValue(obj[key], property);
        }
    }
};

// 指定要提取的属性名
const propertyToExtract = 'key';

// 提取指定属性值
const extractedValue = extractPropertyValue(nestedObject, propertyToExtract);
console.log(extractedValue); // 输出: 'value'

在上面的示例中,我们定义了一个高度嵌套的对象 nestedObject,然后编写了一个递归函数 extractPropertyValue,该函数接收一个对象和要提取的属性名,在对象中查找指定属性,并返回其值。通过调用这个函数,我们成功提取了高度嵌套对象中的指定属性值。

这种方法可以应用于任意层级的嵌套对象,通过递归地遍历对象的属性,找到目标属性并返回其值。

7.对对象与数组的解构的理解

对象和数组的解构是 JavaScript 中一种强大且方便的语法,用于快速提取数组或对象中的值并赋给变量,以便后续使用。下面我将简要介绍对象解构和数组解构的基本概念:

对象解构:
  • 基本语法: 使用花括号 {} 来指定要提取的对象属性,并将属性值赋给相应的变量。

    const person = { name: 'Alice', age: 30 };
    const { name, age } = person;
    console.log(name); // 输出: 'Alice'
    console.log(age); // 输出: 30
    
  • 给变量起别名: 可以使用冒号 : 为提取的属性值指定变量名。

    const { name: personName, age: personAge } = person;
    console.log(personName); // 输出: 'Alice'
    console.log(personAge); // 输出: 30
    
数组解构:
  • 基本语法: 使用方括号 [] 来指定要提取的数组元素,并将值赋给相应的变量。

    const numbers = [1, 2, 3];
    const [first, second, third] = numbers;
    console.log(first); // 输出: 1
    console.log(second); // 输出: 2
    
  • 忽略某些元素: 可以使用逗号 , 来跳过不需要的数组元素。

    const [,, third] = numbers;
    console.log(third); // 输出: 3
    

对象和数组解构可以简化代码,提高可读性,并且方便地从复杂的数据结构中提取所需的值。当结合递归和其他技术时,对象和数组解构可以变得非常强大。

8.Rest参数

Rest 参数是 ES6 中引入的一个新特性,用于捕获函数参数中的剩余参数,将其表示为一个数组。这样可以处理不定数量的参数,而不需要显式地定义参数个数。下面是关于 rest 参数的一些基本概念和示例:

Rest 参数的基本语法
  • 在函数定义时,使用三个点号 ... 加上一个参数名来表示 rest 参数,通常放在参数列表的最后。
function sum(...numbers) {
    return numbers.reduce((acc, curr) => acc + curr, 0);
}

console.log(sum(1, 2, 3, 4, 5)); // 输出: 15

在这个示例中,...numbers 表示将所有传入函数的参数作为一个数组 numbers 来存储。

Rest 参数的应用场景:
  • 处理不定数量的参数: Rest 参数允许函数接受任意数量的参数,无需提前定义参数个数。
function multiply(multiplier, ...numbers) {
    return numbers.map(num => num * multiplier);
}

console.log(multiply(2, 1, 2, 3, 4)); // 输出: [2, 4, 6, 8]
  • 替代 arguments 对象: Rest 参数可以替代传统的 arguments 对象,更直观地操作参数。
function logArguments(...args) {
    console.log(args);
}

logArguments('a', 'b', 'c'); // 输出: ['a', 'b', 'c']

Rest 参数通常用于函数定义中,方便处理不定数量的参数,提高代码的灵活性和可读性。

9.对 rest 参数的理解ES6中模板语法与字符串处理

ES6 中的模板字符串是一种更灵活、更强大的字符串处理方式,可以在字符串中插入变量、表达式,并支持多行字符串的定义。下面我将介绍 ES6 中模板字符串的基本语法和常见用法:

模板字符串的基本语法:

  • 使用反引号 ``(通常位于键盘左上角,与波浪符号~同一个键)来定义模板字符串。
const name = 'Alice';
const greeting = `Hello, ${name}!`;
console.log(greeting); // 输出: 'Hello, Alice!'
  • 在模板字符串中,使用 ${} 来插入变量或表达式,可以是任意有效的 JavaScript 表达式。

多行字符串的定义:

  • 模板字符串可以跨越多行,而无需使用 \n 换行符。
const multiLine = `
    This is a
    multi-line
    string.
`;
console.log(multiLine);
// 输出:
//     This is a
//     multi-line
//     string.

标签模板字符串:

  • 可以使用标签函数对模板字符串进行处理,这种技术称为标签模板字符串。
function customTag(strings, ...values) {
    console.log(strings);
    console.log(values);
}

const value1 = 10;
const value2 = 20;
customTag`The values are: ${value1} and ${value2}`;
// 输出:
//     ["The values are: ", " and ", ""]
//     [10, 20]

模板字符串提供了一种更简洁、更直观的方式来处理字符串内容,特别是在需要插入变量或多行文本时非常有用。标签模板字符串则扩展了这一概念,允许自定义对模板字符串的处理方式。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1541761.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

一文带你看懂甘特图,项目进度、资源分配清清楚楚

带大家看懂一个甘特图,我们打开一个zz-plan 的甘特图,左边是任务栏,右边是进度条,上面这个是时间,下面是一个整个项目的一个状态,任务、工时、周期和进度。 这一列颜色灰色的表示是当天,我们从…

Linux常用命令和基础命令合集---非常推荐

非常好用的Linux通用基础常用命令和高级命令。 下载链接:https://download.csdn.net/download/lishihuijava/89026399

2024腾讯云服务器2核4G、4核8G、8核16G配置最新收费标准

腾讯云服务器多少钱一年?61元一年起。2024年最新腾讯云服务器优惠价格表,腾讯云轻量2核2G3M服务器61元一年、2核2G4M服务器99元一年可买三年、2核4G5M服务器165元一年、3年756元、轻量4核8M12M服务器646元15个月、4核16G10M配置32元1个月、312元一年、8核…

城市内涝水文水动力模型软件

原文链接:城市内涝水文水动力模型软件https://mp.weixin.qq.com/s?__bizMzUzNTczMDMxMg&mid2247598401&idx3&sn0c4c86b3a5d09a75b8f07e6fad81aa9c&chksmfa8200a6cdf589b0970a6854869e8e3a9f132fe40a19977863c091cbcf6d9786f067e0c5651e&token1…

Autosar MCAL配置——ADC

文章目录 前言一、创建Adc硬件单元二、创建、配置Adc通道1.根据电路原理图,有多少ADC采样引脚,就创建多少ADC采样通道。2.配置Adc通道3.配置ADC组4.配置ADC扫描组三、配置ADC通用设置前言 ADC,即Analogue Digital Converter缩写。简单来说,它是将输入的模拟信号转换为数字…

[数据结构]二叉树的建立与遍历(递归)

一、二叉树的遍历与建立 首先我们拥有如下二叉树: 要了解二叉树遍历,我们得先了解二叉树的三种遍历方式:前序遍历,中序遍历,后序遍历 1.前序遍历 前序遍历:根,左子树,右子树 遍历的结果就是:1 2 4 8 N N 9 N N 5 10 N N 11 N N 3 6 N N 7 N N 2.中序遍历 中序遍历:左子树…

SpringCloud-记

目录 什么是SpringCloud 什么是微服务 SpringCloud的优缺点 SpringBoot和SpringCloud的区别 RPC 的实现原理 RPC是什么 eureka的自我保护机制 Ribbon feigin优点 Ribbon和Feign的区别 什么是SpringCloud Spring Cloud是一系列框架的有序集合。它利用Spring Boot的开发…

day29|leetcode|C++|491. 非递减子序列|46. 全排列|47. 全排列 II

Leetcode 491. 非递减子序列 链接:491. 非递减子序列 thought: 设 stack 中最后一个值的位置为 last。如果 stack 为空,则 last -1。 设当前正在处理的位置为 pos。如果在 nums 的子区间 [last1, pos) 中,存在和 nums[pos] 相同的值&…

智慧公厕:跨界融合,打造智慧城市新名片

随着城市化进程的不断加快,公共厕所建设成为一个亟待解决的问题。传统的公厕存在着管理繁琐、卫生差、服务不到位等一系列问题,与城市发展的节奏不协调。为此,推进新型智慧公厕建设成为了一个重要的解决方案。智慧公厕的建设需要推进技术融合…

BM56 有重复项数字的全排列(回溯)

import java.util.*;public class Solution {/*** 代码中的类名、方法名、参数名已经指定&#xff0c;请勿修改&#xff0c;直接返回方法规定的值即可** * param num int整型一维数组 * return int整型ArrayList<ArrayList<>>*/public void recursion(ArrayList<…

20231911 2022-2023-2 《网络攻防实践》实验三

1.实验内容 1、实践tcpdump 使用tcpdump开源软件对在本机上访问www.tianya.cn网站过程进行嗅探&#xff0c;回答问题&#xff1a;你在访问www.tianya.cn网站首页时&#xff0c;浏览器将访问多少个Web服务器&#xff1f;他们的IP地址都是什么&#xff1f; 2、实践Wireshark 使…

复旦EMBA参访娃哈哈:交流企业创新转型、家族企业管理之道

早在多年前&#xff0c;复旦EMBA同学曾参访娃哈哈集团&#xff0c;与宗庆后先生对话&#xff0c;就国内企业创新转型、家族企业管理之道、“企二代”的成长、企业社会责任等热点问题向其探讨交流。通过面对面的实地企业参访和行业领袖的深入交流&#xff0c;亲身触摸中国科创的…

详解:JS异步解决方案之回调函数,及其弊端

「异步编程」是前端工程师日常开发中经常会用到的技术&#xff0c;异步的实现有好几种方式&#xff0c;各有利弊&#xff0c;本篇先讲通过回调来实现来异步 。 一、同步和异步 同步编程和异步编程是两种不同的编程方式。 同步编程是指按照代码的顺序执行&#xff0c;每一行代…

网络基础知识-DNS与DHCP+网络规划与设计故障诊断+嵌入式系统设计师备考笔记

0、前言 本专栏为个人备考软考嵌入式系统设计师的复习笔记&#xff0c;未经本人许可&#xff0c;请勿转载&#xff0c;如发现本笔记内容的错误还望各位不吝赐教&#xff08;笔记内容可能有误怕产生错误引导&#xff09;。 本章的主要内容见下图&#xff1a; 本章知识和计算机…

springboot3+jdk17+MP整合最新版jersey详细案例,正真做到拿来即用

如题&#xff0c;springboot3.x java17 MP 整合最新jersey&#xff0c;各种请求类型&#xff08;实战/详解&#xff09; 文件上传下载 jersey资源注册 拦截器&#xff08;JWT&#xff09; 跨域处理 全局异常 Valid注解校验 等等 &#xff0c;除非你必须整合security&am…

uniapp页面嵌套其他页面的实现

功能: 类似于一个drawer&#xff0c;当主页面加载的时候会一并加载url对应的组件&#xff0c;当点击后以drawer形式显示组件里面的内容&#xff0c;可动画。 <navigator url"/pages/my/components/personalMessage" slot"right"><view><di…

git push出错: src refspec dev/xxx does not match any

使用如下命令gitp push出错: git push origin 远端分支名 git push origin dev/xxxx error: src refspec dev/xxxx does not match any error: failed to push some refs to https://git.woa.com/..... 解决方案 1: git push origin 本地分支名:远端分支名 解决方案2&#…

零代码编程:用kimichat批量重命名txt文本文件

一个文件夹中有很多个txt文本文件&#xff0c;需要全部进行重命名。 可以在kimichat中输入提示词&#xff1a; 你是一个Python编程专家&#xff0c;要完成一个关于批量重命名txt文本文件的Python脚本&#xff0c;下面是具体步骤&#xff1a; D:\Best Seller Books 这个文件夹…

Aztec的客户端证明

1. 引言 隐私保护 zk-rollup 的证明生成与通用 zk-rollup 的证明生成有很大不同。原因是给定交易中存在特定数据&#xff08;由私有函数处理&#xff09;&#xff0c;我们希望保持完全私有。在本文中&#xff0c;我们探讨了用于证明私有函数正确执行的客户端证明生成&#xff…

模拟实现字符串库函数(一)

在C语言的标准库中提供了很多针对字符串的库函数&#xff0c;这篇文章我们会学习并模拟实现几个简单的库函数 求字符串长度函数strlen strlen函数我们在之前已经用过很多次了&#xff0c;同时也模拟实现过&#xff0c;但是都不是模仿标准库中的strlen来实现&#xff0c;首先我…