原型中的函数方法未定义[重复]

问题描述 投票:0回答:1

我计划摆脱 jQuery,只是为了学习更多纯 javascript 来构建我自己的库。我创建了类似于 jQuery 的 $. 我选择的第一个原型方法是 _addClass,它实际上将一个类添加到 DOM 元素;

Html代码很简单:

(() => {
    function __(arg) {
        if (!(this instanceof __))
            return new __(arg);
        this.element = null;
        this.elements = null;
        this.singleElement = false;
        switch (arg.substring(0, 1)) {
            case ".":
                this.elements = document.getElementsByClassName(arg.substring(1));
                break;
            case "#":
                this.element = document.getElementById(arg.substring(1));
                this.singleElement = true;
                break;
            case "&":
                this.elements = document.getElementsByName(arg.substring(1));
                break;
            default:
                this.elements = document.querySelectorAll(arg);
                break;
        }
        return this;
    }

    __.prototype._addClass = (a) => {
        if (this.singleElement) {
            this.element.classList.add(a);
            return this.element;
        } else {
            this.elements.forEach((element) => element.classList.add(a));
            return this.elements;
        }
    }

    document.getElementById("btn").addEventListener("click", () => {
        __("#test")._addClass("new-class-style");
    })
})();
<div id="test">Div content</div>
<button id="btn">Button</button>

但是,我收到错误消息:

未捕获的类型错误:无法读取未定义的属性(读取“classList”)

指向

this.element
this.elements
this.singleElement
是未定义的,我就是不明白为什么?

javascript prototype
1个回答
1
投票

那是因为您在

_addClass
方法中使用了箭头函数,所以
this
关键字变成了
undefined
。将其改回正常功能可解决问题:

 (() => {
        function __(arg) {
          if (!(this instanceof __)) return new __(arg);
          this.element = null;
          this.elements = null;
          this.singleElement = false;
          switch (arg.substring(0, 1)) {
            case '.':
              this.elements = document.getElementsByClassName(arg.substring(1));
              break;
            case '#':
              this.element = document.getElementById(arg.substring(1));
              this.singleElement = true;
              break;
            case '&':
              this.elements = document.getElementsByName(arg.substring(1));
              break;
            default:
              this.elements = document.querySelectorAll(arg);
              break;
          }
          return this;
        }

        __.prototype._addClass = function (a) {
          if (this.singleElement) {
            this.element.classList.add(a);
            return this.element;
          } else {
            this.elements.forEach((element) => element.classList.add(a));
            return this.elements;
          }
        };

        document.getElementById('btn').addEventListener('click', () => {
          __('#test')._addClass('new-class-style');
        });
      })();
    <div id="test">Div content</div>
    <button id="btn">Button</button>

© www.soinside.com 2019 - 2024. All rights reserved.