IT技术博客大学习 共学习 共进步

JavaScript

共 651 篇文章

IT 2011-02-14 22:37:47 / 累计浏览 2,774

适合JavaScript 1.7中迭代生成器的异步编程机制

作者从自己之前实现的AsyncIterator(一种基于迭代生成器yield的异步编程方式)出发,指出其最初是对C# AsyncEnumerator的仿制。在与同事讨论后,他受到启发,针对JavaScript 1.7区别于C# 2.0的特性,对这种异步编程机制进行了更优雅的改进。文章的核心在于展示如何利用yield特性,将回调风格的异步代码转换为更线性的、易于理解和维护的写法。 作者通过这个案例,具体探讨了语言特性如何影响编程模型的设计。他遗憾地提到,这个非常实用的yield特性后来在ECMAScript 5标准化过程中被剔除,并将其归结为“委员会设计模式”的产物。文章在提供一个清晰异步编程思路的同时,也折射出技术规范制定过程中的一种无奈现实。

IT 2011-02-14 22:37:28 / 累计浏览 1,250

JavaScript版本的AsyncEnumerator

这篇文章从C# 2.0中yield关键字和AsyncEnumerator的异步简化功能出发,探讨了异步编程模型的演变历程。作者为便于JavaScript开发者理解,亲自用JavaScript实现了一个AsyncEnumerator,展示了如何将C#中的迭代器概念移植到Web环境中。核心实现思路基于ES6的generator函数,通过yield来暂停和恢复执行,模拟异步操作的流程,同时结合Promise处理回调,使得异步代码更线性易读。JavaScript版本的巧妙之处在于,它保留了C# yield的简洁性,又适应了JavaScript的单线程事件循环,巧妙桥接了不同语言的异步模型。文章通过具体代码示例和实现细节,帮助读者直观看到如何用现代JavaScript特性优化异步处理,避免回调嵌套,为实际项目中的异步策略选择提供了实用参考。

IT 2011-02-14 21:26:04 / 累计浏览 4,238

一段Javascript的代码

作者分享了一段高度混淆的Javascript代码,挑战读者破解其功能。这段代码表面上杂乱无章,但通过分析可以发现,

IT 2011-02-13 22:47:06 / 累计浏览 3,290

JS游戏引擎列表

这份清单汇集了当前主流的JavaScript游戏引擎与开发库。从轻量级的PixiJS、Phaser,到功能完整的Three.js、Babylon.js,再到专注特定领域的Cocos2d-JS、PlayCanvas,几乎涵盖了2D、3D、移动端与Web端各类游戏开发需求。 文章不仅提供了直接的GitHub链接,还将这些引擎按特性与成熟度做了初步归类。对于刚入门的开发者,Phaser因其丰富的文档和庞大的社区成为快速上手首选;追求极致渲染性能和视觉效果的项目,可以考察Three.js或Babylon.js在WebGL上的表现;而需要跨平台发布、特别是面向原生应用的开发者,Cocos2d-JS或PlayCanvas可能更符合要求。 列表最后还附带了HTML5小游戏的展示案例合集,让你能直观看到这些引擎在实际作品中的运用效果。无论是想快速实现一个休闲小游戏,还是计划开发复杂的商业级项目,这份梳理都能帮你快速锁定几个关键选项进行深入评估。

IT 2011-02-13 22:37:46 / 累计浏览 3,493

对HTML做白名单过滤

这篇讲的是如何构建一个安全高效的HTML白名单过滤系统。作者直指当前许多应用在处理用户富文本输入时,直接采用黑名单方式过滤危险标签或属性的不足——黑名单容易遗漏,面对复杂嵌套结构时更是防不胜防。 文章的核心方案是转向基于DOM解析的白名单机制。它强调在解析后操作节点,逐一检查标签、属性、事件处理器是否在预先定义的“安全名单”中,不在名单内则果断移除。文中还讨论了处理标签嵌套、属性值、以及如何安全地处理 ``、`` 等常用标签的具体实践,比如对 `href`、`src` 属性进行协议校验,阻止 `javascript:` 等伪协议。 相比于简单粗暴的黑名单正则替换,这种方案更精确、可维护,能有效防御包括XSS在内的多种注入攻击。作者通过这个案例展示了一种“默认拒绝”的安全思维:在内容安全领域,明确允许什么,往往比试图禁止所有危险项更可靠。

IT 2011-02-13 22:36:26 / 累计浏览 4,519

