在函数作用域内声明的变量会导致if语句出错

时间:2017-05-02 11:12:05

标签: javascript scope closures var

所以我在if语句0 -> c va OR dq -> v NOT cx -> dr kk RSHIFT 3 -> km NOT cx -> dq 3 AND v -> fx lf RSHIFT 2 -> lg var message中的回调函数中声明了两个变量现在当我运行代码时,if语句命中var body语句然后它抛出时我得到错误出else 当我从声明中删除Uncaught TypeError: Cannot read property 'parentNode' of undefined at HTMLButtonElement.<anonymous>关键字并在全局声明它时,我没有错误。问题是什么?我的javascript是函数范围语言,而不是块范围。即使在函数顶部的语句中声明它们变量也没有帮助。

代码:

var

5 个答案:

答案 0 :(得分:2)

message值为if时,您只会向true分配内容。

else分支只有message的未定义值,这就是您收到此错误的原因。

您可以通过声明message变量的值超出if/else语句来解决此问题。

似乎您想要if中的添加消息并在else删除 - 为此,您需要能够获得相同的消息。您正在做的是每次都创建新消息

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

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

答案 1 :(得分:0)

如果if语句为true,则声明变量,但如果为false,则引用它。在if语句之前声明var message = ...而它应该可以工作。

答案 2 :(得分:0)

  

我认为javascript是函数范围语言,而不是块范围

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

答案 3 :(得分:0)

Javascript有一个变量hoisting的概念。 Javascript确实是函数范围的语言,而不是块作用域。 在您的情况下,var messagevar body都会被提升到函数顶部,而不会被赋予任何值(因此值为undefined)。

仅在if块中为其分配值,并且对于else块未定义。

&#34;没有var&#34;将查找范围链,直到找到变量或命中全局范围(此时它将创建它)。从声明中删除var关键字时,var messagevar body将全局声明,并且还会分配赋值中提供的值。因此它不会引发错误。

在全局范围内声明这些变量而不为它们分配任何值会导致var messagevar body未定义,直到明确赋值。因此,其他部分会抛出错误。

答案 4 :(得分:0)

是的,关于变量是函数范围而不是块范围,你是正确的。但是,Javascript只会在达到赋值指令时为您的变量赋值。在你的情况下你把赋值指令(message = document.createElement("p");)放在里面,如果这意味着当条件不满足时不会执行该指令。并且Javascript被挂起,这意味着它将所有变量的声明(并且仅声明)移动到函数的顶部。因此,message的声明已移至函数顶部并保持undefined,当您尝试访问.parentNode时,您将收到错误,因为undefined没有属性。有关详情,请查看此内容:https://scotch.io/tutorials/understanding-hoisting-in-javascript