4

現在、私は構造(通常の関数)を宣言することによってjavascriptでオブジェクトを作成し、次にそのようにプロトタイプにメソッドを追加します

function Test(){
}
Test.prototype.test1 = function(){
    var me = this;
}

var me = thisただし、すべての関数の先頭で宣言する必要はありません。以下は機能しているようですが、非常に非効率的であるようです。

$(document).ready(function(){
var n = 0;
(function(){

     function createTest(){
        var me;
        function Test(){
            this.n = n;
            this.testArr = [1, 2, 3, 4];
            n++;
        }

        Test.prototype.test1 = function(){
            me.test2();
        };
        Test.prototype.test2 = function(){
            alert(me.n);
            $.getJSON('test.php', {}, function(reply)
                //want to be able to use 'me' here
                me.newField = reply;
            });
        };

        var t = new Test();
        me = t;
        return t;
    }
    window['createTest'] = createTest;
})();

var t = createTest();
t.test1();
var t2 = createTest();
t2.test1();
t.test1();
});

このコードは期待値を出力しますが、実際には見た目と同じくらい非効率的ですか(createTest()を呼び出すたびにTestオブジェクトが再宣言されます)?

とにかく、これは少しハッキーに見えるでしょう...これを行うための完全に異なる方法がありますか?

編集:私がこれをしたい本当の理由は、test2のようなコールバックが正しいへの参照を持つようにするためthisです。

4

3 に答える 3

2

あなたの質問はjQueryでタグ付けされていませんが、あなたはあなたの例でそれを使用しているので、私のソリューションもjQueryを利用しています。

$.proxyコールバックコンテキストを回避するために関数を使用することがあります。この単純なjsfiddleの例を見てください。以下のソース。

function Test(){
    this.bind();
}

Test.prototype.bind = function(){
    $('input').bind('change', $.proxy(this.change, this)); 
    // you could use $.proxy on anonymous functions also (as in your $.getJSON example)
}
Test.prototype.change = function(event){ 
    // currentField must be set from e.target
    // because this is `Test` instance
    console.log(this instanceof Test);          // true
    console.log(event.target == $('input')[0]); // true
    this.currentField = event.target;           // set new field
};

function createTest(){
    return new Test();
}

$(function(){ // ready callback calls test factory
    var t1 = createTest();
});
于 2011-03-15T21:29:32.413 に答える
2

できることは、現在のthis値を a にバインドしfunction、コピーをどこかに保存することです。(効率のために。)

if (!Function.prototype.bind) {
    // Most modern browsers will have this built-in but just in case.
    Function.prototype.bind = function (obj) {
        var slice = [].slice,
            args = slice.call(arguments, 1),
            self = this,
            nop = function () { },
            bound = function () {
                return self.apply(this instanceof nop ? this : (obj || {}),
                                    args.concat(slice.call(arguments)));
            };
        nop.prototype = self.prototype;
        bound.prototype = new nop();
        return bound;
    };
}

function Test(n) {
    this.n = n;
    this.callback = (function () {
        alert(this.n);
    }).bind(this)
}

Test.prototype.test1 = function () {
    this.test2();
}

Test.prototype.test2 = function () {
    doSomething(this.callback);
}

function doSomething(callback) {
    callback();
}

var t = new Test(2);
t.test1();
于 2011-03-15T20:37:26.077 に答える
0

ほとんどの場合、コールバックで this への参照が必要な場合は常に、これを参照するローカル変数を宣言するだけです。

function Foo() {
}

Foo.prototype.bar = function() {
  var that=this;
  setTimeout(function() {
     that.something="This goes to the right object";
  }, 5000);
}

または、次のように bind() を使用できます。

Function Foo() {
   this.bar = this.bar.bind(this);
   // ... repeated for each function ...
}

Foo.prototype.bar = function() {
}

これにより、新しい Foo インスタンスを作成するたびに、メソッドが現在のインスタンスにバインドされるため、setTimeout() などのコールバック関数として使用できるようになります。

于 2011-03-15T23:37:18.207 に答える