David David - 1 month ago 9
Javascript Question

How to change Bool value within a function in javascript?

Based on this tutorial: link

Here is my example code:

function modifyVar(obj, val) {
obj.valueOf = obj.toSource = obj.toString = function(){ return val; };
}

function setToFalse(boolVar) {
modifyVar(boolVar, 'false');
}

var isOpen = true;
setToFalse(isOpen);
console.log('isOpen ' + isOpen);


How can I change the bool variable value within a function?
Is it possible to pass the bool value by reference?
thanks in advance

Answer

Several problems there:

  1. 'false' is not false.

  2. Variables are passed by value in JavaScript. Always. So there is no connection whatsoever between the boolVar in setToFalse and the isOpen you're passing into it. setToFalse(isOpen) is processed like this:

    • The value of isOpen is determined

    • That value (completely disconnected from isOpen) is passed into setToFalse

  3. JavaScript has some interesting handling around primitive types: If you try to use them like object types (var a = 42; a.toFixed(2); for instance), the value gets promoted to a temporary object, that object is used, and then the object is discarded. So if obj is false, obj.anything = "whatever" ends up being a no-op, because the object that temporarily exists ends up getting released as soon as the line finishes.

You could do something like what you're doing by promoting isOpen to an object via new Boolean, but beware that it will then act like an object, not a boolean:

function modifyVar(obj, val) {
  obj.valueOf = obj.toSource = obj.toString = function(){ return val; };
}

function setToFalse(boolVar) {
  modifyVar(boolVar, false);
}

var isOpen = new Boolean(true); // An object
setToFalse(isOpen);
snippet.log('isOpen ' + isOpen);
<!-- Script provides the `snippet` object, see http://meta.stackexchange.com/a/242144/134069 -->
<script src="http://tjcrowder.github.io/simple-snippets-console/snippet.js"></script>

That works because the value in isOpen is a reference to an object. So when that value is passed into setToFalse as boolVar, boolVar's value is a copy of that reference, and so refers to the same object. So that sorts out issue #2 above. Issue #3 is solved by creating an object explicitly, rather than relying on the implicit behavior.

But, remember my warning above about how it will act like an object (because it is one), not like a boolean? Here's an example:

function modifyVar(obj, val) {
  obj.valueOf = obj.toSource = obj.toString = function(){ return val; };
}

function setToFalse(boolVar) {
  modifyVar(boolVar, false);
}

var isOpen = new Boolean(true); // An object
setToFalse(isOpen);
snippet.log('isOpen ' + isOpen);
if (isOpen) {
  snippet.log("isOpen is truthy, what the...?!");
} else {
  snippet.log("isOpen is falsey");
}
<!-- Script provides the `snippet` object, see http://meta.stackexchange.com/a/242144/134069 -->
<script src="http://tjcrowder.github.io/simple-snippets-console/snippet.js"></script>

We see:

isOpen false
isOpen is truthy, what the...?!

...because isOpen contains a non-null object reference, and non-null object references are always truthy.

Comments