【译】六个字符构建 Javascript 世界

简介:

李俊冬,租赁大前端,17 年 2 月加入链家,先后负责新房 B 端、租赁 C 端的前端开发。

 前言 

无用但有趣的冷知识,通过[ ] ( ) ! +  构建 Javascript 世界,hope you enjoy it!

Javascript 是一门非常奇怪,同时也非常棒的语言,我们可以用它写出非常疯狂但却奏效的代码,同时,它也能根据我们使用的方式进行类型转换从而辅助开发。

 构建假设  

如果将字符串(string)和其他类型参数相加,它会猜测我们需要文本格式,最后结果将返回  string 类型。

如果将其他类型参数加上 + 或  - 前缀,它知道我们需要一个数值类型(Number ),

如果类型转换合法,紧接着就会将参数转换成数值类型。

如果将参数取反(!),它会把类型转换成布尔值。

 构建法则 

下面让我们从最基础的开始,这里有几条黄金法则:

1.通过 ! 转换为布尔(Boolean)类型 2.通过  + 转换为数值(Number)类型 3.与 [] 相加转换为字符(String)类型

通过上面的黄金法则,让我们实践几个例子:


  ![] === false

  +[] === 0

  []+[] === ""

当然,聪明的你肯定知道可以通过中括号加索引的方式从字符串中获取对应位置的字符:


  "hello"[0] === "h"

通过多个数值字符相加,再转换为数值类型,即可获得多位数:

  +("1" + "1") === 11

非常棒,通过上面的铺垫,现在我们已经拿到了字母  a :

  ![] === false

  ![]+[] === "false"

  +!![] === 1

  ------------------------

  (![]+[])[+!![]] === "a"  // same as "false"[1]

如此,通过一些简单的结合,我们还可以从单词 true 和  false 中获取到 a 、ef 、lr 、st 、u,那剩下的字母呢?

别忘了,我们还可以通过 [][[]] 这种方式获得  undefined,复用上面的方式,我们能拿到字母 d 、in 。


  [][[]] + [] === "undefined"

 模拟构建 

到目前为止,通过我们拿到的字母,已经可以拼出 fill、 filterfind  这些单词,当然,你还可以组合成其他的单词,值得一提的是,上面提出三个单词都属于数组方法,这意味可以在数组实例中直接被调用,例如 [2,1].sort()

语法上,[2,1]["sort"]() 是与  [2,1].sort() 等价的。

让我们继续看看,使用字母拼凑的数组方法还能得到什么,目前我们还不需要执行这些函数:


  []["fill"]

上面的代码最终会产生  function fill() { [native code] },通过黄金法则,我们将结果再次转换为   String 类型:


  []["fill"]+[] === "function fill() { [native code] }"

现在,我们又获得了 c、 ov 、() 、{} 、(空格)。

通过新获取的 c 和  o,现在可以组合单词 constructor ,constructor 是 JS 对象中返回构造函数的方法,下面就让我们通过  constructor 从已有对象类型中获取对应字符串形式的构造函数:


  true["constructor"] + [] === "function Boolean() { [native code] }"

  0["constructor"] + []    === "function Number() { [native code] }"

  ""["constructor"] + []   === "function String() { [native code] }"

  []["constructor"] + []   === "function Array() { [native code] }"

通过这些构造函数,字母集合中增添了 B、 NS 、Am 、gy

现在可以构建 toString,同样,可以通过中括号使用的函数,不过这次我们要执行它:


(10)["toString"]() === "10"

但前文中我们已经通过第三条黄金法则熟练地将任何类型转换为字符串类型了,toString 的存在看起来有点鸡肋,没用了?

别忘了,数值类型的 toString 方法还有第二个参数  radixradix  决定了数值转换为字符串类型前被转换为的进制,举个例子:


  (12)["toString"](10) === "12" // base 10 - normal to us

  (12)["toString"](2) === "1100" // base 2, or binary, for 12

  (12)["toString"](8) === "14" // base 8 (octonary) for 12

  (12)["toString"](16) === "c" // hex for 12

机智的你肯定想到了,为什么只写到 16 进制?进制最大可以是 36,这可包括了  0-9 、 a-z 中的所有字母,现在我们可以拿到我们想要的任何字母:

  (10)["toString"](36) === "a"

  (35)["toString"](36) === "z"

