前端宝典二十二:ES6必须掌握的功能和源码实现

本文主要是介绍前端宝典二十二:ES6必须掌握的功能和源码实现,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

在前端宝典二十一中,我们已经一起探讨了Promise\ async\ await,并手写了Promise相关的方法all、race、allSettled、any等。
这一讲我们一起来看ES6其他重点的内容

一、let、const

let和const的出现,首先是基于var存在的问题,来解决问题的
var存在的问题:

  • 变量提升
  • 无法形成词法作用域
  • 可以随意篡改变量值、重复声明

1、let与const

  • let是声明块级作用域的局部变量,只在代码块内有效
  • const声明的是只读常量,常量必须在声明时初始化
    这样声明的好处是安全、简洁、规范

2、解决的问题

1. 循环中使用let声明变量避免问题

for (let i = 0; i < 5; i++) {setTimeout(() => {console.log(i); }) 
}

上面的代码如果用var声明循环的变量,就会打印出5个5

2. const常量防止被篡改

const PI =3.1415926;
const URL='https://editor.csdn.net/md?articleId=141468095';

3. const声明对象属性避免被修改

const uer = {name: 'frank',age: 18,gender: 'Male'
}
user.like='sports';  // { name: 'frank', age: 18, gender: 'Male', like: 'sports' }
Object.freeze(user);
user.like='music'
console.log(user); // 报错

3、底层原理

let 的底层实现过程

  1. 编译阶段
    在代码编译阶段,编译器会扫描整个函数体(或全局作用域),查找所有使用 let 定义的变量,为这些变量生成一个初始值为 undefined 的词法环境(LexicalEnvironment)并将其保存在作用域链中。

  2. 进入执行上下文
    当进入执行块级作用域(包括 for、if、while 和 switch 等语句块)后,会创建一个新的词法环境。如果执行块级作用域中包含 let 变量声明语句,这些变量将被添加到这个词法环境的环境记录中。

  3. 绑定变量值
    运行到 let 定义的变量时,JavaScript 引擎会在当前词法环境中搜索该变量。首先在当前环境记录中找到这个变量,如果不存在变量,则向包含当前环境的外部环境记录搜索变量,直到全局作用域为止。如果变量值没有被绑定,JavaScript 引擎会将其绑定为 undefined,否则继续执行其他操作。

  4. 实现块级作用域
    使用 let 定义变量时,在运行时不会在当前作用域之外创建单独的执行上下文,而是会创建子遮蔽(shadowing)新环境。在子遮蔽的词法环境中,变量的值只在最接近的块级作用域内有效。

const 的底层实现过程

const 具有与 let 相同的底层实现原理,区别在于 const 定义的变量被视为常量(在赋值之后无法更改),因此变量声明时 必须初始化。此外,应该注意的是,使用 const 声明的对象是可以修改属性的。在定义 const 对象时,对象本身是常量,而不是对象的属性。只有对象本身不能被修改,而对象包含的属性可以任意修改。

let和const有暂时性死区
有点类似webcomponent的shadowDom

二、Proxy

在 ES6 中,Proxy是一种用于创建对象代理的机制,可以拦截并自定义对目标对象的各种操作,如属性访问、赋值、函数调用等。它提供了一种强大的方式来实现面向切面编程(AOP)和元编程。

Proxy对象由两部分组成:目标对象(target)和处理程序对象(handler)。处理程序对象定义了各种捕获器(trap)方法,这些方法会在对目标对象进行特定操作时被调用。

1、代码实例

以下是一些使用 Proxy 的示例:

  1. 拦截属性访问:
const target = {name: 'John',age: 30
};const handler = {get: function(target, prop) {console.log(`Accessing property "${prop}"`);return target[prop];}
};const proxy = new Proxy(target, handler);console.log(proxy.name); // Accessing property "name", then prints "John"
  1. 拦截属性赋值:
const target = {count: 0
};const handler = {set: function(target, prop, value) {console.log(`Setting property "${prop}" to "${value}"`);target[prop] = value;return true;}
};const proxy = new Proxy(target, handler);proxy.count = 10; // Setting property "count" to "10"
console.log(proxy.count); // 10
  1. 拦截函数调用:
const target = {add: function(a, b) {return a + b;}
};const handler = {apply: function(target, thisArg, args) {console.log(`Calling function with arguments ${args}`);return target.apply(thisArg, args);}
};const proxy = new Proxy(target, handler);console.log(proxy.add(3, 4)); // Calling function with arguments [3,4], then prints 7

通过使用 Proxy,可以在不修改原始对象的情况下,对对象的行为进行灵活的控制和扩展。

三、 Reflect

在 ES6 中,Reflect 是一个内置的对象,它提供了一组与对象操作相关的静态方法,这些方法与传统的对象操作方法类似,但更加规范化和统一。Reflect 的目的是为了提供一种更加优雅和一致的方式来执行对象操作,并且可以与 Proxy 对象一起使用,实现对对象操作的拦截和自定义。

