在javascript中,我有一个日志输出选项,允许使用元素/选择器指定输出日志/错误消息的位置。初始化时输出格式如下:
var $messageOutput = options.messageOutputElement ? $(options.messageOutputElement) : null;
以后通过日志函数使用它:
function outputMessage(msg)
{
if ($messageOutput !== null)
{
messageNum++;
var $messageOutput = $(options.messageOutputElement);
var html = $messageOutput.html();
html += '<b>' + messageNum + '</b><br/>' + msg + '<br/>';
$messageOutput.html(html);
$messageOutput.scrollTop($messageOutput[0].scrollHeight);
}
}
问题是即使$ messageOutput === null,outputMessage()内的if语句也会失败。我已经与Chome的调试器验证了$ messageOutput确实等于null。事实上它无论如何都会进入if语句。
任何人都可以告诉我为什么会发生这种情况吗?提前感谢您对此事的任何意见。
答案 0 :(得分:5)
通过在函数范围内声明“var $ messageOutput”,可以停止引用全局范围中的变量。因此,它不是指代那个,而是指一个尚未在函数体中设置的变量,它是未定义的,而不是null。您应该删除“var $ messageOutput = $(options.messageOutputElement);”中的“var”部分,这将使函数引用函数外部的$ messageOutput。
详细说明: “var”在你所在的范围内创建一个新变量,并且增加了混乱,比如“var foo = function”的行为与“function foo”的行为不同。这里有一些有趣的案例&amp;解释你的阅读乐趣:
var x = 5;
function f () {
console.log(x):
if (!x) {
var x = 22;
}
return x;
}
function g () {
console.log(x):
if (!x) {
x = 22;
}
return x;
}
f(); // prints nothing, and returns 22
g(); // prints 5, and returns the same value
您有时需要注意的是,您可以在全局范围之外的声明之前引用函数,具体取决于声明的方式。例如:
function f () {
console.log(f_sub);
function f_sub () {
return "subfunction of f";
}
return f_sub;
}
function g() {
console.log(g_sub);
var g_sub = function () {
return "subfunction of g";
}
return g_sub;
}
f(); // prints and returns f_sub
g(); // prints undefined and returns g_sub
传统的函数声明可以在任何地方进行,并在任何地方引用,但是将函数赋值给变量意味着在行执行之前不能引用它。