我应该如何定义我的构造函数(JS)

时间:2018-03-06 10:12:00

标签: javascript

目前我的构造函数已经像这样定义并正在工作:

function Carousel(parent, currentItem, count) {
    var element = parent;
    var count = count;
    var arrPrev = document.createTextNode('‹');
    var arrNext = document.createTextNode('›');
    var cPrevClass = 'cPrevClass';
    var cNextClass = 'cNextClass';
    var crslClass = 'js-Carousel';
    var current = currentItem;

    showArrows();

    /**
    * Create the navigation arrows (prev/next) and attach to carousel.
    */
    function showArrows() {
       // stuff here
       // Event listener (important for my question)
        buttonPrev.addEventListener('click', showPrev);
        buttonNext.addEventListener('click', showNext);
    }
}

因为当时我不知何故忘记我应该使用this关键字来定义我的类构造函数(我猜),我现在已经重写了这样:

function Carousel(parent, currentItem, count) {
    this.element = parent;
    this.count = count;
    this.current = currentItem;
    this.showArrows = showArrows;
    this.showArrows();
}

/**
 * Create the navigation arrows (prev/next) and attach to carousel.
 */
function showArrows() {
    // stuff here...
    var modal = document.getElementById("netreviews_media_modal");

    // then adding event listener
    buttonPrev.addEventListener('click', showPrev);
    buttonNext.addEventListener('click', showNext);

    modal.appendChild(buttonPrev);
    modal.appendChild(buttonNext);
}

/**
 * Go back
 */
function showPrev() {
    if (Carousel.current == 0) {
        Carousel.current = Carousel.count - 1;
    }
    else {
        Carousel.current = Carousel.current - 1;
    }
    updateModal(element.querySelectorAll('.' + crslClass + ' > ul li > a')[Carousel.current]);
}

现在当updateModal()函数正在运行时(请参阅文件末尾),我发出错误信息告诉我"无法读取属性' querySelectorAll'未定义" 当然,element已不再定义,只是说“未定义”。

我不知道如何将element指向我的班级财产。此外,Carousel.current也不起作用。而且我不知道我是否做了很好的重构。我还没有把所有代码(//这里的东西)放进去,但我觉得它足够...... (仅供参考我稍后在代码中实例化我的Carousel功能) 任何帮助表示赞赏!

3 个答案:

答案 0 :(得分:1)

您在showPrev函数中使用了Carousel,但Carousel不是一个对象,它是一个类。

function MyClass(arg1)
{
    this.myProperty = arg1;
}

// If you want your class to inherit
MyClass.prototype = Object.create(MyParentClass.prototype);

MyClass.prototype.myMethod = function ()
{
    // You can use this inside a method
    console.log(this.myProperty);
};

MyClass.MyStaticProperty = 42;
MyClass.MyStaticMethod = function ()
{
    // You can't use this here
};

const myObject = new MyClass("Hello, World");
myObject.myMethod();

替换" Carousel"通过"这个"并将该方法附加到类原型。 然后将你的班级变成一个对象。

答案 1 :(得分:1)

有两种方法可以做到这一点,最好的方式是es6ECMAScript2015。只需像这样创建一个类:

class Foo {
  constructor(bar) {
    this.bar = bar
  }

  baz() {
    console.log(this.bar) // prints Hello world
  }
}

const foo = new Foo('Hello world') // your instance
foo.baz()

另一种方式是' old'通过创建一个函数,你很接近。但是有一个问题;

function Foo(bar) {
  this.bar = bar;

  this.baz = function() {
    console.log(this.bar) // this would point to the anonymous function scope, not the class scope, so this.bar would be undefined
  }
}

const foo = new Foo('Hello world') // your instance
foo.baz() // throws an error

如评论中所述,this不是类或Foo范围,而是匿名函数的范围。我通常如何解决这个问题,就是使用自执行匿名函数。现在this范围已保存在self中,您可以像这样使用它;

function Foo(bar) {
  this.bar = bar;

  this.baz = (function(self) {
    return function() {
      console.log(self.bar); // prints Hello world
    }
  })(this);
}

const foo = new Foo('Hello world') // your instance
foo.baz() // all good

正如@Kulvar指出的那样,将this存储在常量/变量中也是可能的(并且可能更高效)。我个人并不喜欢这种方法,感觉有点hacky;

function Foo(bar) {
  this.bar = bar;

  var self = this;

  this.baz = function() {
    console.log(self.bar) // note the use of `self` instead of `this`
  }
}

const foo = new Foo('Hello world') // your instance
foo.baz() // all good

答案 2 :(得分:1)

要将其转换为实际的类,它必须看起来像这样。

您将在底部看到我有一个变量,该变量是该类的一个实例,您可以使用它来调用此变量carousel.showPrev()上的函数,例如可以从类外部调用。

class carouselClass {
  constructor(parent, currentItem, count) {
    this.element = parent;
    this.count = count;
    this.arrPrev = document.createTextNode('‹');
    this.arrNext = document.createTextNode('›');
    this.cPrevClass = 'cPrevClass';
    this.cNextClass = 'cNextClass';
    this.crslClass = 'js-Carousel';
    this.current = currentItem;

    this.showArrows();
  }

  // Create the navigation arrows (prev/next) and attach to carousel.
  showArrows() {
    // stuff here...
    let modal = document.getElementById("netreviews_media_modal");

    // then adding event listener
    buttonPrev.addEventListener('click', this.showPrev);
    buttonNext.addEventListener('click', this.showNext);

    modal.appendChild(buttonPrev);
    modal.appendChild(buttonNext);
  }

  // Go back
  showPrev() {
    if (this.current == 0) {
      this.current = this.count - 1;
    } else {
      this.current--;
    }
    updateModal(this.element.querySelectorAll('.' + this.crslClass + ' > ul li > a')[this.current]);
  }
}

let carousel = new carouselClass('parent', 'currentItem', 'count');

以下是further reading

我希望你觉得这很有用。