42

私は最近、JavaScript でゲッター/セッターを定義できる可能性があるという事実について読みました。非常に役立つようです。セッターは、実際に設定する前に、最初に設定する値を解析できる一種の「ヘルパー」です。

たとえば、現在次のコードがあります。

var obj = function(value) {
    var test = !!value; // 'test' has to be a boolean
    return {
        get test() { return test },
        set test(value) { test = !!value }
    };
};

var instance = new obj(true);

valueこのコードは常にブール値に変換されます。したがって、コーディングするinstance.test = 0と、instance.test === false.

ただし、これが機能するには、実際にobjectを返す必要があります。つまり、新しいインスタンスは型ではなくobj、単なるオブジェクトです。これは、 のプロトタイプを変更しobjてもインスタンスには影響しないことを意味します。たとえば、これは機能しませ-instance.func未定義です:

obj.prototype.func = function() { console.log(this.value); };

instance型ではありませんのでご了承objください。プロトタイプ関数を機能させるには、通常のコンストラクターが機能するように、単純なオブジェクトを返すのではなく、何も返さないようにする必要があると思いinstanceます。obj

問題は、ゲッター/セッターを実装する方法ですか? カスタム型のコンストラクターの一部としてではなく、これらをオブジェクトに追加する方法を説明している記事しか見つかりません。

では、ゲッター/セッターの使用とプロトタイプの拡張の両方を可能にするために、コンストラクターにゲッター/セッターを実装するにはどうすればよいでしょうか?

4

6 に答える 6

60

そんなことはできません。

ただし、オブジェクトのプロパティにセッター/ゲッターを設定できます。ただし、 ES5を使用することをお勧めしますObject.defineProperties。もちろん、これは最新のブラウザでのみ機能します。

var obj = function() {
    ...
    Object.defineProperties(this, {
        "test": {
             "get": function() { ... },
             "set": function() { ... }
        }
    });
}

obj.prototype.func = function() { ... }

var o = new obj;
o.test;
o.func();
于 2011-03-07T16:37:44.573 に答える
8

ES6 の更新 -- Alex Rauschmayer の著書Exploring ES6 http://exploringjs.com/es6/ch_maps-sets.html#sec_weakmaps-private-dataのセクション 19.3.1 を参照してください。ここでは、getter および setter で WeakMaps を使用する方法を示しています。個人データを保持します。セクション 16.2.2.3 http://exploringjs.com/es6/ch_classes.html#leanpub-auto-getters-and-setterと組み合わせると、次のような結果になります

# module test_WeakMap_getter.js
var _MyClassProp = new WeakMap();
class MyClass {
    get prop() {
        return _MyClassProp.get( this ); 
    }
    set prop(value) {
        _MyClassProp.set( this, value );
    }
}
var mc = new MyClass();
mc.prop = 5 ;
console.log( 'My value is', mc.prop );

$ node --use_strict test_WeakMap_getter.js 
My value is 5
于 2015-10-20T16:25:16.850 に答える
4
function Obj(value){
    this.value = !!value;
}

Obj.prototype = {
    get test () {
        return this.value;``
    },
    set test (value) {
        this.value = !!this.value;
    }
};
var obj = new Obj(true);
于 2016-04-10T14:49:27.463 に答える
1

@Alex 私はそれをより多くのオプションとより強力なものと考えています。プログラミングは芸術です。@Nat は彼の発見を私たちと共有しています。そういう風にやりたい人がいるのかもしれません。

セッターのバージョンは同じだと思いますが、その g を s に変更するだけです。

イグ:

function Constructor(input){
     this.input = input;
}

Object.__defineGetter__.call(Constructor.prototype, "value", function(){
    return this.input * 2;
});

Object.__defineSetter__.call(Constructor.prototype, "bar", function(foo){
    return this.input *= foo;
});

var test = new Constructor(5);
console.log(test.value); // 10
test.bar = 5;
console.log(test.input); //25

そうは言っても、この機能は非推奨であり、本番コーディングでは使用しないようにアドバイスします。

于 2014-06-11T02:15:21.817 に答える
1

私はこれが非常に遅いかもしれないことを知っていますが、あなたが望むことを達成するための別の方法を考え出し、私のような人々のために、これに対する答えをグーグルで探しています.

function Constructor(input){
     this.input = input;
}
Object.__defineGetter__.call(Constructor.prototype, "value", function(){
    return this.input * 2;
});

var test = new Constructor(5);
alert(test.value) // 10

これを chrome、safari、mobile safari、firefox でテストしましたが、すべて動作します (もちろん最新バージョン)。

于 2011-08-09T16:58:41.947 に答える