141

私はゲッターとセッターに頭を悩ませようとしてきましたが、それは沈みません。JavaScriptのゲッターとセッターとゲッターとセッターの定義を読んだのですが、うまくいきませんでした。

誰かが明確に述べることができますか?

  1. ゲッターとセッターが何をするのか、そして
  2. 非常に簡単な例をいくつか挙げてください。
4

14 に答える 14

104

@millimooseの回答に加えて、セッターを使用して他の値を更新することもできます。

function Name(first, last) {
    this.first = first;
    this.last = last;
}

Name.prototype = {
    get fullName() {
        return this.first + " " + this.last;
    },

    set fullName(name) {
        var names = name.split(" ");
        this.first = names[0];
        this.last = names[1];
    }
};

fullNameこれで、firstを設定できますlast。また、更新されます。その逆も同様です。

n = new Name('Claude', 'Monet')
n.first # "Claude"
n.last # "Monet"
n.fullName # "Claude Monet"
n.fullName = "Gustav Klimt"
n.first # "Gustav"
n.last # "Klimt"
于 2009-05-01T21:15:22.433 に答える
59

たとえば、計算されたプロパティを実装するためにそれらを使用します。

例えば:

function Circle(radius) {
    this.radius = radius;
}

Object.defineProperty(Circle.prototype, 'circumference', {
    get: function() { return 2*Math.PI*this.radius; }
});

Object.defineProperty(Circle.prototype, 'area', {
    get: function() { return Math.PI*this.radius*this.radius; }
});

c = new Circle(10);
console.log(c.area); // Should output 314.159
console.log(c.circumference); // Should output 62.832

(CodePen)

于 2009-05-01T19:58:07.393 に答える
11

ゲッターとセッターは、クラスのプライベート プロパティがある場合にのみ意味があります。オブジェクト指向言語から通常考えられるように、Javascript には実際にはプライベート クラス プロパティがないため、理解するのが難しい場合があります。以下は、プライベート カウンター オブジェクトの一例です。このオブジェクトの良いところは、オブジェクトの外部から内部変数「count」にアクセスできないことです。

var counter = function() {
    var count = 0;

    this.inc = function() {
        count++;
    };

    this.getCount = function() {
        return count;
    };
};

var i = new Counter();
i.inc();
i.inc();
// writes "2" to the document
document.write( i.getCount());

まだ混乱している場合は、Javascript のプライベート メンバーに関する Crockford の記事を参照してください。

于 2009-05-01T20:53:34.827 に答える
8

あなたがリンクしている最初の記事はそれをかなり明確に述べていると思います:

この方法でJavaScriptを作成することの明らかな利点は、ユーザーに直接アクセスさせたくないあいまいな値を使用できることです。

ここでの目標は、get()またはset()メソッドを介してのみフィールドへのアクセスを許可することにより、フィールドをカプセル化して抽象化することです。このようにして、フィールド/データを任意の方法で内部に保存できますが、外部コンポーネントは公開されたインターフェイスから離れているだけです。これにより、外部インターフェイスを変更せずに内部変更を行ったり、set()メソッド内で検証やエラーチェックを行ったりすることができます。

于 2009-05-01T19:57:12.043 に答える
6

アクセス制御のないパブリック プロパティを持つオブジェクトに慣れていることがよくありますが、JavaScript を使用すると、プロパティを正確に記述することができます。実際、記述子を使用して、プロパティにアクセスする方法と、プロパティに適用できるロジックを制御できます。次の例を検討してください。

var employee = {
    first: "Boris",
    last: "Sergeev",
    get fullName() {
        return this.first + " " + this.last;
    },
    set fullName(value) {
        var parts = value.toString().split(" ");
        this.first = parts[0] || "";
        this.last = parts[1] || "";
    },
    email: "boris.sergeev@example.com"
};

最終結果:

console.log(employee.fullName); //Boris Sergeev
employee.fullName = "Alex Makarenko";

console.log(employee.first);//Alex
console.log(employee.last);//Makarenko
console.log(employee.fullName);//Alex Makarenko
于 2016-10-25T13:35:03.203 に答える
3

