【问题标题】:Javascript ES6 Classes - Method cant access class property defined inside class constructorJavascript ES6 类 - 方法无法访问在类构造函数中定义的类属性
【发布时间】:2018-12-18 14:36:05
【问题描述】:

所以我试图在一个类中构建我的代码,以便它可以更有条理,但我正在苦苦挣扎。我有代码:

class App {

  constructor() {

    // Get elements from DOM
    const titleBox = document.getElementById('titleBox');
    const navBox = document.getElementById('navBox');
    const navLinks = document.querySelectorAll('.header__listLink');
    const headerTitle = document.getElementById('headerTitle');
    const headerSubtitle = document.getElementById('headerSubtitle');
    const ulNav = document.getElementById('ulNav');
    const ulNavLinks = document.querySelectorAll('.ulNavLink');

    // for each nav link, add an event listener, expanding content area
    navLinks.forEach((link) => {
      link.addEventListener('click', this.clickedLinkState);
    });

  }

  clickedLinkState(e) {

      e.preventDefault();

      titleBox.classList.remove("header__title-box");
      titleBox.classList.add("header__title-box--linkClicked");

      headerTitle.classList.remove("header__title");
      headerTitle.classList.add("header__title--linkClicked");

      headerSubtitle.classList.remove("header__subtitle");
      headerSubtitle.classList.add("header__subtitle--linkClicked");

      ulNav.classList.remove("header__listInline");
      ulNav.classList.add("header__listInline--linkClicked");

      navBox.classList.remove("header__nav-box");
      navBox.classList.add("header__nav-box--linkClicked");

      ulNavLinks.forEach((navLink) => {
        navLink.classList.remove("header__listLink");
        navLink.classList.add("header__listLink--linkClicked");
      });   

  }

}

const app = new App();

我得到了错误:“main.js:40 Uncaught ReferenceError: ulNavLinks is not defined 在 HTMLLIElement.clickedLinkState (main.js:40)"。'ulNavLinks' 是一个 nodeList。

例如,我试图使用“this.titleBox = ...”来定义元素,但情况变得更糟,我无法通过 clickedLinkState 方法访问它。在课外它正在工作。

为什么我无法访问我的方法中的“ulNavLinks”?如果我将它们声明为“this.titleBox”、“this.navBox”,为什么我无法在方法中访问我的属性?

【问题讨论】:

  • 构造函数中声明的变量只是该函数的简单局部变量。它们不会隐含地成为对象属性;你必须通过在this 上创建属性来明确地做出这些。
  • 问题在于状态。试试 'link.addEventListener('click', this.clickedLinkState.bind(this))'

标签: javascript class ecmascript-6


【解决方案1】:

目前,在 JavaScript 中,实例属性只能在类方法中使用关键字 this (here is the doc) 定义。

还有一个支持公共/私有字段的experimental feature,由于浏览器支持不佳,您可能会在某些构建步骤中使用它。

【讨论】:

    【解决方案2】:

    请务必使用this:

    class App {
    
      constructor() {
    
        // Get elements from DOM
        this.titleBox = document.getElementById('titleBox');
        this.navBox = document.getElementById('navBox');
        this.navLinks = document.querySelectorAll('.header__listLink');
        this.headerTitle = document.getElementById('headerTitle');
        this.headerSubtitle = document.getElementById('headerSubtitle');
        this.ulNav = document.getElementById('ulNav');
        this.ulNavLinks = document.querySelectorAll('.ulNavLink');
    
        // for each nav link, add an event listener, expanding content area
        this.navLinks.forEach((link) => {
          link.addEventListener('click', this.clickedLinkState.bind(this));
        });
    
      }
    
      clickedLinkState(e) {
    
          e.preventDefault();
    
          this.titleBox.classList.remove("header__title-box");
          this.titleBox.classList.add("header__title-box--linkClicked");
    
          this.headerTitle.classList.remove("header__title");
          this.headerTitle.classList.add("header__title--linkClicked");
    
          this.headerSubtitle.classList.remove("header__subtitle");
          this.headerSubtitle.classList.add("header__subtitle--linkClicked");
    
          this.ulNav.classList.remove("header__listInline");
          this.ulNav.classList.add("header__listInline--linkClicked");
    
          this.navBox.classList.remove("header__nav-box");
          this.navBox.classList.add("header__nav-box--linkClicked");
    
          this.ulNavLinks.forEach((navLink) => {
            navLink.classList.remove("header__listLink");
            navLink.classList.add("header__listLink--linkClicked");
          });   
    
      }
    
    }
    
    const app = new App();

    【讨论】:

    • 谢谢。有效。所以我想问题是:我的方法“clickedLinkState”无法访问构造函数中声明的属性,当我们使用“this.clickedLinkState.bind(this)”时,“bind()”使我的方法成为可能访问这些属性,对吗?多谢你们。我学到了一些重要的东西。
    • 是的,bind(this) 返回一个调用您的函数但确保 this 是您传递给 bind 的值的函数
    猜你喜欢
    • 1970-01-01
    • 2019-05-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-12-17
    • 2016-10-09
    相关资源
    最近更新 更多