node.js - 为什么这个本地函数可以修改全局变量?

时间:2013-11-12 06:13:08

标签: node.js scope

这是我的代码:

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);

我第一次运行具有预期结果的代码;
  但是,当我第二次尝试运行该功能时,令我惊讶的是,c["beforeDNS"]的值意外地发生了变化!   事实上,我没有在我的函数中编写任何代码来修改这个全局变量的值,但它只是改变了   所以请帮我找到这个神秘结果的原因或者只是解决它。谢谢!

2 个答案:

答案 0 :(得分:1)

您的dup_condition变量没有重复任何内容。它只是对您传递的参数的引用。

因此,当您将其传递给im函数时,它会修改其参数,它只是引用和修改condition(它本身是对c["beforeDNS"]外部定义的引用功能)。

要解决此问题,您可以使用slice或更复杂的方法来实际填充参数。例如,slice将返回一个新数组。请注意,这只是一个浅表副本。该数组中的引用仍将引用相同的对象。

例如:

if (isArray(condition)) {
  var dup_condition = condition.slice();
  // ...
}

答案 1 :(得分:0)

在javascript中,对象通过引用传递。换句话说,handleCondition dup_condition仍然指向同一个数组。所以,如果你改变它,你实际上是在改变传递的对象。这是一个简短的例子,说明了同样的事情:

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);

脚本的结果是:

[10, 20]
[20, 30]

http://jsfiddle.net/3BK4b/