是否可以将对象传递给eval / setTimeout函数?

时间:2011-10-22 10:34:46

标签: javascript

使用setTimeout;

将对象传递给函数时遇到了麻烦
function alertObject(obj){
   alert(obj); //This is supposed to display "[object Object]"
}

function startCountdown(){
   var myObj = new myClass();
   setTimeout("alertObject("+ myObj +")",1000);
}

startCountdown();

当我运行此操作时,出现“意外标识符”错误。我知道我可以使用这样的匿名函数;

setTimeout(function(){alertObject(myObj)},1000);

而不是

setTimeout("alertObject("+ myObj +")",1000);

但问题是我想知道为什么你不能使用eval()函数传递一个对象。它适用于字符串......

5 个答案:

答案 0 :(得分:2)

您无法在保持对象身份的同时序列化对象。 (使用任何语言,而不仅仅是JavaScript。)

'alertObject('+myObj+')'涉及将对象转换为包含toString()的字符串,从而导致alertObject([object Object])显然无效的JavaScript。

您可以提供一个返回有效JavaScript的toString()实现,并使用它来创建一个类似原始对象的新对象:

function myClass(num) {
    this.num= num;
}
myClass.prototype.toString= function() {
    return 'new myClass('+this.num+')';
};

var a= new myClass(3);
var b= eval(''+a);     // 'new myClass(3)'
alert(a.num===b.num);  // true

但它不是同一个对象实例:

alert(a===b); // false

并且没有办法获得实际的原始对象,例如,保持查找对象的每个实例,并将密钥传递给该查找。

隐藏字符串中的代码很糟糕。这是您永远不应将setTimeout与字符串参数一起使用的原因之一。去传递函数对象。

答案 1 :(得分:1)

你可以这样写:

setTimeout(alertObject,1000,myObj);

或者像这样:

setTimeout("alertObject(myObj)",1000);

在您的示例中,myObj被序列化为无法运行的"alertObject([Objecct object])"

答案 2 :(得分:0)

setTimeout("alertObject("+ myObj +")",1000);

相同
setTimeout("alertObject("+ ..object converted to string.. +")",1000);

setTimeout("alertObject([object Object])",1000);

,而

  "alertObject([object Object])"

无效Javascript,因此出现错误消息。

答案 3 :(得分:0)

这是因为该对象仅存在于函数内部。

setTimeout中的回调代码将在全局范围(即window)中调用,而不是在函数范围内调用。由于myObj是函数内部的局部变量,因此在全局范围内不可用。

如果您在全局范围内声明变量,它将在您的函数结束时继续存在,并且可以从回调代码中访问它。

请注意,您应该在代码中使用变量的名称,而不是将变量的值连接到字符串中。如果你这样做,你最终会得到像"alertObject([Objecct object])"这样的东西,当然不能运行。

var myObj;
function startCountdown(){
  myObj = new myClass();
  setTimeout("alertObject(myObj)",1000);
}

答案 4 :(得分:0)

setTimeout(function() {
    alertObject(object);
}, 1000);

我认为这就是你所需要的。

相关问题