标签

 javascript 

相关的文章:

掌握JavaScript的多种方法生成二维数组,Python与Javascript进行数据通信,超实用的10条JavaScript这20年来增加的新功能,CefSharp实现C#与JavaScript相互调用的技术详解,JavaScript中的URL编码和解码。

六虎

六虎 -

JavaScript对象属性可枚举性详解

文章的更新路线:JavaScript基础知识-Vue2基础知识-Vue3基础知识-TypeScrip

JavaScript中的目标特点分为可枚举和不可枚举两种。可枚举特点可以通过遍历方法访问,大多数内建目标的原型特点都是可枚举的。不可枚举特点无法通过遍历方法访问,通常使用Object.defineProperty或Object.defineProperties设置。可枚举性在JavaScript中是一个重要概念,影响特点的遍历和序列化行为。根据实际需求选择是否将特点设置为可枚举。

相关推荐 去reddit讨论
蚊子

蚊子 -

JavaScript 中数组 Array 的常见操作

这篇文章总结了JavaScript中数组的常用操作,包括创建数组、初始化二维数组、创建连续数字的范围数组、判断是否是数组类型、查找元素、循环数组、数组操作、拷贝复制数组等。同时还介绍了不改变原数组的方法。

相关推荐 去reddit讨论
颜海镜

颜海镜 -

一文搞懂 JavaScript 模块化

