2

オブジェクト指向の観点から特定の問題にどのように取り組むかについて、概念的な質問があります(注:ここでの名前空間に関心がある人のために、私はGoogle Closureを使用しています)。私はOOPJSゲームにかなり慣れていないので、あらゆる洞察が役立ちます!

クラス名と一致するページ上の各DOM要素のカルーセルを開始するオブジェクトを作成するとします.carouselClassName

このようなもの

/*
 * Carousel constructor
 * 
 * @param {className}: Class name to match DOM elements against to
 * attach event listeners and CSS animations for the carousel.
 */
var carousel = function(className) {
  this.className = className;

  //get all DOM elements matching className
  this.carouselElements = goog.dom.getElementsByClass(this.className);
}

carousel.prototype.animate = function() {
  //animation methods here
}

carousel.prototype.startCarousel = function(val, index, array) {
  //attach event listeners and delegate to other methods 
  //note, this doesn't work because this.animate is undefined (why?)
  goog.events.listen(val, goog.events.EventType.CLICK, this.animate);
}

//initalize the carousel for each
carousel.prototype.init = function() {
  //foreach carousel element found on the page, run startCarousel
  //note: this works fine, even calling this.startCarousel which is a method. Why?
  goog.dom.array.foreach(this.className, this.startCarousel, carousel);
}

//create a new instance and initialize
var newCarousel = new carousel('carouselClassName');
newCarousel.init();

JSで初めてOOPをいじってみたところ、いくつかの観察を行いました。

  1. this.classname私のコンストラクターオブジェクト( )で定義されたプロパティはthis、他のプロトタイプオブジェクトの操作で利用できます。
  2. コンストラクターオブジェクトまたはプロトタイプで定義されたメソッドは、this.methodNameを使用して使用できません(上記のコメントを参照)。

これに対する私のアプローチに関する追加のコメントは間違いなく大歓迎です:)

4

2 に答える 2

2

Carouselページ上のすべてのカルーセルをオブジェクトで表さないようにすることをお勧めします。それぞれが の新しいインスタンスである必要がありますCarousel

this適切に割り当てられていないという問題thisは、コンストラクターでこれらのメソッドを「バインド」することで修正できます。

例えば

function Carousel(node) {
    this.node = node;

    // "bind" each method that will act as a callback or event handler
    this.bind('animate');

    this.init();
}
Carousel.prototype = {
    // an example of a "bind" function...
    bind: function(method) {
        var fn = this[method],
            self = this;
        this[method] = function() {
            return fn.apply(self, arguments);
        };
        return this;
    },

    init: function() {},

    animate: function() {}
};

var nodes = goog.dom.getElementsByClass(this.className),
    carousels = [];

// Instantiate each carousel individually
for(var i = 0; i < nodes.length; i++) carousels.push(new Carousel(nodes[i]));
于 2012-04-19T17:29:15.857 に答える
1

キーワードのリファレンスをthis見てください。オブジェクトからいずれかのメソッドを呼び出すとnewCarousel(例: newCarousel.init();)、thisinit メソッドでオブジェクトがポイントされます。その上でメソッドを呼び出す場合、それは同じです。

オブジェクト参照からいつでもプロパティを取得できます。これらのプロパティが関数であり、適切なコンテキストで (イベント ハンドラーなどから) 実行されない場合、それらはもはやthisを指しませんnewCarouselbind()それを回避するために使用します(forEach各呼び出しのコンテキストとして3番目のパラメーターを取るようです)。

于 2012-04-19T17:27:28.107 に答える