JavaScript:属性函数是否悬空?

时间:2018-05-29 23:13:49

标签: javascript

我试图理解为什么以下代码有效:

function checkReading () {
  if (checkReading.read) {
    return; 
  }
  checkReading.read = this.scrollHeight - this.scrollTop === this.clientHeight;
  document.registration.accept.disabled = document.getElementById("nextstep").disabled = !checkReading.read;
  checkReading.noticeBox.innerHTML = checkReading.read ? "Thank you." : "Please, scroll and read the following text.";
}
  

来源:https://developer.mozilla.org/en-US/docs/Web/API/Element/scrollHeight

我正在努力解决的问题是在if(checkReading.read)函数对象上声明checkReading.read属性之前如何调用checkReading

这是否有效的原因是函数声明,即使直接作为属性(如上所述)完成,也会被提升到其范围的顶部?

因此,在JS引擎完成事件循环的第一个滴答之后,checkReading.read实际上被提升(移动)到checkReading函数的顶部?

PS:我知道正常的函数声明被挂起function foo() {..}到其作用域的顶部,但不确定是否也适用于上述属性。

2 个答案:

答案 0 :(得分:2)

  

我正在努力解决的问题是在if(checkReading.read)函数对象上声明checkReading.read属性之前如何调用checkReading

这与功能或吊装无关。您可以访问任何对象上的不存在的属性:



var foo = {};
console.log(foo.bar);




如果该属性不存在,则其返回值为undefined,强制为false

  

我实际上考虑过伪造的概念,但接下来的代码永远不会到达。或者我错过了什么?

如果条件为false,则if语句的正文执行,即return;未执行,因此剩下的该功能已被执行。

答案 1 :(得分:2)

问题不在于提升,而在于在这些不同情况下访问未初始化的值时会发生什么。

如果您在读取之前从未声明变量,则会出现ReferenceError:

if (a) { foo(); }  // ReferenceError thrown
let a;

......除非它是varfunction,否则适用吊装:

function home() {
    if (a || b()) { foo(); }
    var a;
    function b() {}
}

但是,对象属性访问是不同的。对象属性访问永远不会抛出ReferenceError。对象属性也无法声明,实际上 - 它们只是被创建/修改/用作对象的一部分。

if (!a.foo) { a.foo = new Foo(); }
// Use a.foo