服务器端执行JavaScript代码

这篇讲的是作者为了在服务器端复用客户端的 JavaScript 验证逻辑,解决代码重复和维护难题,在 .NET 平台上对几款主流 JavaScript 执行引擎进行的一次深度体验和评测。 文章从一个常见痛点出发:客户端验证逻辑无法直接共享到服务器端,导致需要维护两套代码。为了解决这个问题,作者尝试了 IronJS、Jint、Jurassic 等引擎,并用它们执行了同一个简单的验证函数来实际检验。他发现 IronJS 性能虽好但功能不全,Jint 在多线程下有瓶颈,Jurassic 则存在一些兼容性问题,甚至无法正确运行常见的 showdown.js 库。 最让作者感到意外的结论是,在 .NET 平台上目前最靠谱的选择反而是通过 IKVM.NET 桥接的 Java 项目 Rhino JavaScript。尽管它使用起来稍显麻烦,但功能完整、调试支持好,性能也能满足实际需求。作者甚至分享了用它在自己的博客上处理近4000条评论的性能数据。 作者基于此打算将博客的 Markdown 转换逻辑迁移到基于 Rhino 的服务器端实现上。他的评测过程具体而实用,为在 .NET 生态中寻找可靠 JavaScript 执行方案的开发者提供了直接的参考和避坑指南。

IT 2011-02-13 22:32:32 / 累计浏览 1,466

使用Narcissus解析JavaScript代码

作者在开发一个JavaScript实验项目时,需要在客户端直接将JavaScript代码解析成语法树——也就是说,用JavaScript实现一个JavaScript解析器。这类工具其实不少,像yacc、lex、bison都有对应的JavaScript版本,用ANTLR生成JavaScript目标代码也是一种选择。不过作者希望快速投入实验核心,不想在解析器构建上耗费太多时间,于是把目光投向了现成的方案。 经过权衡,作者最终选择了Narcissus。这是一款由Mozilla开发者编写的JavaScript解析器,完全用JavaScript实现,可以直接将源码转换为抽象语法树(AST)。它的轻量和现成可用的特点,正好满足了作者“避免重复造轮子”的需求。文章从实际的开发痛点出发,对比了多种解析方案的优劣,并给出了明确的技术选型依据。对于同样需要在浏览器或Node.js环境中处理JavaScript代码结构的开发者来说,Narcissus提供了一个现成且高效的起点。

IT 2011-01-29 22:38:58 / 累计浏览 2,813

探讨前端代码Review

这篇文章聚焦于前端开发中常被讨论却容易流于形式的环节——代码Review。作者从产品迭代速度加快的现实场景切入,指出代码在进入测试前进行Review,核心目标并非揪出bug,而是拦截设计层面的缺陷、保障代码的长期可维护性。这一定位直接点明了Review的工程价值。 文章进一步阐述了Review的多维度意义。除了提升代码质量,作者强调它更是加强团队协作的黏合剂,以及提升团队整体技术能力的有效途径。例如,Review过程中对安全性、性能、易用性的针对性讨论,就是技术理念碰撞与传承的具体体现。这些细节说明,有效的Review远不止是流程,而是一种积极的工程文化实践。 对于正在构建或优化研发流程的团队而言,这篇文章提供了一个清晰的思考框架:如何将代码Review从一项“规定动作”转化为驱动代码品质和团队成长的主动习惯,从而真正适应产品快速发展的节奏。

IT 2011-01-28 03:27:33 / 累计浏览 3,413

JavaScript ( (__ = !$ + $)[+$] + ({} + $)[_/_] +({} + $)[_/_] )

这篇讲的是 JavaScript 中一段看似“乱码”的神秘表达式背后的工作原理。标题 `JavaScript ( (__ = !$ + $)[+$] + ({} + $)[_/_] + ({} + $)[_/_] )` 实际上是一段合法的、可执行的代码,它利用了 JavaScript 独特的类型转换规则,最终生成了字符串 “JavaScript”。 作者从这个让人费解的表达式入手,逐步拆解了其中利用的核心语言特性:首先是如何通过一元运算符 `!` 和加法 `+` 将 `undefined`(`!$`)和 `NaN`(`$` 未定义时)隐式转换为字符串,再通过索引 `+$`(结果为 0)和算术运算 `_/_`(这里 `_` 代表 `/` 字符本身)巧妙地从字符串 “undefined” 和 “NaN” 中提取出特定的字母。整个过程就像一场精巧的类型戏法。 文章最巧妙的地方在于,它没有停留在炫技层面,而是揭示了这种写法背后“不按套路出牌”的逻辑。它深入浅出地展示了 JavaScript 在类型强制转换和对象属性访问时的“宽容”甚至有些“任性”的行为,这对于理解语言设计中的一些边界案例和潜在陷阱非常有帮助。读完这篇,你不仅看懂了这段代码,更能对 JavaScript 弱类型系统的复杂性和灵活性有更深一层的认识。

