0

Here is my code:

var handleCondition = function(condition,params){
  var dup_condition;
  dup_condition = condition;

  var isArray = function(obj) {
    return Object.prototype.toString.call(obj) === '[object Array]';
  };

  var __replace = function(str){
    var reg_slot = /^#(.+)/;

    if(reg_slot.test(str) == true){
      var ss = reg_slot.exec(str)[1];
      return params[ss];
    }else{
      return str;
    }
  };

  var compare = function(a){
    var arr = a;
    if(params != undefined){
      for(var j =1;j<arr.length;j++){
        arr[j] = __replace(arr[j]);
      }
    }
    switch(arr[0]){
      case "$eq":
      case "==":
        return (arr[1] == arr[2]);
      default:
        return (arr[1] == arr[2]);
      }
    };

  if(isArray(dup_condition)){

    var im = function (arr){
      for(var i=0;i<3;i++){
        if(isArray(arr[i])){
          arr[i] = im(arr[i]);
      }
    }
    return compare(arr);
  };
  var res = im(dup_condition);
    return res;
  }
};

/*Here are test data*/
var c = {
  "beforeDNS":
  ["$eq","#host",["$eq",10,10]]
,
  "afterDNS":["$match",/^10\.+/,"#ip"]
};

var params ={
   host:"dd"
};

console.log(c["beforeDNS"]); // ==>  ["$eq","#host",["$eq",10,10]]
handleCondition(c["beforeDNS"],params);

console.log(c["beforeDNS"]);  // ==> ["$eq","dd",true]
handleCondition(c["beforeDNS"],params);

The first time I run the code with the expected result;
However , when I tried to run the function second time,to my surprise,the value of c["beforeDNS"] has changed unexpectedly!
In fact,I haven't write any code in my function to modify the value of this global variable,but it just changed.
So please help me find the reason of this mysterious result or just fix it.Thanks!

DemoHn
  • 23
  • 4

2 Answers2

1

Your dup_condition variable isn't duping anything. It's just a reference to the argument you pass in.

Thus when you pass it to the im function, which modifies its argument in place, it is just referencing and modifying condition (which is itself a reference to the c["beforeDNS"] defined outside the function).

To fix this you might use slice or some more sophisticated method to actually dupe the arguments. slice, for example, would return a new array. Note though that this is only a shallow copy. References within that array would still refer to the same objects.

For example:

if (isArray(condition)) {
  var dup_condition = condition.slice();
  // ...
}
numbers1311407
  • 33,686
  • 9
  • 90
  • 92
  • To my understanding, `var` means to init a new variable,therefore I think in this way a new variable is established.So can you explain what does `var` means actually in this example?Is it like a pointer? – DemoHn Nov 12 '13 at 07:11
  • A new variable is established, yes, but that variable is assigned a reference to an object. It's like a pointer in a sense, but refers to the object itself, not the memory address. There are a bunch of SO questions regarding this. Here's a starting point: http://stackoverflow.com/questions/10231868/pointers-in-javascript – numbers1311407 Nov 12 '13 at 07:36
0

In javascript the objects are passed by reference. In other words, in handleCondition dup_condition still points to the same array. So, if you change it there you are actually changing the passed object. Here is a short example which illustrates the same thing:

var globalData = {
    arr: [10, 20]
};

var handleData = function(data) {
    var privateData = data;
    privateData.arr.shift();
    privateData.arr.push(30);
}

console.log(globalData.arr);
handleData(globalData);
console.log(globalData.arr);

The result of the script is:

[10, 20]
[20, 30]

http://jsfiddle.net/3BK4b/

Krasimir
  • 13,306
  • 3
  • 40
  • 55