如果你看过某个现代 JavaScript 库的代码,一定会困惑其复杂的模块适配,下图目前主流的 JavaScript 库模块适配方案。 本文梳理 JavaScript 模块化的历史和现状,不仅介绍不同模块系统是什么,而是深入介绍不同模块系统诞生的原因和解决的问题,阅读本文将为你解开很多 JavaScript 模块化的疑惑。 传统 JavaScript JavaScript 诞生之初,是一门在浏览器使用的脚本语言,并没有提供模块系统,站在当时的视角来看,确实也并不需要模块系统。 在浏览器中,如果想引用一个脚本文件,只需要使用 script 标签引入即可,非常简单直观,如下所示即可可入 jQuery。 script 的方式,并没有解决依赖的问题,依赖关系的解决,需要我们手动保证引入的顺序问题,2013 年我曾写过一个较为复杂的绘图程序Painter,手动维护依赖关系,如下图所示,曾经让我非常痛苦。 JavaScript 缺少模块带来两个问题,一个是封装的问题,一个是依赖的管理问题,关于如何支持模块的问题,浏览器社区和 Node.js 社区分别给出了不同的探索和方案,下面介绍其中影响比较大的模块系统。 Node.js 模块方案 Node.js 是浏览器之外的另一个运行时,其创建之初,为了弥补 JavaScript 缺失模块的问题,其带来了commonjs 规范,在 Node.js 中模块是强制的,commonjs 的模块定义和使用示例如下,需要注意外面的 define 在 Node.js 中是自动添加的,不需要写。 define(function (require, exports, module) { //使用event 模块 var ec = require("event"); }); 随着 Node.js 的发展,commonjs 影响力也越来越大,社区中很多库都提供了 commonjs 的引入方式,在当前这个时间点(2024-03-11),社区中依然存在大量仅支持 commonjs 的库。 浏览器模块方案 当浏览器社区考虑引入模块系统时,发现 commonjs 并不适合浏览器,这是因为 commonjs 是为同步导入设计的模块系统,在 Node.js 中引入一个模块是通过文件系统,同步非常合理,也非常简单。但在浏览器环境中,都是基于网络加载 js 文件的,需要设计一套异步加载规范。 其中最突出的异步加载规范是AMD(Asynchronous Module Definition),如果要使用 AMD 模块,还需要加载器,其中 RequireJS 是使用最为广泛的 AMD 模块加载器。 AMD 规范中定义模块的方式如下: define(["beta"], function (beta) { bata.***//调用模块 }); 笔者早年间写的变色方块小游戏,就是使用 RequireJS 作为加载器的,其源代码中只加载一个入口文件。 其依赖的其他模块都通过 RequireJS 异步导入,示例如下: 目前 AMD 已经很少使用,仅作为了解即可,但在当时 AMD 也有很多用户,很多 JS 库都提供了 AMD 的引入方式。 割裂的社区 在 AMD 和 commonjs 双雄并存的年代,不得不面临一个巨大的问题,很多 JS 库,都只提供一种引入方式,这让社区割裂开来,如何在一种模块中使用另一种模块的库,成了模块加载器的急需解决的问题。 AMD 如何给 Node.js 使用 RequireJS 提供了在 Node.js 中使用 AMD 模块的方案,其使用方式如下所示: 为了实现这个功能,给 RequireJS 中添加了冗余代码,其部分源码实现如下所示,即便今天来看,RequireJS 的实现也颇为巧妙。 commonjs 如何给浏览器使用 那么大量的 commonjs 模块如何让浏览器使用呢?最早开始探索的先驱是# Browserify,其通过预编译的方式,将 commonjs 编译为传统 script 的方式,其使用方式如下所示: Browserify 的这种方式被后来的工具借鉴并发扬光大,今天我们常用的工具都是基于这种方式,比如 webpack,rollup,pracel,vite 等。 如何融合 AMD 和 commonjs? 两套模块系统的另一个困扰来自库开发者,我到底该提供哪个模块给大家使用呢?有什么办法可以融合 AMD 和 commonjs 呢? 这个问题最终被 UMD 解决,UMD的全称是 Universal Module Definition。和它名字的意思一样,这种规范基本上可以在任何一个模块环境中工作。 UMD 的设计非常精巧,其支持传统 JavaScript,AMD 和 commonjs,对于传统 JavaScript,它设置支持了类似 jQuery 中的 noConflict 方法,一段典型的 UMD 代码如下所示: (function (root, factory) { var Data = factory(root); if ( typeof define === 'function' && define.amd) { // AMD define('data', function() { return Data; }); } else if ( typeof exports === 'object') { // Node.js module.exports = Data; } else { // Browser globals var _Data = root.Data; Data.noConflict = function () { if (root.Data === Data) { root.Data = _Data; } return Data; }; root.Data = Data; } }(this, function (root) { var Data = ... //自己的代码 return Data; })); 其实故事到此本该就结束了,一些主要问题,已经基本解决了,没想到半路杀出个程咬金——ESM,对 AMD 和 commonjs 实现了降维打击。 ESM 2015 年 ECMAScript6 发布,也被称为 ECMAScript2015,其为 JavaScript 语言带来了原生的模块系统 ECMAScript6 Module,下文我们简称为 ESM。 网上有很多文章介绍 ESM,ESM 的科普不是本文的重点,这里不再展开介绍,commonjs 和 ESM 的引用模块的对比如下: // commonjs let { stat, exists, readfile } = require("fs"); // ESM import { stat, exists, readFile } from "fs"; 打包工具如何支持 ESM ES6 虽然带来了 ESM,但并未提供实际的使用方式,并没有环境支持 ESM,为了使用 ESM 需要借助打包工具,最早支持 ESM 的打包工具应该是 rollup,rollup 给的方案是库提供两个入口,一个是 esm,一个是 commonjs,这样让库同时在 rollup 和其他打包工具中使用。 rollup 建议库中增加module字段,来标记 ESM 的入口文件,rollup 有一篇文档详细介绍这个字段 pkg.module,值得一提的是由于不同工具的原因,实现同样的诉求,存在两个字段,一个是module,一个是jsnext:main。 如果库中存在如下字段,rollup 会加载module字段文件,其他打包工具则加载main。 后来 webpack 也提供了支持,其是通过增加配置来实现的,mainFields中的main前面添加module配置即可,如下所示: 你可能会好奇最前面的browser字段是啥,那就继续往下看吧。 如何解决 Node.js 和浏览器差异的问题 一个库同时支持 Node.js 和浏览器,理想很美好,然后现实却可能遇到挑战,由于环境的不一致问题,同一个库,在不同环境中,可能存在不同的实现方式。 举个例子,我们熟悉的 axios 库,其功能是提供发送请求的友好接口,同时支持在 Node.js 和浏览器中使用,其在浏览器中基于 xhr 实现,但在 Node.js 由于没有 xhr,其基于 http 模块实现。 对于这个问题,可以通过提供两个 npm 包的方式来解决,但这并不优美,库的开发者可能希望只提供一个 npm 包。还有一种解决办法,就是在一个 npm 包中,写分支代码,但这种方式会让浏览器环境中多出来 Node.js 中的代码,虽然可以通过打包工具,避免将 http 模块打包进来,但仍然有冗余代码。 为了解决这个问题,package-browser-field-spec诞生了,其通过在 package.json 中增加 browser 字段的方式,来区分不同的环境,对于浏览器环境来说,打包工具会自动引用 browser 字段的内容。 其使用方式如下所示,即支持整个入口替换,也支持部分文件的替换。 webpack 对于 browser 的支持也通过增加配置的方式,上面我们看到 webpack 配置中的 browser 字段,就是实现这个功能的。 浏览器如何支持 ESM 除了借助打包工具,浏览器也对 ESM 提供了原生支持,其通过给 script 标签增加type="module"属性的方式,来区分传统加载,还是模块化加载。 举个例子,我们有main.js和hello.js两个文件,其中main.js依赖hello.js,内容如下所示: 如果通过传统 script 标签直接加载存在import和export的 js 文件会报错,如下所示: 只需简单添加type="module"即可,示例如下,现在我们使用 vite 在 dev 模式下,就是基于浏览器原生 ESM 加载模块的。 Node.js 如何支持 ESM Node.js 对 ESM 的支持比较坎坷,其中实现方案也修改过,导致其比较复杂,Node.js 从 18 版本开始提供了较为稳定的 ESM 支持。 Node.js 支持 ESM 的挑战是,如何兼容大量的存量 commonjs 模块,Node.js 提供了两种方式,一种是通过后缀名区分,一种是通过给 package.json 增加 type 字段来区分。 在一个 npm 包中,可以同时存在这种量情况,归纳起来,可以分为如下情况,.mjs是 ESM,.cjs是 commonjs,.js要看 package.json 的type字段。 .mjs .js package.json 没有 type package.json type=commonjs package.json type=module .cjs 有一点需要注意,在 Node.js 中 ESM 中可以引用 commonjs,在 commonjs 中不能引用 ESM,如果想了解背后的原因,以及更多细节,可以查看 Node.js 官方的文档:package 包模块 目前 webpack 中也支持.mjs,可以通过如下配置来实现: exports 那么一个库,如何给旧版本 Node.js 提供 commonjs,给新版本 Node.js 提供 ESM 呢,Node.js 提供的答案是引入新的 exports 字段,exports 是重新设计的接口,其支持我们前面提到的全部功能,比如 browser。 下面是 exports 的示例: 对于不支持 exports 的环境,会继续读取 main 字段 支持 exports,但不支持 ESM 的环境,会使用 require 字段 支持 exports,且支持 ESM 的环境,会使用 import 字段 exports 本身的规则也比较复杂,如果想正确使用 exports 建议仔细阅读规范,下面是工具库 axios 的的 exports 配置,其中 types 是给 typescript 使用的,browser 是支持我们前面提到的 browser 功能。 目前 webpack 也支持 exports 导入,可以通过如下配置来实现: 双包问题 对于 Node.js 来说,支持 ESM 并不简单,这里提一个双包的问题,假如我们的 npm 包通过前面的 exports 字段,提供了 ESM 和 commonjs 两种入口,在实际使用中,两种入口可能会被同时使用,导致我们的代码被执行两遍。 举个例子,我们的包是 A,项目中使用 A 的 ESM,项目依赖另一个包 B,B 依赖 A 的 commonjs 时,就会存在双包的问题。 如果我们的包是无副作用的代码,则执行两次问题不大,如果是希望单例的包,这样则会造成严重问题。 解决双包的问题,目前有两个思路: 一种是保守方法,由于 ESM 可以引入 commonjs,在 commonjs 中实现功能代码,在 ESM 中提供一个包装代码,调用我们的 commonjs 即可。 一种是激进办法,只提供 ESM 的包,放弃支持 commonjs 的旧环境。 Deno 仔细观察你会发现,Node.js 加载 ESM 是基于文件路径,而我们的浏览器是基于 URL,这并不统一,世界上也并不只有 Node.js,比如 Deno 就只支持 URL 加载,如下所示: 那么 Deno 如何使用我们的 npm 包呢,答案是通过unpkg和esm这种的平台来实现。 不过这要在我们的 package.json 中添加新的字段,如下所示,unpkg 会自动识别我们的字段,并提供相应的替换和包装功能: 需要注意,在 Node 17 以后,也支持通过 URL 来加载 ESM。 总结 本文介绍了 JavaScript 中主要模块方案和其背后的原因,希望对您有帮助,在日后的工作中看到任何模块,都不再困扰。

本文介绍了JavaScript中的主要模块方案,包括CommonJS、AMD、UMD和ESM,并解释了它们的背景和使用方式。同时还介绍了打包工具如何支持ESM以及如何解决Node.js和浏览器之间的差异问题。最后提到了双包问题和Deno对模块加载的不同方式。

相关推荐 去reddit讨论
程序师

程序师 -

不存在的浏览器安全漏洞:PDF 中的 JavaScript

有一种相当常见的安全漏洞报告形式:"我可以在 PDF 文件中放入 JavaScript,而且它还能运行!"

PDF文件中的JavaScript功能受限,无法访问cookie或存储空间,请求能力也有限。PDF中的JavaScript应尊重应用程序/用户设置。Firefox的全局javascript.enabled开关不影响PDF查看器内的脚本。Chromium忽略PDF响应中的Content-Security-Policy标头。

相关推荐 去reddit讨论
解道jdon.com

解道jdon.com -

Javascript回调异步操作示例教程

有没有想过网站如何在不堵塞所有内容的情况下获取数据?这就是异步操作的魔力!回调是处理这些幕后任务的经典方法。想象一下,您告诉朋友(函数)获取某些东西(数据)。当你的朋友购物(操作运行)时,你(主程序)可以继续做事。一旦他们带回项目(数据),您的朋友就会告诉您(回调函数),您就可以使用它!回调是一个简单的概念,但存在更新的方法来保持代码整洁。尽管如此,理解回调仍然是异步世界中伟大的第一步!传统同步与异步操作想象一下,您有一个名为 的函数makeCoffeeSync可以完美地冲泡一杯咖啡。但是,它是同步的,这意味着程序会等待整个过程完成后再继续。它可能如下所示:function makeCoffe

JavaScript回调异步操作示例教程。回调是处理异步任务的经典方法。传统同步操作会导致程序等待,而异步操作可以在后台进行。回调函数作为参数传递给异步函数,确保在任务完成后采取行动。回调的优点是简单和灵活,但可能导致回调地狱和可读性问题。Promise和Async/Await是处理异步操作的替代方法,提供更清晰、更可读的代码。它们提供更好的错误处理和更简洁的代码。了解回调可以帮助理解这些新技术的优势。

相关推荐 去reddit讨论
FreeBuf网络安全行业门户

FreeBuf网络安全行业门户 -

相关推荐 去reddit讨论
ByteByteGo Newsletter

ByteByteGo Newsletter -

EP106: How Does JavaScript Work?

This week’s system design refresher: Roadmap for Learning SQL (Youtube video) Can Kafka lose messages? 9 Best Practices for building microsercvices Roadmap for Learning Cyber Security How does Javascript Work? SPONSOR US New Relic IAST exceeds OWASP Benchmark with accuracy scoring above 100% (Sponsored)

本文介绍了学习SQL和Kafka消息丢失的路线图,以及构建微服务的最佳实践。对于Kafka消息丢失,需要了解其架构和配置的细节,以及如何预防消息丢失。对于构建微服务,需要设计容错性、构建小型服务、使用轻量级协议进行通信、实现服务发现、数据所有权、弹性模式、安全性、集中日志记录和容器化等。此外,还介绍了学习网络安全和JavaScript的路线图。

相关推荐 去reddit讨论
The Cloudflare Blog

The Cloudflare Blog -

We've added JavaScript-native RPC to Cloudflare Workers

Cloudflare Workers now features a built-in RPC (Remote Procedure Call) system for use in Worker-to-Worker and Worker-to-Durable Object communication, with absolutely minimal boilerplate. We've designed an RPC system so expressive that calling a remote service can feel like using a library

Cloudflare Workers现在具有内置的RPC系统,可以在工作线程和持久化对象之间实现无缝通信。该RPC系统旨在具有表达能力和安全性,具备传递结构化可克隆类型和函数作为参数的功能,以及在RPC上进行方法调用和发送字节流的能力。RPC系统基于对象能力模型,完全开源。它不需要编写模式,并且可以与惯用的JavaScript代码一起使用。RPC实现了工作线程之间更轻松、更快速的通信,使得创建更复杂的应用程序成为可能。

相关推荐 去reddit讨论
dotNET跨平台

dotNET跨平台 -

Eval-Expression.NET:动态执行C#脚本,类似Javascript的Eval函数功能

我们都知道在JavaScript中,我们可以通过Eval来执行JavaScript字符串代码。下面推荐一个.Net版本的Eval的开源项目。01项目简介Eval-Expression.NET是一个非常强大工具,使得开发人员可以动态编译和执行C#代码和表达式。通过C#反射,还能轻松访问公共和私有方法、字段、属性值,并创建对象实例。02使用示例1、依赖库安装Install-PackageZ.Expr...

Eval-Expression.NET是一个开源项目,可以在.Net中执行C#代码和表达式。它可以动态编译和执行代码,访问公共和私有方法、字段和属性值,并创建对象实例。该项目提供了多种使用示例,包括简单公式、复杂代码、参数占位符、动态类的属性、字符串扩展方法和委托。项目地址:https://github.com/zzzprojects/Eval-Expression.NET

相关推荐 去reddit讨论
六虎

六虎 -

掌握JavaScript:多种方法生成二维数组

本文深入探讨JavaScript中生成一维和二维数组的多种方法,从基础到进阶,通俗易懂,适合各层次开发者。旨在提升对数组操作的理解和灵活运用能力。

本文介绍了在JavaScript中生成二维数组的多种方法。首先讲解了创建一维数组的常见方法,包括数组字面量、Array结构函数、Array.from()和打开运算符等。然后讨论了生成二维数组的四种方法,分别是嵌套循环、Array.from()、Array.fill()和map()、打开运算符和map()。每种方法都有其优缺点,选择取决于具体需求和个人喜好。作者推荐使用Array.from()方法,因为它强大且易于理解。最后,强调了掌握生成二维数组的多种方法对于处理不同的编程挑战非常有帮助。

相关推荐 去reddit讨论

热榜 Top10

观测云
观测云
LigaAI
LigaAI
Dify.AI
Dify.AI
eolink
eolink

推荐或自荐