JavaScript“平平无奇”的 8 种函数调用方式!

335 阅读3分钟

用过JavaScript的前端佬都知道,如何去调用一个函数。

什么?还没有用过?那我先介绍下吧!

image.png

如下,我们可以这么定义一个JavaScript函数:

function ttt(string) {
   alert(string)
}

执行这个函数,就可以像下面这样编写:

ttt('JavaScript是第二好的语言!CSS是第一!')

好了,简单介绍完毕。肯定有很多技术超群的前端佬,还知道另外几种函数调用方式,这里就不补充了。掘金社区有很多很多这样的文章。

今天呢,主要给各位前端佬介绍几种“平平无奇”的函数调用方式!而且不带上面的小括号()。

而且这些调用方式并不是属于个别浏览器的hack,而是在绝大部分浏览器上可以顺利执行。尤其最后一种方式,堪称函数调用的天花板之一!!!

98b9a8d586cc43f2a6248b86dab2de2b.gif

声明!本知识大部分来自web安全大大佬Gareth Heyes博客学习!诸位需要精进自己技艺的前端佬,可以搜搜看看!

以下所有调用,默认都已经定义了ttt函数。

好,Show Time:

1、``符号调用

上面这个符号看着像单引号,其实不是,符号就是我们平常用的字符模版那个符号。然后如下敲出代码:

ttt`JavaScript是世界上第二好的语言!CSS是第一!`

然后,刷新页面执行。

不出意外,网页顺利出现如下效果: image.png

惊不惊喜?如果不惊喜,第二种开始。

2、throw + onerror方法调用

前端佬都知道,throw 语句用于抛出用户自定义的异常,通常是这么用的:

throw new Error('JavaScript不是世界上第二好的语言!');

这样会在浏览器中的控制台中输出这样效果。

image.png

onerror比较独特。一般是使用在html标签中,如果加载外部文件发生错误时,会被触发。比如下面这种经典用法。

<img src="image.gif" onerror="myFunction()">

直接在js语句直接写这个,也不会有报未定义之类的。

这两种呢,都有调用某一函数的能力。然后两个结合起来,就会发生奇妙的调用函数方式:

throw onerror=ttt,'JavaScript是世界上第二好的语言!CSS是第一!'

我也尝试换了几种事件,比如onloadoncancelonabort等,都不行,还是onerror好使!!

怎么,还不够行?再来第三种!

3、Function 调用

在 JavaScript 中,每个函数实际上都是一个 Function 对象。用Function ,是可以直接用字符串,构造一个函数的。

比如想要执行上面定义的ttt函数,就可以这么去调用:

Function('ttt("JavaScript是世界上第二好的语言!CSS是第一!")')()

但这个不是重点,我们需要平平无奇的去掉小括号(),结合第一种方式,可以有如下操作:

Function`a${'ttt\x28`JavaScript是世界上第二好的语言!CSS是第一!`\x29'}a```

嘎嘎!

怎么,还不行?来第四种!

4、instanceof 调用

instanceofSymboleval用处,被面试过的前端佬都知道是什么意思。但如果按照下面这么去组合:

'ttt\x28"JavaScript是世界上第二好的语言!CSS是第一!"\x29'instanceof{[Symbol['hasInstance']]:eval}

不出意外,那就那么意外的执行了ttt函数。

为啥?这里先不介绍了,我们接下去介绍第五种!

5、valueOf 调用

valueOf可能很多前端佬不大用。在Object、Symbol、Boolean、Date、String、Number等对象中都有这个方法,主要作用,是将自身指向返回。

功能调用不多说,在社区很多文章介绍。但如下这种组合:

valueOf=ttt'JavaScript是世界上第二好的语言!CSS是第一!';window+''

也会一样被执行。

上面那种奇怪的组合,假如删掉分号;,或者window,或者+号都会语法报错,唯独那么组合起来,一点没错,函数还能被执行。真正的神奇!

去执行上面那样带有参数的函数,简直有点可惜,丢失了简洁性。如果直接一个函数不需要参数,那么也可以这么去调用:

valueOf=ttt;window+''

还不满意?那么继续上第六种!!

6、DOMMatrix 调用

先不说,直接上代码:

x=new DOMMatrix;matrix=ttt;x.a=110;location='javascript'+':'+x

效果: image.png

上面那种写法,只能支持数字。如果x.a处,写了字符,那会直接语法报错。

new DOMMatrix是实例化一个矩阵对象操作,具体怎么样,说来惭愧,不是太了解,兼容性不是很好。所以这个只适合比较高的浏览器版本。

好了,不管满不满意,再上第七种了!