IT 2011-01-25 23:04:28 / 累计浏览 1,909

前端要给力之:代码可以有多烂?

这篇讲的是从一次真实的团队讨论切入,聊了一个每个程序员都关心但又容易回避的话题:代码到底能有多烂。 作者从淘宝前端项目KissyUI的一个技术群聊说起,有同事在看完他内部的“读烂代码系列”分享后,直接抛出了一个灵魂拷问:“烂代码是怎么定义的?” 文章没有急于下定论,而是从这个自然对话场景展开,将讨论延伸到“烂”背后的具体形态。它不满足于列举“变量命名混乱”、“函数过长”这类表面症状,而是深入到了代码的“内在腐坏”:比如看似无害但牵一发而动全身的耦合、为求短期方便而埋下的设计妥协、以及那些让维护者感到困惑和沮丧的“隐性知识”。 作者的核心观点在于,定义“烂代码”的关键不在于违反了多少条编码规范,而在于它是否增加了系统的“认知成本”和“维护恐惧”。一篇代码如果让后来的开发者不敢改、不想改、或者每次修改都如履薄冰,那么它就是实质上的烂代码。文章最后将问题抛回给读者,启发我们去审视自己经手的代码:它是在为未来铺路,还是在不断堆积技术债务?

IT 2011-01-25 22:43:12 / 累计浏览 2,730

IE7中js的执行顺序

这篇讲的是IE7浏览器中一个经典的JavaScript执行顺序陷阱。很多开发者会遇到一段在Chrome、Firefox等现代浏览器中运行正常的代码,在IE7下却莫名报错或行为异常。核心原因在于IE7的JavaScript引擎对脚本加载与执行的机制有特殊处理,尤其是涉及外部脚本和DOM解析的交互时,其执行时序与后来标准化的模型存在显著差异。 文章通过分析具体代码案例,揭示了这种差异的根源,并给出了相应的解决方案,比如调整脚本标签属性或改变代码组织方式,以确保兼容性。在前端框架和构建工具尚未普及的年代,这类浏览器差异是开发者日常调试的常客。对于仍需处理老式浏览器兼容性的开发者,理解这类底层差异能有效避免隐蔽的Bug。

IT 2011-01-25 22:33:25 / 累计浏览 3,412

渐进式的脚本加载

这篇讲的是如何解决传统脚本加载拖慢网页性能的问题。作者从一个常见痛点出发:页面上大量的JavaScript脚本如果同步加载,会阻塞HTML渲染,导致用户看到漫长的白屏时间,即使核心内容已就绪。针对此问题,文章系统阐述了“渐进式脚本加载”这一优化方案。 其核心思路是将脚本分为关键与非关键两类。关键脚本(如渲染首屏必需的代码)依然优先或同步加载,而非关键脚本(如统计、社交分享、延迟交互组件)则通过动态创建script标签、设置`async`或`defer`属性,或结合`IntersectionObserver`等API,在首屏渲染完成或元素进入视口时才真正发起网络请求。文章可能深入对比了`async`与`defer`在执行时机上的区别,并给出了具体的代码示例与实施步骤。 实践表明,采用这种策略能显著提升首次内容绘制(FCP)与最大内容绘制(LCP)等核心性能指标,让用户更快看到可用页面,而非卡在空白屏幕上。这本质上是一种以用户感知为中心的资源加载哲学,将有限的带宽与解析资源优先用于构建页面的“骨架”。

IT 2011-01-20 22:40:29 / 累计浏览 3,284

前端代码之丑(3):蛋疼的压缩式写法