1、常见方法及示例

  1. Reflect.get(target, propertyKey[, receiver]):获取对象的属性值。

    const obj = {name: 'John',age: 30
    };
    console.log(Reflect.get(obj, 'name')); // John
    
  2. Reflect.set(target, propertyKey, value[, receiver]):设置对象的属性值。

    const obj = {name: 'John'
    };
    Reflect.set(obj, 'age', 30);
    console.log(obj); // { name: 'John', age: 30 }
    
  3. Reflect.has(target, propertyKey):检查对象是否具有某个属性。

    const obj = {name: 'John',age: 30
    };
    console.log(Reflect.has(obj, 'name')); // true
    
  4. Reflect.apply(target, thisArgument, argumentsList):以指定的 this 值和参数列表调用一个函数。

    function add(a, b) {return a + b;
    }
    console.log(Reflect.apply(add, null, [3, 4])); // 7
    
  5. Reflect.construct(target, argumentsList[, newTarget]):使用指定的构造函数和参数列表创建一个新对象。

    class Person {constructor(name, age) {this.name = name;this.age = age;}
    }
    const person = Reflect.construct(Person, ['John', 30]);
    console.log(person); // Person { name: 'John', age: 30 }
    

Reflect 的方法与传统的对象操作方法类似,但在一些情况下更加灵活和安全,特别是在与 Proxy 对象一起使用时,可以实现对对象操作的拦截和自定义。

四、class语法

JavaScript 的类最终也是一种函数,使用 class 关键字创建的类会被编译成一个函数,因此其底层原理与函数有一些相似之处。

1、js中原型继承实现继承有哪些方法?

构造器借用、寄生式继承、组合继承

2、class语法继承,最接近哪种?

寄生+组合
js引擎将class语法转化为了原型链继承的方式

3、构造函数

使用 class 关键字来定义类时,在内部会创建一个特殊的函数,称为构造函数(constructor)。构造函数用于在创建对象时初始化对象的属性,类似于传统的基于原型的代码中的构造函数。

class Person {constructor(name, age) {this.name = name;this.age = age;}
}const p = new Person("Tom", 20);
console.log(p.name, p.age); // Tom 20

class 中定义的属性和方法分别定义在这个构造函数的 prototype 属性中。并且与原型方式不同的是,类的方法(静态方法)是不可枚举的,因此无法使用 for…in 循环进行遍历。

问题:是否可枚举
判断方法:
是否可枚举,就用for…in循环遍历到属性,不能遍历就不可枚举
如何设置不可枚举:

Object.defineProperty(obj,'name',{value:'frank',enumerable: false // 不可枚举
})
for (const key in obj) {console.log(key); // 没有输出
}

4、继承

class Student extends Person {constructor(name,age,grade){super(name,age);this.grade = grade;}
}

这段代码中,子类 Student 继承了父类 Person 的构造函数方法并添加了自己的属性和方法。

5、静态方法和属性

类中的静态方法和属性可以使用 static 关键字来定义,它们不是类实例的属性,而是类本身的属性和方法。

class Person {static species = "human";static saySpecies() {console.log(`We are ${this.species}.`);}
}

这段代码中定义了一个静态方法和一个静态属性,可以通过类本身直接调用静态方法和属性。

6、也可以使用class表达式创建函数对象

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

五、@修饰器(Decorators)

ES6 修饰器是一种特殊的语法,它可以用来修改类及其成员(方法、属性、访问器等)的行为。修饰器本质上是一个函数,它接收被修饰的目标、名称和描述符作为参数,并返回一个新的描述符或直接修改目标。

修饰器可以用于实现许多功能,如日志记录、性能测量、权限控制等,它可以帮助我们在不修改原有代码的情况下增强类的功能。

1、代码实例

  1. 方法修饰器

    function logMethod(target, name, descriptor) {const originalMethod = descriptor.value;descriptor.value = function (...args) {console.log(`Calling method ${name} with arguments ${args}`);const result = originalMethod.apply(this, args);console.log(`Method ${name} returned ${result}`);return result;};return descriptor;
    }class MyClass {@logMethodmyMethod(arg1, arg2) {return arg1 + arg2;}
    }const instance = new MyClass();
    instance.myMethod(2, 3);
    

    在这个例子中,logMethod修饰器用于在方法调用前后输出日志信息。

  2. 类修饰器

    function logClass(constructor) {console.log(`Creating class ${constructor.name}`);return constructor;
    }@logClass
    class MyClass {constructor() {console.log('Constructing MyClass instance');}
    }const instance = new MyClass();
    

    这里的logClass修饰器在创建类的时候输出日志信息。

2、注意:

修饰器只可用于类和类属性方法,不可用于函数,因为存在函数提升。
修饰器是在编译时执行而不是运行时,所以修饰符是可以在编译时执行的代码,优秀哦