コンストラクターのプロトタイプを介して、js クラスのインスタンス メソッドを定義できます。

サンプルコードは次のとおりです。

// BaseClass

var BaseClass = function(name) {
    // instance property
    this.name = name;
};

// instance method
BaseClass.prototype.getName = function() {
    return this.name;
};
BaseClass.prototype.setName = function(name) {
    return this.name = name;
};


// test - start
function test() {
    var b1 = new BaseClass("b1");
    var b2 = new BaseClass("b2");
    console.log(b1.getName());
    console.log(b2.getName());

    b1.setName("b1_new");
    console.log(b1.getName());
    console.log(b2.getName());
}

test();
// test - end

また、これはどのブラウザでも機能するはずです。nodejs を使用してこのコードを実行することもできます。

于 2014-06-16T03:27:58.817 に答える
2

アクセサの概念を参照している場合、単純な目標は、基盤となるストレージを任意の操作から隠すことです。このための最も極端なメカニズムは

function Foo(someValue) {
    this.getValue = function() { return someValue; }
    return this;
}

var myFoo = new Foo(5);
/* We can read someValue through getValue(), but there is no mechanism
 * to modify it -- hurrah, we have achieved encapsulation!
 */
myFoo.getValue();

実際のJSゲッター/セッター機能を参照している場合、たとえば。defineGetter/ defineSetter、または{ get Foo() { /* code */ } }、その後、ほとんどの最新のエンジンでは、これらのプロパティのその後の使用は、そうでない場合よりもはるかに遅くなることに注意してください。例えば。のパフォーマンスを比較する

var a = { getValue: function(){ return 5; }; }
for (var i = 0; i < 100000; i++)
    a.getValue();

対。

var a = { get value(){ return 5; }; }
for (var i = 0; i < 100000; i++)
    a.value;
于 2009-05-01T20:51:32.523 に答える
2

それについて何が混乱しているのか...ゲッターは、プロパティを取得するときに呼び出される関数であり、セッターは、設定するときに呼び出されます。たとえば、そうする場合

obj.prop = "abc";

ゲッター/セッターを使用している場合は、プロパティ プロップを設定しています。セッター関数は、「abc」を引数として呼び出されます。オブジェクト内のセッター関数の定義は、理想的には次のようになります。

set prop(var) {
   // do stuff with var...
}

それがブラウザ間でどれだけうまく実装されているかはわかりません。Firefox には、下線が 2 つ付いた特別な (「マジック」) メソッドを使用する別の構文もあるようです。いつものように、Internet Explorer はこれをサポートしていません。

于 2011-04-28T11:19:14.777 に答える
2

また、私が書いていない既存のプロトタイプにプロパティを追加しようとしていたため、読んだ説明にも多少混乱しました。そのため、プロトタイプを置き換えるのは間違ったアプローチのように思えました。したがって、後世のために、lastプロパティをに追加する方法は次のArrayとおりです。

Object.defineProperty(Array.prototype, "last", {
    get: function() { return this[this.length - 1] }
});

関数IMHOを追加するよりも少しいいです。

于 2014-09-16T16:53:31.673 に答える
-1

私はあなたたちのために少し醜いかもしれないものを持っていますが、それはプラットフォーム間でうまくいきます

function myFunc () {

var _myAttribute = "default";

this.myAttribute = function() {
    if (arguments.length > 0) _myAttribute = arguments[0];
    return _myAttribute;
}
}

このように、あなたが電話するとき

var test = new myFunc();
test.myAttribute(); //-> "default"
test.myAttribute("ok"); //-> "ok"
test.myAttribute(); //-> "ok"

あなたが本当に物事を盛り上げたいのなら..あなたは一種のチェックを挿入することができます:

if (arguments.length > 0 && typeof arguments[0] == "boolean") _myAttribute = arguments[0];
if (arguments.length > 0 && typeof arguments[0] == "number") _myAttribute = arguments[0];
if (arguments.length > 0 && typeof arguments[0] == "string") _myAttribute = arguments[0];

または、高度なtypeofチェックでさらにクレイジーになります: codingforums.comのtype.of()コード

于 2010-07-09T14:15:03.100 に答える