0

私はプロトタイプに不慣れで、うまくいかない簡単な例を作成しました。以下のコードから、私が欲しいのは明らかです-カウンター。しかし、何らかの理由で、出力は常にです。は、オブジェクトのディープコピーを作成している5と思います。これは、関数にバインドされます。私がすべてを公開する明らかな解決策がありますが、もっとエレガントな解決策があるかどうか知りたいです。(または、私の修正を行って、深いコピーはないが、他のバグがあると教えてください)。ドキュメントは私を助けませんでした。bindthis

コード:

<!DOCTYPE html>
<html>
    <body>
        <input type="button" value="click" onclick="javascript: doTest();" />
        <div id="canvas"></div>
        <script>
            var ClassA = function (position, element) { // constructor
              this.field1 = position;
              this.target = element;
            };

            ClassA.prototype = function () {
              // private functions
                var _aPrivateMethod = function(){
                    console.log(this);
                    this.field1 += 1;
                    return this.field1;
                };

                var _aPublicMethod = function(){
                    this.target.innerHTML = _aPrivateMethod.bind(this)();
                };

                return { // interface
                    constructor: ClassA,
                    aPublicMethod : _aPublicMethod
                };
            }();

            function doTest() {
                var obj = new ClassA(4, document.getElementById('canvas'));
                obj.aPublicMethod();
            }
        </script>
    </body>
</html>
4

1 に答える 1

1

ここにいくつかの問題があります。まず、doTest毎回電話します。クリックするたびに新しいオブジェクトが作成されるため、インクリメントする方法はありませんfield1

field1私が理解したように、あなたはプライベートになりたいです。初期化する方法では、プライベートにすることはできません。あなたは次のようなことをすることができます:

function Person() {
   var counter = 0;
   this.increment = function () {
       return ++counter;
   }
}

counterこのようにして、関数スコープの外部からにアクセスすることはできません。

もう1つの問題は、適切なコンテキストでプライベートメソッドを呼び出さないことです。_aPrivateMethod.call(this)pimvdbが述べたように使用する必要があります。

次に例を示します。

function Person() {

    var age = 0;

    function incrementAge() {
        return ++age;
    }

    function eatCake() {
        console.log('Yey. I\'ll eat cake!');
    }

    this.birthday = function () {
        eatCake();
        return incrementAge();
    }
}

var p = new Person();
p.birthday(); //'Yey. I'll eat cake!', returns 1
p.birthday(); //'Yey. I'll eat cake!', returns 2

このようeatCakeに、incrementAgeおよびageは機能範囲のためにすべてプライベートです。この例の悪い点は、関数を宣言した方法ですbirthdayPerson新しいコピーのインスタンスごとに作成されます。正しい方法は次のとおりです。

Person.prototype.birthday = function () { ... }

プライベートデータメンバーを使用したいので、私の宣言はこのようなものではありません。実際には、関数(、、)のローカルだけでプライベートではありませageん。プロトタイプで宣言されている関数からそれらにアクセスする方法はないので、上記の例ではそのアプローチを選択しました。eatCakeincrementAge

于 2012-11-27T13:33:36.390 に答える