太棒了,我们已经拿到了全部小写字母,但新问题摆在眼前,标点符号和大写字母该怎么办呢?

根据 JS 执行的位置,它可能有权限访问特定的预定义对象或数据,如果是在浏览器中运行,那么就可以有访问到一些传统的 HTML 包装方法,例如,bold  是一个字符串方法,可以将字符串用 <b> 标签包裹。

  "test"["bold"]() === "<b>test</b>"

这样,我们就拿到了 <、 > 和 / 。

 函数运行 

你可能在项目开发中使用过 escape 函数,它可以将字符串转换为浏览器可以翻译的  URI 友好格式,这个函数在我们接下来的工作中扮演了重要角色,我们需要用到它。通过拼凑字母得到这个单词,但问题是如何使其执行,它是一个全局函数,不属于任何类型。

那么函数的构造函数是什么呢?其实就是函数对象本身,function Function() { [native code] }


  []["fill"]["constructor"] === Function

通过  Function,我们可以传入字符串来构建一个函数:


  Function("alert('test')");

运行得到:


  Function anonymous() {

      alert('test')

  }

我们只需要在末尾加上 () 就可以立即执行这个函数,如你所见,我们现在可以真正执行代码了!

小试牛刀,运行 escape 函数:

  []["fill"]["constructor"]("return escape(' ')")() === "%20"

如果我们给  escape 函数传入   <,会得到  %C ,如果想获得盛夏的大写字母,这个  C 至关重要。


  []["fill"]["constructor"]("return escape('<')")()[2] === "C"

通过  C,我们可以得到   fromCharCode 函数,通过给定的十进制参数,可以得到对应的 Unicode 字符,它属于字符对象,因此调用方式可以参照前文:


  ""["constructor"]["fromCharCode"](65) === "A"

  ""["constructor"]["fromCharCode"](46) === "."

 Javascript 世界  

通过 Unicode 速查可以快速找到任何字符对应的数值。

到这里,Javascript 世界的构建元素已经全部找齐!我们已经能拿到我们需要的任何参数,并将它们连接到一起形成代码并执行,这意味,我们仅通过 [ 、]( 、)+ 、! 实现了 Javascript 的图灵完备。

想证明一下?不妨在浏览器控制台里执行下面的代码:

如果你是在手机上看的,可以告诉你,上面执行的是 alert("wtf")

jsFuck 可以自动转换你的代码,这里是过程介绍。

你说了这么多,有用吗?

如果你非要问我有没有用,我只能说点儿用也没,不过 eBay 前段时间出了个 Bug,网站里允许卖家在页面中插入这些字符构成的 JS 代码,但这种攻击媒介不是很常见。有人说可以用来进行代码混淆,实际上,有更好的混淆方式。

原文:

A Javascript journey with only six characters

作者:李俊冬


监审:蔡白银

编辑:钟   艳

网址:tech.lianjia.com


原文发布时间为:2018年06月21日
原文作者: 掘金

本文来源: 掘金 如需转载请联系原作者