六、箭头函数

在箭头函数中,this关键字的作用域与它周围代码作用域相同,因而有时也被称为“词法作用域函数”。

1、基础概念与使用

箭头函数的原理是基于JavaScript中的闭包、this和参数作用域。在箭头函数中,this关键字始终指向函数所在上下文的this指针,而不是所在作用域的this指针。

2、箭头函数与普通函数的区别

  • this指向,箭头函数不能定义构造器
  • 不能new
  • 内部无arguments对象
  • this绑定方法失效,如apply、call、bind

所以,当我们需要引用所在父级的this指向时,可以用箭头函数。

这篇关于前端宝典二十二:ES6必须掌握的功能和源码实现的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1120727

相关文章

C++中零拷贝的多种实现方式

《C++中零拷贝的多种实现方式》本文主要介绍了C++中零拷贝的实现示例,旨在在减少数据在内存中的不必要复制,从而提高程序性能、降低内存使用并减少CPU消耗,零拷贝技术通过多种方式实现,下面就来了解一下... 目录一、C++中零拷贝技术的核心概念二、std::string_view 简介三、std::stri

C++高效内存池实现减少动态分配开销的解决方案

《C++高效内存池实现减少动态分配开销的解决方案》C++动态内存分配存在系统调用开销、碎片化和锁竞争等性能问题,内存池通过预分配、分块管理和缓存复用解决这些问题,下面就来了解一下... 目录一、C++内存分配的性能挑战二、内存池技术的核心原理三、主流内存池实现:TCMalloc与Jemalloc1. TCM

OpenCV实现实时颜色检测的示例

《OpenCV实现实时颜色检测的示例》本文主要介绍了OpenCV实现实时颜色检测的示例,通过HSV色彩空间转换和色调范围判断实现红黄绿蓝颜色检测,包含视频捕捉、区域标记、颜色分析等功能,具有一定的参考... 目录一、引言二、系统概述三、代码解析1. 导入库2. 颜色识别函数3. 主程序循环四、HSV色彩空间

苹果macOS 26 Tahoe主题功能大升级:可定制图标/高亮文本/文件夹颜色

《苹果macOS26Tahoe主题功能大升级:可定制图标/高亮文本/文件夹颜色》在整体系统设计方面,macOS26采用了全新的玻璃质感视觉风格,应用于Dock栏、应用图标以及桌面小部件等多个界面... 科技媒体 MACRumors 昨日(6 月 13 日)发布博文,报道称在 macOS 26 Tahoe 中

全面解析HTML5中Checkbox标签

《全面解析HTML5中Checkbox标签》Checkbox是HTML5中非常重要的表单元素之一,通过合理使用其属性和样式自定义方法,可以为用户提供丰富多样的交互体验,这篇文章给大家介绍HTML5中C... 在html5中,Checkbox(复选框)是一种常用的表单元素,允许用户在一组选项中选择多个项目。本

HTML5 搜索框Search Box详解

《HTML5搜索框SearchBox详解》HTML5的搜索框是一个强大的工具,能够有效提升用户体验,通过结合自动补全功能和适当的样式,可以创建出既美观又实用的搜索界面,这篇文章给大家介绍HTML5... html5 搜索框(Search Box)详解搜索框是一个用于输入查询内容的控件,通常用于网站或应用程

Python实现精准提取 PDF中的文本,表格与图片

《Python实现精准提取PDF中的文本,表格与图片》在实际的系统开发中,处理PDF文件不仅限于读取整页文本,还有提取文档中的表格数据,图片或特定区域的内容,下面我们来看看如何使用Python实... 目录安装 python 库提取 PDF 文本内容:获取整页文本与指定区域内容获取页面上的所有文本内容获取

基于Python实现一个Windows Tree命令工具

《基于Python实现一个WindowsTree命令工具》今天想要在Windows平台的CMD命令终端窗口中使用像Linux下的tree命令,打印一下目录结构层级树,然而还真有tree命令,但是发现... 目录引言实现代码使用说明可用选项示例用法功能特点添加到环境变量方法一:创建批处理文件并添加到PATH1

Java使用HttpClient实现图片下载与本地保存功能

《Java使用HttpClient实现图片下载与本地保存功能》在当今数字化时代,网络资源的获取与处理已成为软件开发中的常见需求,其中,图片作为网络上最常见的资源之一,其下载与保存功能在许多应用场景中都... 目录引言一、Apache HttpClient简介二、技术栈与环境准备三、实现图片下载与保存功能1.

canal实现mysql数据同步的详细过程

《canal实现mysql数据同步的详细过程》:本文主要介绍canal实现mysql数据同步的详细过程,本文通过实例图文相结合给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的... 目录1、canal下载2、mysql同步用户创建和授权3、canal admin安装和启动4、canal