前端 -- ES6语法
文章平均质量分 90
wincheshe
秋天,黄叶坠地,凉风有信。
展开
-
如何在顶层使用await 【top level await】
仅当 “module” 选项设置为 “es2022”、“esnext”、“system”、“node16” 或 “nodenext”,且 “target” 选项设置为 “es2017” 或更高版本时,才允许使用顶级 “await” 表达式。添加type为module。如何在顶层使用await 【top level await】原创 2022-11-08 00:22:56 · 2655 阅读 · 2 评论 -
JS引擎执行顺序 --- 事件循环(Event Loop)彻底搞懂 Event Loop 与 宏任务,微任务之间的关系
文章目录事件循环:微任务和宏任务事件循环用例 1:拆分 CPU 过载任务用例 2:进度指示用例 3:在事件之后做一些事情宏任务和微任务总结事件循环:微任务和宏任务浏览器中 JavaScript 的执行流程和 Node.js 中的流程都是基于 事件循环 的。理解事件循环的工作方式对于代码优化很重要,有时对于正确的架构也很重要。在本章中,我们首先介绍事件循环工作方式的理论细节,然后介绍该知识的实际应用。事件循环事件循环 的概念非常简单。它是一个在 JavaScript 引擎等待任务,执行任务和进入休原创 2022-03-13 17:03:55 · 376 阅读 · 0 评论 -
Vue3.x 数据响应式基础,Proxy代理模式 和 Reflect(映射),数据代理,捕获,拦截(三)
Proxy 和 Reflect一个 Proxy 对象包装另一个对象并拦截诸如读取/写入属性和其他操作,可以选择自行处理它们,或者透明地允许该对象处理它们。Proxy 被用于了许多库和某些浏览器框架。在本文中,我们将看到许多实际应用。Proxy语法:let proxy = new Proxy(target, handler)target —— 是要包装的对象,可以是任何东西,包括函数。handler —— 代理配置:带有“捕捉器”(“traps”,即拦截操作的方法)的对象。比如 get 捕捉原创 2022-03-07 20:58:31 · 901 阅读 · 0 评论 -
Proxy 和 Reflect深入,Reflect(映射),Proxy的局限性,Reflect搭配Proxy使用(二)
ReflectReflect 是一个内建对象,可简化 Proxy 的创建。前面所讲过的内部方法,例如 [[Get]] 和 [[Set]] 等,都只是规范性的,不能直接调用。Reflect 对象使调用这些内部方法成为了可能。它的方法是内部方法的最小包装。以下是执行相同操作和 Reflect 调用的示例:操作Reflect 调用内部方法obj[prop]Reflect.get(obj, prop)[[Get]]obj[prop] = valueReflect.set(原创 2022-03-07 19:53:24 · 626 阅读 · 0 评论 -
Proxy 和 Reflect深入学习,数据代理,数据拦截,数据捕获,数据响应式原理(一)
Proxy 和 Reflect一个 Proxy 对象包装另一个对象并拦截诸如读取/写入属性和其他操作,可以选择自行处理它们,或者透明地允许该对象处理它们。Proxy 被用于了许多库和某些浏览器框架。在本文中,我们将看到许多实际应用。Proxy语法:let proxy = new Proxy(target, handler)target —— 是要包装的对象,可以是任何东西,包括函数。handler —— 代理配置:带有“捕捉器”(“traps”,即拦截操作的方法)的对象。比如 get 捕捉原创 2022-03-07 17:26:09 · 358 阅读 · 0 评论 -
JavaScript(JS)模块化开发,什么是动态导入?使用import()表达式,异步动态导入模块使用(三)
动态导入我们在前面章节中介绍的导出和导入语句称为“静态”导入。语法非常简单且严格。首先,我们不能动态生成 import 的任何参数。模块路径必须是原始类型字符串,不能是函数调用,下面这样的 import 行不通:import ... from getModuleName(); // Error, only from "string" is allowed其次,我们无法根据条件或者在运行时导入:if(...) { import ...; // Error, not allowed!}{原创 2022-03-06 16:10:56 · 5362 阅读 · 2 评论 -
JavaScript(JS)模块化开发学习,导出导入的多种方式,默认导出,重新导出,(二)
导出和导入导出(export)和导入(import)指令有几种语法变体。在上一节,我们看到了一个简单的用法,现在让我们来探索更多示例吧。在声明前导出我们可以通过在声明之前放置 export 来标记任意声明为导出,无论声明的是变量,函数还是类都可以。例如,这里的所有导出均有效:// 导出数组export let months = ['Jan', 'Feb', 'Mar','Apr', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'];// 导出 const 声明的变量e原创 2022-03-06 15:58:11 · 4127 阅读 · 3 评论 -
JavaScript(JS)模块(Module)化开发,什么是模块?模块核心功能,浏览器特定模块功能(一)
模块 (Module) 简介随着我们的应用越来越大,我们想要将其拆分成多个文件,即所谓的“模块(module)”。一个模块可以包含用于特定目的的类或函数库。很长一段时间,JavaScript 都没有语言级(language-level)的模块语法。这不是一个问题,因为最初的脚本又小又简单,所以没必要将其模块化。但是最终脚本变得越来越复杂,因此社区发明了许多种方法来将代码组织到模块中,使用特殊的库按需加载模块。列举一些(出于历史原因):AMD —— 最古老的模块系统之一,最初由 require.j原创 2022-03-06 12:32:38 · 1003 阅读 · 0 评论 -
ES6面试高频 --- 什么是生成器(Generator)?什么是异步可迭代对象,使用生成器手写一个异步可迭代对象(二)
异步迭代和 generator异步迭代允许我们对按需通过异步请求而得到的数据进行迭代。例如,我们通过网络分段(chunk-by-chunk)下载数据时。异步生成器(generator)使这一步骤更加方便。首先,让我们来看一个简单的示例以掌握语法,然后再看一个实际用例。回顾可迭代对象让我们回顾一下可迭代对象的相关内容。假设我们有一个对象,例如下面的 range:let range = { from: 1, to: 5};我们想对它使用 for..of 循环,例如 for(value原创 2022-03-05 17:58:46 · 2958 阅读 · 0 评论 -
ES6面试高频 --- 什么是生成器(Generator)?生成器为什么可以迭代,生成器如何搭配“yield“关键字使用(一)
Generator常规函数只会返回一个单一值(或者不返回任何值)。而 Generator 可以按需一个接一个地返回(“yield”)多个值。它们可与 iterable 完美配合使用,从而可以轻松地创建数据流。Generator 函数要创建一个 generator,我们需要一个特殊的语法结构:function*,即所谓的 “generator function”。它看起来像这样:function* generateSequence() { yield 1; yield 2; retur原创 2022-03-05 16:49:47 · 512 阅读 · 0 评论 -
ES6 --- Promise深入学习(八) 重点掌握面试高频,Async/await ,以及错误处理
Async/awaitAsync/await 是以更舒适的方式使用 promise 的一种特殊语法,同时它也非常易于理解和使用。Async function让我们以 async 这个关键字开始。它可以被放置在一个函数前面,如下所示:async function f() { return 1;}在函数前面的 “async” 这个单词表达了一个简单的事情:即这个函数总是返回一个 promise。其他值将自动被包装在一个 resolved 的 promise 中。例如,下面这个函数返回一个结果原创 2022-03-04 15:24:33 · 719 阅读 · 0 评论 -
ES6 --- Promise深入学习(七)Promise 微任务(Microtask)
微任务(Microtask)Promise 的处理程序(handlers).then、.catch 和 .finally 都是异步的。即便一个 promise 立即被 resolve,.then、.catch 和 .finally 下面 的代码也会在这些处理程序(handler)之前被执行。示例代码如下:let promise = Promise.resolve();promise.then(() => alert("promise done!"));alert("code finis原创 2022-03-04 15:09:07 · 1021 阅读 · 0 评论 -
ES6 --- Promise深入学习(六)Promisification化函数
Promisification对于一个简单的转换来说 “Promisification” 是一个长单词。它指将一个接受回调的函数转换为一个返回 promise 的函数。由于许多函数和库都是基于回调的,因此,在实际开发中经常会需要进行这种转换。因为使用 promise 更加方便,所以将基于回调的函数和库 promisify 是有意义的。(译注:promisify 即指 promise 化)为了更好地理解,让我们来看一个例子。例如,在 回调地狱 一章中我们有 loadScript(src, callba原创 2022-03-03 19:14:51 · 401 阅读 · 0 评论 -
ES6 --- Promise深入学习(五)Promise 内置的6个API,all,allSettled,race,any,resolve/reject
Promise API在 Promise 类中,有 6 种静态方法。我们在这里简单介绍下它们的使用场景。Promise.all假设我们希望并行执行多个 promise,并等待所有 promise 都准备就绪。例如,并行下载几个 URL,并等到所有内容都下载完毕后再对它们进行处理。这就是 Promise.all 的用途。语法:let promise = Promise.all([...promises...]);Promise.all 接受一个 promise 数组作为参数(从技术上讲,它可原创 2022-03-03 19:12:50 · 1170 阅读 · 0 评论 -
ES6 --- Promise深入学习(四)使用 promise 进行错误处理,手动停止Promise,捕获全局rejection
使用 promise 进行错误处理Promise 链在错误(error)处理中十分强大。当一个 promise 被 reject 时,控制权将移交至最近的 rejection 处理程序(handler)。这在实际开发中非常方便。例如,下面代码中所 fetch 的 URL 是错的(没有这个网站),.catch 对这个 error 进行了处理:fetch('https://no-such-server.blabla') // rejects .then(response => response.原创 2022-03-02 22:34:06 · 1779 阅读 · 0 评论 -
ES6 --- Promise深入学习(三)Promise链式调用,结合案例分析
Promise 链我们回顾一下 回调地狱 一章中提到的问题:我们有一系列的异步任务要一个接一个地执行 — 例如,加载脚本。我们如何写出更好的代码呢?Promise 提供了一些方案来做到这一点。在本章中,我们将一起学习 promise 链。它看起来就像这样:new Promise(function(resolve, reject) { setTimeout(() => resolve(1), 1000); // (*)}).then(function(result) { // (**原创 2022-03-02 22:31:42 · 1493 阅读 · 0 评论 -
ES6 --- Promise深入学习(二)Promise,then,catch,finally,及使用示例
Promise想象一下,你是一位顶尖歌手,粉丝没日没夜地询问你下首歌什么时候发。为了从中解放,你承诺(promise)会在单曲发布的第一时间发给他们。你给了粉丝们一个列表。他们可以在上面填写他们的电子邮件地址,以便当歌曲发布后,让所有订阅了的人能够立即收到。即便遇到不测,例如录音室发生了火灾,以致你无法发布新歌,他们也能及时收到相关通知。每个人都很开心:你不会被任何人催促,粉丝们也不用担心错过歌曲发行。这是我们在编程中经常遇到的事儿与真实生活的类比:“生产者代码(producing code)”原创 2022-03-02 04:18:09 · 2434 阅读 · 0 评论 -
ES6 --- Promise深入学习(一)回调地狱,厄运金字塔带来的问题
简介:回调JavaScript 主机(host)环境提供了许多函数,这些函数允许我们计划 异步 行为(action)。换句话说,我们现在开始执行的行为,但它们会在稍后完成。例如,setTimeout 函数就是一个这样的函数。这儿有一些实际中的异步行为的示例,例如加载脚本和模块(我们将在后面的章节中介绍)。让我们看一下函数 loadScript(src),该函数使用给定的 src 加载脚本:function loadScript(src) { // 创建一个 <script> 标签,原创 2022-03-02 00:14:14 · 778 阅读 · 1 评论 -
JavaScript(JS)错误处理(一) “try...catch”,“try...catch...finally”,“throw”抛出自定义Error,全局错误处理
错误处理,“try…catch”不管你多么精通编程,有时我们的脚本总还是会出现错误。可能是因为我们的编写出错,或是与预期不同的用户输入,或是错误的服务端响应以及其他数千种原因。通常,如果发生错误,脚本就会“死亡”(立即停止),并在控制台将错误打印出来。但是有一种语法结构 try...catch,它使我们可以“捕获(catch)”错误,因此脚本可以执行更合理的操作,而不是死掉。“try…catch” 语法try...catch 结构由两部分组成:try 和 catch:try { // 代码原创 2022-03-01 10:09:54 · 2739 阅读 · 0 评论 -
JavaScript 错误处理(二)自定义Error,拓展Error,包装异常技术
自定义 Error,扩展 Error当我们在开发某些东西时,经常会需要我们自己的 error 类来反映在我们的任务中可能出错的特定任务。对于网络操作中的 error,我们需要 HttpError,对于数据库操作中的 error,我们需要 DbError,对于搜索操作中的 error,我们需要 NotFoundError,等等。我们自定义的 error 应该支持基本的 error 的属性,例如 message,name,并且最好还有 stack。但是它们也可能会有其他属于它们自己的属性,例如,HttpEr原创 2022-03-01 10:06:30 · 1873 阅读 · 0 评论 -
ES6 类的学习(七) --- Mixin编程模式,以及自定义一个Mixin示例,实现类继承即拥有--事件生成,事件监听,事件取消功能
Mixin 模式在 JavaScript 中,我们只能继承单个对象。每个对象只能有一个 [[Prototype]]。并且每个类只可以扩展另外一个类。但是有些时候这种设定(译注:单继承)会让人感到受限制。例如,我有一个 StreetSweeper 类和一个 Bicycle 类,现在想要一个它们的 mixin:StreetSweepingBicycle 类。或者,我们有一个 User 类和一个 EventEmitter 类来实现事件生成(event generation),并且我们想将 EventEmit原创 2022-02-28 16:06:02 · 426 阅读 · 0 评论 -
ES6 类的学习(六) --- 类检查方法,instanceof,{}.toString.call ,typeof,三种方法的区别
类检查:“instanceof”instanceof 操作符用于检查一个对象是否属于某个特定的 class。同时,它还考虑了继承。在许多情况下,可能都需要进行此类检查。例如,它可以被用来构建一个 多态性(polymorphic) 的函数,该函数根据参数的类型对参数进行不同的处理。instanceof 操作符语法:obj instanceof Class如果 obj 隶属于 Class 类(或 Class 类的衍生类),则返回 true。例如:class Rabbit {}let rabb原创 2022-02-28 15:56:10 · 792 阅读 · 0 评论 -
ES6 类的学习(五) --- class拓展内建类
扩展内建类内建的类,例如 Array,Map 等也都是可以扩展的(extendable)。例如,这里有一个继承自原生 Array 的类 PowerArray:// 给 PowerArray 新增了一个方法(可以增加更多)class PowerArray extends Array { isEmpty() { return this.length === 0; }}let arr = new PowerArray(1, 2, 5, 10, 50);alert(arr.isEmp原创 2022-02-28 15:46:40 · 167 阅读 · 0 评论 -
ES6 类的学习(四) --- class受保护的属性和方法(_propsName),私有的属性和方法(#propsName)
私有的和受保护的属性和方法面向对象编程最重要的原则之一 —— 将内部接口与外部接口分隔开来。内部接口和外部接口在面向对象的编程中,属性和方法分为两组:内部接口 —— 可以通过该类的其他方法访问,但不能从外部访问的方法和属性。外部接口 —— 也可以从类的外部访问的方法和属性。在 JavaScript 中,有两种类型的对象字段(属性和方法):公共的:可从任何地方访问。它们构成了外部接口。到目前为止,我们只使用了公共的属性和方法。私有的:只能从类的内部访问。这些用于内部接口。在许多其他编原创 2022-02-28 15:41:32 · 839 阅读 · 0 评论 -
ES6 类的学习(三) --- class静态属性和静态方法
静态属性和静态方法我们可以把一个方法赋值给类的函数本身,而不是赋给它的 "prototype"。这样的方法被称为 静态的(static)。在一个类中,它们以 static 关键字开头,如下所示:class User { static staticMethod() { alert(this === User); }}User.staticMethod(); // true这实际上跟直接将其作为属性赋值的作用相同:class User { }User.staticMetho原创 2022-02-28 15:26:46 · 2229 阅读 · 0 评论 -
ES6 类的学习(二) --- class类继承,重写构造器,方法,super原理分析
类继承类继承是一个类扩展另一个类的一种方式。因此,我们可以在现有功能之上创建新功能。“extends” 关键字假设我们有 class Animal:class Animal { constructor(name) { this.speed = 0; this.name = name; } run(speed) { this.speed = speed; alert(`${this.name} runs with speed ${this.speed}.`原创 2022-02-26 23:20:51 · 981 阅读 · 0 评论 -
ES6 类的学习(一) --- class基础语法
Class 基本语法在面向对象的编程中,class 是用于创建对象的可扩展的程序代码模版,它为对象提供了状态(成员变量)的初始值和行为(成员函数或方法)的实现。在日常开发中,我们经常需要创建许多相同类型的对象,例如用户(users)、商品(goods)或者任何其他东西。new function 可以帮助我们实现这种需求。但在现代 JavaScript 中,还有一个更高级的“类(class)”构造方式,它引入许多非常棒的新功能,这些功能对于面向对象编程很有用。“class” 语法基本语法是:原创 2022-02-26 23:08:04 · 268 阅读 · 0 评论 -
javascript(JS) --- 浅拷贝和深拷贝 --- 带你深入手写一个深拷贝函数
浅拷贝与深拷贝浅拷贝是创建一个新对象,这个对象有着原始对象属性值的一份精确拷贝。如果属性是基本类型,拷贝的就是基本类型的值,如果属性是引用类型,拷贝的就是内存地址 ,所以如果其中一个对象改变了这个地址,就会影响到另一个对象。深拷贝是将一个对象从内存中完整的拷贝一份出来,从堆内存中开辟一个新的区域存放新对象,且修改新对象不会影响原对象。赋值和深/浅拷贝的区别这三者的区别如下,不过比较的前提都是针对引用类型:当我们把一个对象赋值给一个新的变量时,赋的其实是该对象的在栈中的地址,而不是堆中的数据。原创 2022-02-25 19:51:18 · 341 阅读 · 0 评论 -
ES6 --- 深度理解箭头函数
箭头函数,基础知识创建函数还有另外一种非常简单的语法,并且这种方法通常比函数表达式更好。它被称为“箭头函数”,因为它看起来像这样:let func = (arg1, arg2, ..., argN) => expression;这里创建了一个函数 func,它接受参数 arg1..argN,然后使用参数对右侧的 expression 求值并返回其结果。换句话说,它是下面这段代码的更短的版本:let func = function(arg1, arg2, ..., argN) { re原创 2022-02-24 21:26:40 · 885 阅读 · 0 评论 -
JavaScript (JS) --- 最新的八种基本的数据类型(七种原始数据类型,一种引用数据类型)
数据类型JavaScript 中的值都具有特定的类型。例如,字符串或数字。在 JavaScript 中有 8 种基本的数据类型(译注:7 种原始类型和 1 种引用类型)。在这里,我们将对它们进行大体的介绍,在下一章中,我们将详细讨论它们。我们可以将任何类型的值存入变量。例如,一个变量可以在前一刻是个字符串,下一刻就存储一个数字:// 没有错误let message = "hello";message = 123456;允许这种操作的编程语言,例如 JavaScript,被称为“动态类型”(d原创 2022-02-24 17:37:55 · 2034 阅读 · 0 评论 -
ES6 --- Spread 语法(...拓展运算符)
Spread 语法(…拓展运算符)例如,内建函数 Math.max 会返回参数中最大的值:alert( Math.max(3, 5, 1) ); // 5假如我们有一个数组 [3, 5, 1],我们该如何用它调用 Math.max 呢?直接把数组“原样”传入是不会奏效的,因为 Math.max 希望你传入一个列表形式的数值型参数,而不是一个数组:let arr = [3, 5, 1];alert( Math.max(arr) ); // NaN毫无疑问,我们不可能手动地去一一设置参数 M原创 2022-02-24 14:11:47 · 516 阅读 · 2 评论 -
ES6 --- 解构赋值(数组,对象,函数)使用详解
解构赋值JavaScript 中最常用的两种数据结构是 Object 和 Array。对象让我们能够创建通过键来存储数据项的单个实体。数组则让我们能够将数据收集到一个有序的集合中。但是,当我们把它们传递给函数时,函数可能不需要整个对象/数组。它可能只需要对象/数组的一部分。解构赋值 是一种特殊的语法,它使我们可以将数组或对象“拆包”至一系列变量中,因为有时这样更方便。解构操作对那些具有很多参数和默认值等的函数也很奏效。我们马上会看到类似的例子。数组解构下面是一个将数组解构到变量中的例子:原创 2022-02-23 18:17:39 · 27366 阅读 · 6 评论 -
ES6 --- WeakMap、WeakSet(弱映射和弱集合)
13日 二月 2022WeakMap and WeakSet(弱映射和弱集合)我们从前面的 垃圾回收 文章中知道,JavaScript 引擎在值“可达”和可能被使用时会将其保持在内存中。例如:let john = { name: "John" };// 该对象能被访问,john 是它的引用// 覆盖引用john = null;// 该对象将会被从内存中清除通常,当对象、数组之类的数据结构在内存中时,它们的子元素,如对象的属性、数组的元素都被认为是可达的。例如,如果把一个对象放入到原创 2022-02-23 16:31:21 · 1352 阅读 · 3 评论 -
ES6 --- Map、Set 映射和集合
Map and Set(映射和集合)学到现在,我们已经了解了以下复杂的数据结构:对象,存储带有键的数据的集合。数组,存储有序集合。但这还不足以应对现实情况。这就是为什么存在 Map 和 Set。MapMap 是一个带键的数据项的集合,就像一个 Object 一样。 但是它们最大的差别是 Map 允许任何类型的键(key)。它的方法和属性如下:new Map() —— 创建 map。map.set(key, value) —— 根据键存储值。map.get(key) —— 根据键来返原创 2022-02-23 16:08:14 · 263 阅读 · 0 评论 -
ES6 --- Iterable object(可迭代对象)
Iterable object(可迭代对象)可迭代(Iterable) 对象是数组的泛化。这个概念是说任何对象都可以被定制为可在 for..of 循环中使用的对象。数组是可迭代的。但不仅仅是数组。很多其他内建对象也都是可迭代的。例如字符串也是可迭代的。如果从技术上讲,对象不是数组,而是表示某物的集合(列表,集合),for..of 是一个能够遍历它的很好的语法,因此,让我们来看看如何使其发挥作用。Symbol.iterator通过自己创建一个对象,我们就可以轻松地掌握可迭代的概念。原创 2022-02-22 23:32:37 · 524 阅读 · 0 评论 -
ES6 --- Symbol 类型
es6中引入了第六种原始数据类型,字符串,数值,布尔值,null,undefined,symbol原创 2022-02-22 17:25:53 · 202 阅读 · 0 评论