6

Lightbox2を使用しています

https://github.com/lokesh/lightbox2/blob/master/js/lightbox.js

Lightbox.prototype.initそして、ライトボックスのすべての内部メンバーが単にメンバー()ではなくプロトタイプ化されている()理由がわかりませんLightbox.initか?

それらがライトボックスの各インスタンスに固有である場合、使用する方が簡単ではないでしょうthis.initか。

4

2 に答える 2

8

混乱している?しないでください...

このように考えてください:

  1. ライトボックスはクラス定義ですが、まだインスタンスではありません。

  2. クラスに直接配置するものはすべて、静的メンバーのようなものです。

    Lightbox.staticFunc = function() {
        // "this" will not point to instance object
    };
    
  3. プロトタイプに配置するものはすべて、共有インスタンスメンバーです。

    Lightbox.prototype.instanceFunc = function() {
        // "this" will point to object instance so members can be accessed
    };
    
  4. クラスのインスタンスを作成すると、すべてのインスタンスメンバーはthisキーワードを介してアクセスできますが、静的メンバーはクラス定義を介してアクセスできます。

    var someData = Lightbox.staticFunc();
    var l = new Lightbox();
    l.instanceFunc();
    

これにより、プロトタイプメンバーの理解が明確になりますか?

次にライトボックスコード

あなたが見ているコードはこれを意味します:

// this is a constructor that accesses instance properties (using "this")
// ------
// since properties are accessed via "this.something" means that they are
//    not shared between instances but are part of one particular instance
// ------
function Lightbox(options) {
    this.options = options;
    this.album = [];
    this.currentImageIndex = void 0;
    this.init();
}

// adding an instance method that will be accessible to lightbox object instance
//    that's why it can also access instance members (using "this")
// ------
// all functions that are defined on the prototype are shared between
//    all instances so they consume less resources because not every
//    object instance created them separately.
// ------
Lightbox.prototype.init = function() {
    this.enable();
    return this.build();
};

しかし、このコードのいくつかの部分は少し混乱しています。

LightboxOptions = (function() {

    function LightboxOptions() {
        this.fileLoadingImage = 'images/loading.gif';
        this.fileCloseImage = 'images/close.png';
        this.resizeDuration = 700;
        this.fadeDuration = 500;
        this.labelImage = "Image";
        this.labelOf = "of";
    }

    return LightboxOptions;

})();

LightboxOptionsクラスはプライベートデータを定義していなくても関数クロージャ内に含まれているため、この例では、同じ結果を得ながら、すぐに実行される外部関数を省略できます。

LightboxOptions = function() {
    this.fileLoadingImage = 'images/loading.gif';
    this.fileCloseImage = 'images/close.png';
    this.resizeDuration = 700;
    this.fadeDuration = 500;
    this.labelImage = "Image";
    this.labelOf = "of";
};

もちろん、を使用してコンストラクターでこれらの関数を定義することは可能ですがthis、インスタンス間で共有されないため、すべてのオブジェクトインスタンスが同じ関数を定義するため、より多くのリソースを消費します。したがって、これは同じではありませんが、実行ポイントからは同じように見えます。

CustomClass = function() {
    this.prop = true;
};
CustomClass.prototype.method = function() { alert("I'm shared."); };

とは少し異なります:

CustomClass = function() {
    this.prop = true;
    this.method = function() { alert("I'm duplicated in every instance."); };
};

後者は、すべてのオブジェクトインスタンスに対して関数が定義されている間、より多くのリソースを消費します。

...そしてこのことを完全にクリアするためにもう少し

次のクラス定義があるとします。

var C = function() {
    this.prop = true;
    this.method = function() { console.log("Per instance method"); };
}
C.prototype.method = function() { console.log("Shared instance method"); };

これらのコード行を呼び出すと、ここで何が起こりますか

var a = new C();
var b = new C();
a.method();
b.method();
delete a.method;
a.method();
b.method();

出力はどうなると思いますか?あなたは後に何が起こるか少なくとも少し混乱するはずdeleteですか?どのメソッドが削除されますか?インスタンスごとに?共有しますか?両方?インスタンスごとにメソッドがオブジェクトインスタンスで削除されるはずですがa、そのため、後で共有メソッドが呼び出されたことが報告されます。しかし、のみabまだインスタンスごとの独自のメソッドがあります。

したがって、これ以上面倒なことをしなければ、出力は次のようになります。

Per instance method      // a.method
Per instance method      // b.method
Shared instance method   // a.method
Per instance method      // b.method

prototypeプロパティはどうですか

これらは異なります。オブジェクトインスタンスを作成すると、これらのプロパティはすべてすべてのオブジェクトにコピーされ、共有されません。したがって、特定のオブジェクトの領域内でそれらに対して行うことは、他のオブジェクトに反映されません。

次に、特定のオブジェクトでそのようなプロパティを削除すると、オブジェクトがインスタンス化されたときの初期値で引き続き使用できます。

var C = new function() {};
C.prototype.prop = 1;

var a = new C();
var b = new C();

a.prop = 10;   // does not change the value of "b.prop"
delete a.prop; // "a.prop" is now back to 1
于 2012-06-09T10:34:27.553 に答える
4

それらがライトボックスの各インスタンスに固有である場合、this.initを使用する方が簡単ではないでしょうか。

彼らはそうあるべきではありません。それが彼らがすべてをprototypeオブジェクトに入れている理由です。を使用するprototypeと、すべてのメソッドが引き続き使用可能になりますが、インスタンスメンバーにはなりません。

JavaScriptはプロトタイプチェーンで動作し、メソッドを検出すると、指定されたメソッドが見つかるまでプロトタイプチェーンを検索します。このプロセスはObject、途中で見つからない場合は最終オブジェクトまで続きます。

インスタンスメンバーなどのキーワードthisを使用して不要なメソッドを配置するとオーバーヘッド(計算の無駄)が追加されるため、合理的または必要と思われるインスタンスメンバーのみを(経由で)作成する必要があります。this

于 2012-06-09T10:28:33.797 に答える