5

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

1
  • No way. In javascript scalar parameters (such as boolean) are passed to function by value. So you cannot change external variable inside function. But you can return new value from the function and use it to change the variable outside of function Commented Nov 9, 2014 at 14:29

5 Answers 5

13

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.

Sign up to request clarification or add additional context in comments.

3 Comments

Great answer I learned a lot! But What I should do If I would like to check the isOpen value in the if statement?
Okey I find it... I need to use the valueOf() method in the if statement. thanks
What if you do it like var changeBool = function(obj,prop,value){ obj[prop] = value; } var sampleObj = {someBool : true}; changeBool(sampleObj,'someBool',false); console.log(sampleObj.someBool); Can someone compare the difference between the accepted and this?
9

We can use that.

var myBoolean = { value: false }

//get
myBoolean.value;

//set
myBoolean.value = true;

Comments

2

You are passing boolean primitive variable isObject. For primitive types it doesn't make sense to try to set toString method, because it's not needed (and used), since in ECMAScript spec there are already defined rules for to String conversion.

If you really want to use modifyVar function like you are trying, you can work with Boolean object instead of primitive:

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

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

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

So the answer: use new Boolean(true) or Object(true).

Comments

0

I had the same problem. You can solve that with returning an Object or an Array. In my case I used an Array. I did not had an second parameter for the function found, but if I did you see that it will return the changed value for found.

/**
 * error codes and messages
 * @param {string} statusMessage - message to check for error code
 */
 export default (statusMessage) => 
 {
    // list with error codes
    let errorCodes = [
      { code: "ECONNREFUSED", message: "Het lijkt erop dat de database niet actief is" },
      { code: "EADDRINUSE", message: "App is already running, kill this instance first!"}   
    ];

   // translate error message
   let found = false;
   errorCodes.forEach(err => {
      if (statusMessage.includes(err.code)) {
        statusMessage = err.message;
        found = true;
        return
      }
   })

   // return corresponding status message
   return [statusMessage, found];
 }

Comments

-2

I am not sure but you are assigning false in single quote, value withing single/double quotes will be considered as string. Just use modifyVar(boolVar, false); and try.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.