相关文章
|
27天前
|
JavaScript 前端开发 物联网
JavaScript:构建动态世界的引擎
JavaScript:构建动态世界的引擎
|
27天前
|
前端开发 JavaScript 开发者
JavaScript:构建动态网络的引擎
JavaScript:构建动态网络的引擎
|
27天前
|
前端开发 JavaScript 开发者
JavaScript:构建动态Web的核心力量
JavaScript:构建动态Web的核心力量
|
5月前
|
前端开发 算法 API
构建高性能图像处理Web应用:Next.js与TailwindCSS实践
本文分享了构建在线图像黑白转换工具的技术实践,涵盖技术栈选择、架构设计与性能优化。项目采用Next.js提供优秀的SSR性能和SEO支持,TailwindCSS加速UI开发,WebAssembly实现高性能图像处理算法。通过渐进式处理、WebWorker隔离及内存管理等策略,解决大图像处理性能瓶颈,并确保跨浏览器兼容性和移动设备优化。实际应用案例展示了其即时处理、高质量输出和客户端隐私保护等特点。未来计划引入WebGPU加速、AI增强等功能,进一步提升用户体验。此技术栈为Web图像处理应用提供了高效可行的解决方案。
|
6月前
|
前端开发 搜索推荐 JavaScript
如何通过DIY.JS快速构建出一个DIY手机壳、T恤的应用?
DIY.JS 是一款基于原生 Canvas 的业务级图形库,专注于商品定制的图形交互功能,帮助开发者轻松实现个性化设计。适用于 T 恤、手机壳等多种商品场景。它自带丰富功能,无需从零构建,快速集成到项目中。通过创建舞台、添加模型、定义 DIY 区域和添加素材四个步骤即可完成基础用法。支持在线演示体验,文档详细,易上手。
217 57
|
6月前
|
前端开发 JavaScript NoSQL
使用 Node.js、Express 和 React 构建强大的 API
本文详细介绍如何使用 Node.js、Express 和 React 构建强大且动态的 API。从开发环境搭建到集成 React 前端,再到利用 APIPost 高效测试 API,适合各水平开发者。内容涵盖 Node.js 运行时、Express 框架与 React 库的基础知识及协同工作方式,还涉及数据库连接和前后端数据交互。通过实际代码示例,助你快速上手并优化应用性能。
|
7月前
|
JavaScript 算法 前端开发
JS数组操作方法全景图,全网最全构建完整知识网络!js数组操作方法全集(实现筛选转换、随机排序洗牌算法、复杂数据处理统计等情景详解,附大量源码和易错点解析)
这些方法提供了对数组的全面操作,包括搜索、遍历、转换和聚合等。通过分为原地操作方法、非原地操作方法和其他方法便于您理解和记忆,并熟悉他们各自的使用方法与使用范围。详细的案例与进阶使用,方便您理解数组操作的底层原理。链式调用的几个案例,让您玩转数组操作。 只有锻炼思维才能可持续地解决问题,只有思维才是真正值得学习和分享的核心要素。如果这篇博客能给您带来一点帮助,麻烦您点个赞支持一下,还可以收藏起来以备不时之需,有疑问和错误欢迎在评论区指出~
|
7月前
|
JavaScript 前端开发 Java
详解js柯里化原理及用法,探究柯里化在Redux Selector 的场景模拟、构建复杂的数据流管道、优化深度嵌套函数中的精妙应用
柯里化是一种强大的函数式编程技术,它通过将函数分解为单参数形式,实现了灵活性与可复用性的统一。无论是参数复用、延迟执行,还是函数组合,柯里化都为现代编程提供了极大的便利。 从 Redux 的选择器优化到复杂的数据流处理,再到深度嵌套的函数优化,柯里化在实际开发中展现出了非凡的价值。如果你希望编写更简洁、更优雅的代码,柯里化无疑是一个值得深入学习和实践的工具。从简单的实现到复杂的应用,希望这篇博客能为你揭开柯里化的奥秘,助力你的开发之旅! 只有锻炼思维才能可持续地解决问题,只有思维才是真正值得学习和分享的核心要素。如果这篇博客能给您带来一点帮助,麻烦您点个赞支持一
|
10月前
|
JSON JavaScript 前端开发
深入浅出Node.js:从零开始构建RESTful API
在数字化时代的浪潮中,后端开发作为连接用户与数据的桥梁,扮演着至关重要的角色。本文将引导您步入Node.js的奇妙世界,通过实践操作,掌握如何使用这一强大的JavaScript运行时环境构建高效、可扩展的RESTful API。我们将一同探索Express框架的使用,学习如何设计API端点,处理数据请求,并实现身份验证机制,最终部署我们的成果到云服务器上。无论您是初学者还是有一定基础的开发者,这篇文章都将为您打开一扇通往后端开发深层知识的大门。
206 12
|
11月前
|
JavaScript NoSQL API
深入浅出Node.js:从零开始构建RESTful API
在数字化时代的浪潮中,后端开发如同一座灯塔,指引着数据的海洋。本文将带你航行在Node.js的海域,探索如何从一张白纸到完成一个功能完备的RESTful API。我们将一起学习如何搭建开发环境、设计API结构、处理数据请求与响应,以及实现数据库交互。准备好了吗?启航吧!

热门文章

最新文章