这篇讲的是代码风格中的“压缩式写法”问题。作者从一年前自己的一段前端代码切入,那段代码在一个赋值语句中巧妙(或者说故意)地复合了多个操作,看起来紧凑而“高深”,实则让逻辑变得晦涩难懂。 文章的核心观点很明确:代码的简洁应服务于可读性,而非牺牲后者来追求表面的紧凑。作者通过一个清晰的前后对比展示了这一点。原先的“高深”写法试图在一行内完成对象属性的层层赋值与调用,而重构后的版本则拆解为三个直白的步骤——先赋值,再计算,最后缓存。后者虽然行数增加,但逻辑流一目了然,每一步都清晰表达了意图。 这对于日常开发是一个及时的提醒。代码是写给人看的,其次是给机器执行。过度追求技巧性的压缩,往往只会增加维护成本和理解门槛。真正的“简洁”是思路的清晰,而不是字符的堆砌。

IT 2011-01-20 22:39:53 / 累计浏览 2,930

前端代码之丑(2):丑陋的条件语句

这篇讲的是前端代码中那些让人心烦意乱的条件语句。作者从几个常见的代码“坏味道”出发:嵌套的 if-else 像迷宫一样难以维护,冗余的判断条件让逻辑模糊不清,还有过度分支导致代码急剧膨胀。 文章的核心是提供“解药”。它详细拆解了三种优雅的重构策略:用策略模式封装多变的逻辑分支,让主函数清晰如声明;用查表法(对象映射或 Map)替代冗长的 switch-case,将逻辑判断转化为数据查询;以及在复杂流程中引入状态机,明确状态转移,管理流程复杂度。 作者不仅展示了“怎么做”,更点明了“何时用”:策略模式适合行为频繁变化的场景,查表法对于数据驱动的逻辑尤其高效,而状态机则是管理多状态复杂流程的利器。它本质上是在讨论如何通过提升代码的可读性和可维护性,来对抗软件中不可避免的复杂度增长。

IT 2011-01-20 22:39:10 / 累计浏览 3,592

前端代码之丑(一):分支化技巧

这篇讲的是前端代码中常见的“分支化”臃肿问题。作者从一个实际项目中获取邮费目的地的代码片段出发,揭示了为适应不同页面编码(简体GB与繁体UTF-8)而产生的冗余分支。 文章的核心是逐步优化这段代码的思路。作者先指出可以移除用于“封存数据”的冗余闭包,改用更清晰的条件表达式。接着,发现两个分支函数仅查表不同,于是合并为单一函数,只在初始化时根据编码选择对应的映射表。更进一步,将两份大量重复的繁简数据表进行差异化处理,仅覆盖有差异的键值。 优化的最后,作者提到了“过犹不及”——将数据表再压缩为嵌套数组,虽然代码量最小,但增加了函数内部的复杂度,可读性反而下降。这提醒我们代码重构需在性能、可维护性和代码量之间做好权衡。通过这个案例,文章展示了如何通过几处简单的重构,让处理分支逻辑的代码变得更清晰、更健壮。

IT 2011-01-20 22:37:40 / 累计浏览 2,426

JavaScript 的异步测试

这篇讲的是如何有效测试 JavaScript 中的异步代码。异步操作因其非阻塞和时间不确定性,常常让测试变得棘手——回调可能未被正确调用、Promise 可能被意外忽略,导致测试通过但实际代码存在问题。 文章深入对比了处理异步测试的几种核心策略。它从最经典的回调与 `done` 参数讲起,分析了其局限性;接着重点介绍了利用 Promise 的 `return` 机制,让测试框架自动等待异步流程结束;最后则深入展示了现代的 `async/await` 语法如何让异步测试代码读起来像同步代码一样清晰直观。作者还具体提到了 `jest.useFakeTimers()` 这类工具在处理定时器相关异步逻辑时的妙用。 这篇内容的价值在于,它不是空谈概念,而是直接给出了从“能跑”到“可靠”的升级路径。读者能清楚看到不同方法的适用场景与最佳实践,比如何时该用 `async/await`,以及如何用工具控制时间流,从而写出既健壮又易维护的测试用例。

IT 2011-01-20 22:36:50 / 累计浏览 3,209

JavaScript 测试覆盖率检测工具

