Javascript in ten minutes: what happens in this code example illustrating the lazy scope?

I re-read Spencer Tipping excellent Javascript in ten minutes , and for me life cannot figure out what is going on in this example using the lazy area to create syntax macros:

var f = function () {return $0 + $1}; var g = eval (f.toString ().replace (/\$(\d+)/g, function (_, digits) {return 'arguments[' + digits + ']'})); g(5,6); // => 11 (except on IE) 

In particular,

  • $ 0 and $ 1 are replaced by the definition of a function - how is this function evaluated? (Presumably eval (), but I don't see it).
  • What is the purpose of a single underscore argument in a function - if I take it out, the code no longer works. Presumably, this is just the owner of the place, but why is it needed?
+6
source share
2 answers

This code scares me. It should not be fully used. (Unless there really is a convincing excuse, I don't know a single 1 2. ) In addition, there is no “functional programming” in the code above, except possibly using a callback. But hell, even C can trivially do this, since there was no closure.

_ is only a valid identifier (e.g. foo or _foo or $0 ). It doesn’t care (the value matches the entire agreed text, since the function is a “callback” to match RegExp).

$0 and $1 are replaced by arguments[0] and arguments[1] respectively (remember that this is a text substitution of the "string" value!). It could be printed manually without a "macro":

 function () { return arguments[0] + arguments[1] } 

Or what I would do:

 function (a,b) { return a + b } 

The rest ( Function.toString and eval(functionStr) ) are meaningless to support macro photography, which is based on: Function -> codeString -> alteredCodeString -> Function .

This code requires a working Function.toString , which can emit a "source as is". I'm not sure when IE started supporting this, but it seems to work in IE9.


1 This is a bit of a white lie, but the only place I used this approach is IE in the sidebar checkmark, where the DOM can be “prematurely unloaded” when the popup has been removed, and some other mess with trying to call a function in a different context window . All about a dirty situation.

2 The JavaScript function library shows how many macros can be made without eval .

+5
source

I agree with pst here, this code is pretty scary. This is terrible for readability. This is neat though:

  • f defined as a kind of placeholder function. It seems to be the macro itself; numeric variables will be replaced when they are calculated in g . They act as positional, variable arguments, which we will see below.
  • g where magic happens: the definition of the function f converted to a string, and the numeric variables in the macro definition of f replaced by references to the indexed arguments for the number of numeric variables that exist in the definition of f (hence the regular expression and call replace ). Underscore is used only because we don’t care about the first callback parameter for replace .
  • All this then eval ed, as soon as f expands substantially to the following:

     function () { return arguments[0] + arguments[1] } 

So, this is neat, since you can define f with as many positional numbers as the arguments you wanted:

 var f = function() { return $0 + $1 + $2 } 

and he will be rated as

 function() { return arguments[0] + arguments[1] + arguments[2] } 

Accurate but useless, possibly dangerous, impractical and difficult to read. I would probably never use it.

+5
source

Source: https://habr.com/ru/post/919074/


All Articles