Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Use variable by reference in arrow function

PHP 7.4 introduced Arrow functions. And it also introduced implicit by-value scope binding which eliminate the need for use keyword.

Now if we want to use a variable out of a closure's scope by reference with a regular anonymous function we would do this:

$num = 10;
call_user_func(function() use (&$num) {
$num += 5;
});
echo $num; // Output: 15

But using an arrow function it seems impossible

$num = 10;
call_user_func(fn() => $num += 5);

echo $num; // Output: 10

So how to use $num variable by reference?

like image 587
Rain Avatar asked Nov 28 '19 06:11

Rain


People also ask

How do you pass parameters in arrow function?

The arrow function can be shortened: when it has one parameter you can omit the parentheses param => { ... } , and when it has one statement you can omit the curly braces param => statement . this and arguments inside of an arrow function are resolved lexically, meaning that they're taken from the outer function scope.

What does () => mean in JavaScript?

It's a new feature that introduced in ES6 and is called arrow function. The left part denotes the input of a function and the right part the output of that function.

Can we use arguments object in arrow function?

Arrow functions do not have an arguments binding. However, they have access to the arguments object of the closest non-arrow parent function. Named and rest parameters are heavily relied upon to capture the arguments passed to arrow functions.

Can we use call apply bind on arrow functions?

Arrow functions don't have their own bindings to this , arguments or super , and should not be used as methods. Arrow functions don't have access to the new. target keyword. Arrow functions aren't suitable for call , apply and bind methods, which generally rely on establishing a scope.


2 Answers

Reading the documentation about it, it says...

By-value variable binding
As already mentioned, arrow functions use by-value variable binding. This is roughly equivalent to performing a use($x) for every variable $x used inside the arrow function. A by-value binding means that it is not possible to modify any values from the outer scope:

$x = 1; 
$fn = fn() => $x++; // Has no effect 
$fn(); 
var_dump($x); // int(1)

So it is not possible ATM.

like image 99
Nigel Ren Avatar answered Oct 21 '22 15:10

Nigel Ren


You can use an object to do this.

$state = new stdClass; 
$state->index = 1;

$fn = fn() => $state->index++; // Now, has effect.
$fn();

var_dump($x); // int(2)

It works because objects always pass by reference. I don't encourage you to use this but in some places it's useful.

like image 20
Mahdi Aslami Khavari Avatar answered Oct 21 '22 15:10

Mahdi Aslami Khavari