6

私は、javascript でクラスを作成するためのユーティリティに取り組んでいます。問題はプライベート属性を定義する方法です。

これがコードです

var OO = {

    Class:function(){

        var len = arguments.length;
        var data = arguments[len-1];



        var Klass;
        if (data.constructor === Object){
            Klass = function (){};

        } else {
            Klass = data.constructor;
            delete data.constructor;                
        }



        OO.extend(Klass.prototype,data); //Classic Extend Method


        return Klass;


    },
//Simple extend method, just what I need in this case
    extend: function(target, source){
            var prop;
            for (prop in source)
                target[prop] = source [prop];

    }
}

これが仕組みです

// first create a class
var person = OO.Class ({
constructor: function (name, age) {
this.name = name;
this.age = age;
},

name:'',
age:'',

getName: function () {
return this.name;
},

getAge: function () {
return this.age;
}

});

そして、これがインスタンスです

var one = new Person ('josh', 22);

そして問題:

one.age / / returns 22
one.name / / returns josh

私が必要としているのは、これらのプロパティが getName () や getAge () などのメソッドによってのみアクセスできることです。

EDIT1 : 拡張機能を追加

4

4 に答える 4

1

クロージャーはコンストラクターのパラメーターによって作成されるため、必要なのはこれだけです (AlienWebguy のコードを編集)。

var Person = function(name, age){

    this.getName = function() {
        return name;
    };

    this.getAge = function() {
        return age;
    };

};

var john = new Person('johnathan', 33);

document.writeln(john.name);        // undefined
document.writeln(john.age);         // undefined
document.writeln(john.getName());   // johnathan
document.writeln(john.getAge());    // 33
于 2012-09-07T04:27:38.897 に答える
0

更新 1:

これが実用的なプロトタイプです。を除いて動作します

1.) 構築値をプライベート メンバーに渡す。

 Dummy values do work however.

フィドルをテストします。

http://jsfiddle.net/UWRHP/11/

于 2012-09-06T22:52:38.563 に答える
-1

オブジェクトのインターフェースの一部である変数(つまりthis.x、およびthis.y)はすべてパブリックになります。これらの変数への外部アクセスへのアクセスを強制的にゲッター経由で実行することはできません。

したがって、次のようなコードがある限り、次のようになります。

getAge: function () {
    return this.age;
}

...これを防ぐことはできません:

var one = new Person ('josh', 22);
console.log(one.age);

DouglasCrockfordの記事JavaScriptのプライベートメンバーをチェックしてください。

于 2012-09-06T22:48:17.560 に答える
-1

@AlienWebguyが示唆するように、物事を複雑にしすぎないようにする(そしてこれまでに行ったことを完全に捨てる)ことを検討している場合は、メンバーさえ必要ありません-最終的にはandプロパティと.io同じくらい公開されます:.name.age

john.io.set('name', 'Johnny'); // still exposed!

最終的に、オブジェクトはおよびプロパティ.ioと同じように公開されるため、カプセル化も情報隠蔽も進歩しない複雑なソリューションになります。(すみません、@ AlienWebguy、それは私が感じる方法です).name.age

古典的な継承パラダイムを使用しようとしていて、従来の JavaScript OOP を完全に破棄する場合は、従来のコンストラクターとしての関数のパラダイムを破棄thisし、コンストラクターでの参照の使用を忘れてください。

// first create a constructor
var Person = function(arg0, arg1) {

    var that = {};

    // private variables

    var age = arg0;
    var name = arg1;

    // public methods

    that.getName = function() {
        return name;
    };

    that.getAge = function() {
        return age;
    };

    that.setAge = function(a) {
        age = a;
    };

    return that;

};

var john = new Person('johnathan', 33);

console.log(john.name);        // undefined
console.log(john.getName());   // 'johnathan'
console.log(john.age);        // undefined
console.log(john.getAge());   // 33
john.setAge(28);
console.log(john.getAge());   // 28
john.setName("Richard");      // Error - setName is not a function

これは Douglas Crockford のParasitic Inheritanceの例ですが、「継承」の部分はありません。要点は、インスタンス変数ageとインスタンス変数nameはプライベートですが、JavaScript の機能変数スコープによりスコープ内にとどまるため、オブジェクトのメソッドは引き続きそれらを操作できるということです。

nameまた、変数にはセッターがないことにも気付くでしょう。したがって、この手法を使用すると、name変数へのアクセスを正当に制御できます。隠し変数this.namethis.io変数の操作を許可するものはありません。それは完全にプライベートです。

于 2012-09-07T00:22:56.137 に答える