[]['map']['constructor']('console.log(1)')();
这行代码本身在我的js文件中输出'1'。根据Martin Kleppe的说法,这是如何分解的:
[]['map'] becomes function
function['constructor'] becomes Function
Function('console.log(1)')() becomes eval('console.log(1)')
在更简单的Javascript逻辑中,是否可能有一个解释像我是五个 Stacks Edition ?因为当 Martin 解释它时,他已经为像我这样的初学者跳过了许多步骤:(
答案 0 :(得分:3)
[]['map']['constructor']('console.log(1)')();
请记住,JavaScript支持使用方括号和点语法来查询对象。
所以第一部分相当于
[].map.constructor
...其中[]
创建一个新数组。此数组继承(在其原型上)map()
方法,该方法继承其原型,对Function
构造函数的引用(因为map()
是一个函数。)
所以这一切只是Function()
的一条错综复杂的路线。我们可以用任何其他数组方法替换map()
,例如forEach
或reduce
,或根本不使用数组,例如
document['querySelector']['constructor']
...因为每个方法都继承自Function()
。
现在,Function()
允许您通过将函数体作为字符串传递给它的第一个也是唯一的参数来创建动态函数。所以:
var myFunc = new Function('alert("hello from my func");');
此技术几乎从不使用,same security risks为eval()
。在任何语言中,很少有充分的理由(或安全的方式)将字符串作为代码进行评估。 (也就是说,在框架中作为允许在DOM属性中使用基于JS的指令和语法的手段,例如,例如Framework7),这一点令人担忧。
在您的示例中,动态创建的函数是在控制台中记录整数1的函数。
最后,我们创建的函数尾随()
immediately executes。它没有分配给变量;它只是被执行了。
答案 1 :(得分:0)
[]
这是一个 Array Literal 。它创建了一个新数组。
['map']['constructor']
这是用于访问对象(数组)属性的括号表示法。原因图是函数,其构造函数是全局Function
函数。
('console.log(1)')
这将调用Function
函数,并将一些代码作为第一个参数。这将返回一个新函数,其中包含我们在其中传递的代码(糟糕的黑魔法)。
()
现在我们称之为该功能。
答案 2 :(得分:0)
[]['map']['constructor']('console.log(1)')();
:
[]
:是一个数组(Array
的实例)['map']
:是从 1访问数组属性map
的括号表示法。 ['constructor']
:使用括号表示法访问 2。中constructor
函数的map
属性Function
('console.log(1)')
:使用字符串Function
从 3。调用"console.log(1)"
,该字符串将返回定义为function() { console.log(1) }
的函数。()
:调用 4。返回的函数,该函数会将1
记录到控制台。