我正在研究一些 JavaScript 代码,发现当我取出“console.dir”语句时,结果有所不同。调用 console.dir 后,某些属性似乎变得可见。例如,下面的代码将为 x1._rgbString 打印出“undefined”,但将为 x2._rgbString 打印出实际值。
var x1 = MochiKit.Color.Color.fromHexString("#ad3f40");
console.log(x1._rgbString);
var x2 = MochiKit.Color.Color.fromHexString("#ad3f40");
console.dir(x2);
console.log(x2._rgbString);
完整测试代码在这里:http://patorjk.com/misc/console-dir-test.htm
如果我在console.log(x1._rgbString)之前添加console.dir(x1),那么console.log(x1._rgbString)将开始打印出一个值,而不是打印出未定义的值。
为什么在对象上调用 console.dir 会影响对象上字段的值? console.dir 是否有副作用或者我在这里缺少什么?
*我知道下划线通常意味着私有(private),但我在记录这个值时感到惊讶,当 console.dir 没有第一次被调用时它开始显示为“未定义”。
最佳答案
原因是console.dir(以及console.log)对您传递给它的值调用toString()
。这通常不会产生副作用,但 Mochikit.Color.Color 的 toString() 又会调用 toRGBString()
。 toRGBString() 将其结果缓存在 this._rgbString
中:
toRGBString: function () {
var c = this.rgb;
var ccc = MochiKit.Color.clampColorComponent;
var rval = this._rgbString;
if (!rval) {
var mid = (
ccc(c.r, 255).toFixed(0)
+ "," + ccc(c.g, 255).toFixed(0)
+ "," + ccc(c.b, 255).toFixed(0)
);
if (c.a != 1) {
rval = "rgba(" + mid + "," + c.a + ")";
} else {
rval = "rgb(" + mid + ")";
}
this._rgbString = rval; // <-- _rgbString is set
}
return rval;
},
所以,并不是控制台函数有副作用,只是某些 toString() 实现可能有副作用。值得注意的是,一些 JS 最小化器(包括 Google Closure Compiler)假设 toString() 没有副作用,因此它们实际上可能会进行优化,从而对有副作用的代码产生影响。
在这种情况下,这不会成为问题,因为副作用只是缓存 - 只要您不在外部使用它 - 因此是“私有(private)”下划线。
关于javascript - console.dir 会对调用它的变量产生副作用吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9058493/