7、[].map.call 调用

上代码:

[].map.call`${eval}\\u{74}tt\x28'JavaScript是世界上第二好的语言!CSS是第一!'\x29`

完美执行。

ttt函数,其中一个t被\u{74}代替。

看到这里,有被轰炸到么?

准备迎接最猛烈的袭击么?

8、终极调用法

上代码:

[][[[][[[][[]]+[]][+[]][!+[]+!+[]+!+[]+!+[]]+[[][[]]+[]][+[]][!+[]+!+[]+!+[]+!+[]+!+[]]+[[][[]]+[]][+[]][!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]+[[][[]]+[]][+[]][!+[]+!+[]]]+[]][+[]][!+[]+!+[]+!+[]]+[[]+{}][+[]][+!+[]]+[[][[]]+[]][+[]][!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]+[![]+[]][+[]][!+[]+!+[]+!+[]]+[!![]+[]][+[]][+[]]+[!![]+[]][+[]][+!+[]]+[[][[]]+[]][+[]][+[]]+[[][[[][[]]+[]][+[]][!+[]+!+[]+!+[]+!+[]]+[[][[]]+[]][+[]][!+[]+!+[]+!+[]+!+[]+!+[]]+[[][[]]+[]][+[]][!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]+[[][[]]+[]][+[]][!+[]+!+[]]]+[]][+[]][!+[]+!+[]+!+[]]+[!![]+[]][+[]][+[]]+[[]+{}][+[]][+!+[]]+[!![]+[]][+[]][+!+[]]][[[][[[][[]]+[]][+[]][!+[]+!+[]+!+[]+!+[]]+[[][[]]+[]][+[]][!+[]+!+[]+!+[]+!+[]+!+[]]+[[][[]]+[]][+[]][!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]+[[][[]]+[]][+[]][!+[]+!+[]]]+[]][+[]][!+[]+!+[]+!+[]]+[[]+{}][+[]][+!+[]]+[[][[]]+[]][+[]][!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]+[![]+[]][+[]][!+[]+!+[]+!+[]]+[!![]+[]][+[]][+[]]+[!![]+[]][+[]][+!+[]]+[[][[]]+[]][+[]][+[]]+[[][[[][[]]+[]][+[]][!+[]+!+[]+!+[]+!+[]]+[[][[]]+[]][+[]][!+[]+!+[]+!+[]+!+[]+!+[]]+[[][[]]+[]][+[]][!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]+[[][[]]+[]][+[]][!+[]+!+[]]]+[]][+[]][!+[]+!+[]+!+[]]+[!![]+[]][+[]][+[]]+[[]+{}][+[]][+!+[]]+[!![]+[]][+[]][+!+[]]]`$${[!![]+[]][+[]][+[]]+[!![]+[]][+[]][+[]]+[!![]+[]][+[]][+[]]+[[][[[][[]]+[]][+[]][!+[]+!+[]+!+[]+!+[]]+[[][[]]+[]][+[]][!+[]+!+[]+!+[]+!+[]+!+[]]+[[][[]]+[]][+[]][!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]+[[][[]]+[]][+[]][!+[]+!+[]]]+[]][+[]][+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]+[[][[[][[]]+[]][+[]][!+[]+!+[]+!+[]+!+[]]+[[][[]]+[]][+[]][!+[]+!+[]+!+[]+!+[]+!+[]]+[[][[]]+[]][+[]][!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]+[[][[]]+[]][+[]][!+[]+!+[]]]+[]][+[]][+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]}$```      

能猜出上面的是干嘛了么?

第一次见,我也是觉的我之前学的JS,都是白学了!

直接上解释,上面主要的做法,就是Function(ttt())给逐个转义了。其中[!![]+[]][+[]][+[]]代表了t

[[][[[][[]]+[]][+[]][!+[]+!+[]+!+[]+!+[]]+[[][[]]+[]][+[]][!+[]+!+[]+!+[]+!+[]+!+[]]+[[][[]]+[]][+[]][!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]+[[][[]]+[]][+[]][!+[]+!+[]]]+[]][+[]][+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]代表了左括号(

[[][[[][[]]+[]][+[]][!+[]+!+[]+!+[]+!+[]]+[[][[]]+[]][+[]][!+[]+!+[]+!+[]+!+[]+!+[]]+[[][[]]+[]][+[]][!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]+[[][[]]+[]][+[]][!+[]+!+[]]]+[]][+[]][+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]代表了右括号)

OK!这些就是JavaScript中平平无奇的函数调用!

请受用!也请那些举一反三的大佬,不要另外他用哦!

A7.gif