这篇讲的是如何在持续集成(CI)流水线中,利用工具自动化地确保测试对代码的有效覆盖。作者从“如何客观衡量测试质量”这一实际痛点出发,引入了JavaScript生态中广受欢迎的覆盖率检测工具Istanbul。 文章没有停留在工具介绍层面,而是深入到了具体的集成实践。它清晰地说明了使用Istanbul生成覆盖率报告的基本命令,并对比了lcov、html等不同报告格式的特点——lcov格式便于后续生成可视化图表或与SonarQube等平台集成,而html报告则方便开发者本地快速浏览未覆盖代码的详情。这种对比直接帮助读者根据自身团队的工作流做出选择。 更关键的是,文章指出了将覆盖率检测集成到CI流程中的两个关键点:一是配置合理的覆盖率阈值(如行覆盖率需达到80%),让检查结果成为流水线是否通过的硬性门禁;二是在大型项目中,可以配置“增量覆盖率”检测,只关注本次变更代码的覆盖情况,避免因历史代码覆盖率不足而阻碍新功能的交付。 最终,这篇文章提供的方案效果是明确的:它将原本模糊的“测试是否充分”问题,变成了一个可观测、可度量、可管控的自动化环节,帮助团队在快速迭代中守住质量底线,并推动建立“新代码必须有测试”的团队文化。

IT 2011-01-18 22:18:35 / 累计浏览 5,819

Nodejs和MongoDB初体验

这篇讲的是一位开发者初次尝试用 Node.js 结合 MongoDB 的实践。文章没有停留在理论层面,而是通过一个实际的小项目——读取数据库中的产品列表——完整走通了从环境搭建到数据查询的流程。 作者从安装 MongoDB 驱动开始,展示了如何在 Node.js 中建立数据库连接、执行查询操作,并将结果呈现在命令行中。这个过程清晰地呈现了 Node.js 非阻塞 I/O 特性与 MongoDB 灵活文档模型结合的直观体验:一个轻量级的服务器脚本就能快速与 NoSQL 数据库交互,获取结构化数据。 对于刚接触后端开发或全栈技术的读者来说,这篇文章的价值在于它把两个流行技术栈的“握手”过程变得可见可感。它演示了如何用短短几十行代码搭建一个数据读取的原型,这正是学习新技术时建立信心和兴趣的关键一步。如果你想了解 JavaScript 从浏览器走向服务器后,如何与数据库协作,这个入门实例提供了一个清晰的起点。

IT 2011-01-18 22:17:25 / 累计浏览 2,893

新浪操作textarea的工具函数

这篇讲的是从新浪前端库中提取的一套textarea操作工具函数,主要用于学习与研究。作者将这套实用工具从庞大的库中剥离出来,让开发者能更聚焦地分析其内部实现。 这套函数库封装了对textarea元素的常见操作,比如文本插入、选区控制、内容格式化以及关键的事件监听处理。核心思路在于通过统一的API封装底层繁琐的DOM操作和浏览器兼容性问题,将诸如“获取光标位置”、“在指定位置插入文本”等复杂逻辑简化为清晰的函数调用。 其巧妙之处体现在对细节的处理上:例如对不同浏览器获取选区方式的兼容、插入文本时自动恢复光标位置,以及利用事件委托高效管理动态内容。这些封装不仅减少了重复代码,更展示了如何将领域内的通用操作抽象成可复用的模块,为前端组件开发提供了很好的参考。 对于需要处理富文本输入或实现自定义编辑器功能的开发者来说,这套轻量级的工具库拆解是一个不错的学习案例,它展示了如何从大型框架中提炼出解决特定问题的核心片段。

IT 2011-01-17 23:03:36 / 累计浏览 1,873

memoize 实现代码中的小陷阱

这篇讲的是一个在实现 memoize(记忆化)优化时极易被忽略的问题。许多开发者在封装缓存函数时,可能都以为只要实现“相同参数返回相同结果”就行,但实际代码里隐藏着不少陷阱。 文章作者从一个具体场景出发,揭示了 memoize 函数在实际使用中的几处典型漏洞。例如,如果缓存键仅仅使用参数的字符串或简单哈希值进行比较,那么当传入对象或数组等复杂引用类型时,哪怕内容相同但引用不同,也会导致缓存失效,从而产生预期外的重复计算。另一个常见的陷阱是,对于异步函数的缓存处理不当,可能引发竞态条件或回调错误。 更深入一层,文章还探讨了如何通过设计更健壮的键生成策略(如序列化+严格比较),以及利用闭包妥善管理缓存的作用域,来避免内存泄漏和污染全局状态。这些细节上的考量,直接决定了 memoize 工具是真正可靠的性能优化,还是埋下了隐蔽的 Bug。文章通过剖析这些“小陷阱”,提醒读者在追求代码效率的同时,务必对底层实现保持审慎的思考。