Javascript 函数范围内声明的变量会导致if语句出错

Javascript 函数范围内声明的变量会导致if语句出错,javascript,scope,closures,var,Javascript,Scope,Closures,Var,因此,我在if语句var message和var body的回调函数中声明了两个变量。现在,当我运行代码时,当if语句命中else语句时,我得到错误,然后它抛出Uncaught TypeError:无法读取未定义的属性'parentNode' 在HTMLButtoneElement。 当我从声明中删除var关键字并全局声明它们时,不会出现错误。有什么问题?我认为javascript是函数作用域语言,而不是块作用域。即使在函数顶部的if语句之外声明这些变量也无济于事 代码: function cl

因此,我在if语句
var message
var body
的回调函数中声明了两个变量。现在,当我运行代码时,当if语句命中
else
语句时,我得到错误,然后它抛出
Uncaught TypeError:无法读取未定义的属性'parentNode'
在HTMLButtoneElement。
当我从声明中删除
var
关键字并全局声明它们时,不会出现错误。有什么问题?我认为javascript是函数作用域语言,而不是块作用域。即使在函数顶部的if语句之外声明这些变量也无济于事

代码:

function clickBtn() {
  var btn = document.getElementById("button");
  btn.addEventListener("click", function () {
    if (theName.value == "") {
      var message = document.createElement("p");
      message.className = "message";
      message.innerHTML = "You forgot the name and email";
      var body = document.getElementsByTagName("body")[0];
      body.appendChild(message);
    } else {

    message.parentNode.removeChild(message);
    var user1 = new User (theName.value, theEmail.value);
    users.push(user1);
    console.log(JSON.stringify(users, null, 2));
  }
    theName.value = "";
    theEmail.value = "";
  });
}
clickBtn();

只有当
if
值为
true
时,才能将某些内容分配给
消息

else
分支只有一个未定义的值
message
,这就是为什么会出现此错误

您可以通过声明
message
变量的值在
if/else
语句之外来解决此问题


似乎您希望在
if
中添加消息,并在
else
中删除它们-要做到这一点,您需要能够获得相同的消息。您所做的是每次创建一条新消息

下面是一个您可以执行的操作示例(基于您的代码):


只有当
if
值为
true
时,才能将某些内容分配给
消息

else
分支只有一个未定义的值
message
,这就是为什么会出现此错误

您可以通过声明
message
变量的值在
if/else
语句之外来解决此问题


似乎您希望在
if
中添加消息,并在
else
中删除它们-要做到这一点,您需要能够获得相同的消息。您所做的是每次创建一条新消息

下面是一个您可以执行的操作示例(基于您的代码):


如果if语句为true,则声明变量,如果为false,则引用它。声明var消息=。。。如果if语句为true,则声明变量;如果if语句为false,则引用该变量。声明var消息=。。。而不是在if语句之前,它应该可以工作

我认为javascript是函数作用域语言,而不是块作用域

现代代码看起来有点不同,它的目标是功能性风格和不可更改性。版本6中的ES-262也更高,因此希望仅使用const和let,并且为了将来与ES模块的兼容性,直接包括使用严格模式。 在将这些更正输入到代码中之后,阶段运行时的错误很可能会传递到编译时阶段。如果需要,最好解决功能关闭问题,而不是使用全局信息字段

我认为javascript是函数作用域语言,而不是块作用域

现代代码看起来有点不同,它的目标是功能性风格和不可更改性。版本6中的ES-262也更高,因此希望仅使用const和let,并且为了将来与ES模块的兼容性,直接包括使用严格模式。
在将这些更正输入到代码中之后,阶段运行时的错误很可能会传递到编译时阶段。如果需要的话,最好解决函数关闭问题,而不是使用全局信息字段。

Javascript有变量的概念。 Javascript实际上是函数范围的语言,而不是块范围的语言。 在您的情况下,
var message
var body
都被提升到函数的顶部,而没有被分配任何值(因此具有未定义的值)

它仅在if块中指定一个值,而在else块中未定义

“No var”将查找作用域链,直到找到变量或到达全局作用域(此时它将创建变量)。当您从声明中删除var关键字时,
var message
var body
将被全局声明,并按照赋值中的规定赋值。因此,它不会抛出错误


在全局范围内声明这些变量而不为其分配任何值会导致
var message
var body
在明确分配值之前未定义。因此else部分会抛出一个错误。

Javascript有一个变量的概念。 Javascript实际上是函数范围的语言,而不是块范围的语言。 在您的情况下,
var message
var body
都被提升到函数的顶部,而没有被分配任何值(因此具有未定义的值)

它仅在if块中指定一个值,而在else块中未定义

“No var”将查找作用域链,直到找到变量或到达全局作用域(此时它将创建变量)。当您从声明中删除var关键字时,
var message
var body
将被全局声明,并按照赋值中的规定赋值。因此,它不会抛出错误


在全局范围内声明这些变量而不为其分配任何值会导致
var message
var body
在明确分配值之前未定义。所以else部分抛出一个错误。

是的,关于变量是函数作用域而不是块作用域的说法是正确的。但是,Javascript仅在达到赋值指令时才为变量赋值。在您的例子中,您将赋值指令(
message=document.createElement(“p”);
)放在if中,这意味着在不满足条件时将不执行此指令。和Javascrip
function clickBtn() {
  var btn = document.getElementById("button");
  btn.addEventListener("click", function () {
    if (theName.value == "") {
      var message = document.createElement("p");
      message.className = "message";
      message.innerHTML = "You forgot the name and email";
      var body = document.getElementsByTagName("body")[0];
      body.appendChild(message);
    } else {
      message = document.getElementsByClassName("message")[0]; // first one
      message.parentNode.removeChild(message);
      var user1 = new User (theName.value, theEmail.value);
      users.push(user1);
      console.log(JSON.stringify(users, null, 2));
  }
    theName.value = "";
    theEmail.value = "";
  });
}
clickBtn();