Revision 57938 of Defining Getters and Setters

  • Revision slug: JavaScript/Guide/Obsolete_Pages/Creating_New_Objects/Defining_Getters_and_Setters
  • Revision title: Defining Getters and Setters
  • Revision id: 57938
  • Created:
  • Creator: Brettz9
  • Is current revision? No
  • Comment no wording changes

Revision Content

A getter is a method that gets the value of a specific property. A setter is a method that sets the value of a specific property. You can define getters and setters on any predefined core object or user-defined object that supports the addition of new properties. The syntax for defining getters and setters uses the object literal syntax.

{{ js_minversion_note("1.8.1", "Starting in JavaScript 1.8.1, setters are no longer called when setting properties in object and array initializers.") }}

The following JS shell session illustrates how getters and setters could work for a user-defined object o. The JS shell is an application that allows developers to test JavaScript code in batch mode or interactively.

js> var o = {a:7, get b() {return this.a+1;}, set c(x) {this.a = x/2}};
[object Object]
js> o.a;
7
js> o.b;
8
js> o.c = 50;
js> o.a;
25

The o object's properties are:

  • o.a - a number
  • o.b - a getter that returns o.a plus 1
  • o.c - a setter that sets the value of o.a to half of the value o.c is being set to

Another (Mozilla-specific) way to represent the first line which also would support setting getters and setters on object properties (such as "foo-bar") that need to be quoted:

var o = {a:7, 'b' getter:function () {return this.a + 1;}, c setter:function (x) {this.a = x / 2;}};

Please note that function names of getters and setters defined in an object literal using "[gs]et property()" (as opposed to __define[GS]etter__ below) are not the names of the getters themselves, even though the [gs]et propertyName(){ } syntax may mislead you to think otherwise. To name a function in a getter or setter using the "[gs]et property()" syntax, put the name of the getter after the get or set and then put the function name after it. The following example shows how to name getter functions in object literals:

var objects = [{get a b(){return 1}},
               {a getter:function b(){return 1}},
               {"a" getter:function b(){return 1}}];

for (var i=0; i<objects.length; ++i)
    print(objects[i].__lookupGetter__("a")) // prints "function b(){return 1}" for every getter.

This JavaScript shell session illustrates how getters and setters can extend the Date prototype to add a year property to all instances of the predefined Date class. It uses the Date class's existing getFullYear and setFullYear methods to support the year property's getter and setter.

These statements define a getter and setter for the year property:

js> var d = Date.prototype;
js> d.__defineGetter__("year", function() { return this.getFullYear(); });
js> d.__defineSetter__("year", function(y) { this.setFullYear(y); });

These statements use the getter and setter in a Date object:

js> var now = new Date;
js> print(now.year);
2000
js> now.year = 2001;
987617605170
js> print(now);
Wed Apr 18 11:13:25 GMT-0700 (Pacific Daylight Time) 2001
During development of JavaScript 1.5, there was a brief period in which expressions including getter = or setter = were used to define new getters or setters on existing objects. This syntax is highly deprecated now, will cause a warning in current JS 1.5 engines, and will become a syntax error in the future. It should be avoided.

Summary

In principle, getters and setters can be either

  • defined using object initializers, or
  • added later to any object at any time using a getter or setter adding method.

When defining getters and setters using object initializers all you need to do is to prefix a getter method with get and a setter method with set. Of course, the getter method must not expect a parameter, while the setter method expects exactly one parameter (the new value to set). For instance:

o = {
  a:7,
  get b() { return this.a+1; },
  set c(x) { this.a = x/2; }
};

Getters and setters can also be added to an object at any time after creation using two special methods called __defineGetter__ and __defineSetter__. Both methods expect the name of the getter or setter as their first parameter, in form of a string. The second parameter is the function to call as the getter or setter. For instance (following the previous example):

o.__defineGetter__("b", function() { return this.a+1; });
o.__defineSetter__("c", function(x) { this.a = x/2; });

Which of the two forms to choose depends on your programming style and task at hand. If you already go for the object initializer when defining a prototype you will probably most of the time choose the first form. This form is more compact and natural. However, if you need to add getters and setters later – because you did not write the prototype or particular object – then the second form is the only possible form. The second form probably best represents the dynamic nature of JavaScript – but it can make the code hard to read and understand.

Prior to Firefox 3.0, getter and setter are not supported for DOM Elements. Older versions of Firefox silently fail. If exceptions are needed for those, changing the prototype of HTMLElement (HTMLElement.prototype.__define{{ mediawiki.external('SG') }}etter__) and throwing an exception is a workaround.

With Firefox 3.0, defining getter or setter on an already-defined property will throw an exception. The property has to be deleted beforehand, what is not the case for older versions of Firefox.

See also

{{ PreviousNext("Core_JavaScript_1.5_Guide:Creating_New_Objects:Using_this_for_Object_References", "Core_JavaScript_1.5_Guide:Creating_New_Objects:Deleting_Properties") }}

{{ languages( { "zh-tw": "zh_tw/Core_JavaScript_1.5_教學/新物件的建立/Getter_和_Setter_的定義", "es": "es/Gu\u00eda_JavaScript_1.5/Crear_nuevos_objetos/Definiendo_las_funciones_get_y_set", "fr": "fr/Guide_JavaScript_1.5/Cr\u00e9ation_d\'objets/D\u00e9finition_d\'accesseurs_et_de_mutateurs", "ja": "ja/Core_JavaScript_1.5_Guide/Creating_New_Objects/Defining_Getters_and_Setters", "ko": "ko/Core_JavaScript_1.5_Guide/Creating_New_Objects/Defining_Getters_and_Setters", "pl": "pl/Przewodnik_po_j\u0119zyku_JavaScript_1.5/Tworzenie_nowych_obiekt\u00f3w/Definiowanie_metod_pobierania_i_ustawiania" } ) }}

Revision Source

<p>A getter is a method that gets the value of a specific property. A setter is a method that sets the value of a specific property. You can define getters and setters on any predefined core object or user-defined object that supports the addition of new properties. The syntax for defining getters and setters uses the object literal syntax.</p>
<p>{{ js_minversion_note("1.8.1", "Starting in JavaScript 1.8.1, setters are no longer called when setting properties in object and array initializers.") }}</p>
<p>The following JS shell session illustrates how getters and setters could work for a user-defined object o. The <a href="/En/SpiderMonkey/Introduction_to_the_JavaScript_shell" title="En/SpiderMonkey/Introduction_to_the_JavaScript_shell">JS shell</a> is an application that allows developers to test JavaScript code in batch mode or interactively.</p>
<pre>js&gt; var o = {a:7, get b() {return this.a+1;}, set c(x) {this.a = x/2}};
[object Object]
js&gt; o.a;
7
js&gt; o.b;
8
js&gt; o.c = 50;
js&gt; o.a;
25
</pre>
<p>The <code>o</code> object's properties are:</p>
<ul> <li>o.a - a number</li> <li>o.b - a getter that returns o.a plus 1</li> <li>o.c - a setter that sets the value of o.a to half of the value o.c is being set to</li>
</ul>
<p>Another (Mozilla-specific) way to represent the first line which also would support setting getters and setters on object properties (such as "foo<strong>-</strong>bar") that need to be quoted:</p>
<pre class="brush: js">var o = {a:7, 'b' getter:function () {return this.a + 1;}, c setter:function (x) {this.a = x / 2;}};</pre>
<p>Please note that function names of getters and setters defined in an object literal using "[gs]et <em>property</em>()" (as opposed to <code>__define[GS]etter__</code> below) are not the names of the getters themselves, even though the <code>[gs]et <em>propertyName</em>(){ }</code> syntax may mislead you to think otherwise. To name a function in a getter or setter using the "[gs]et <em>property</em>()" syntax, put the name of the getter after the get or set and then put the function name after it. The following example shows how to name getter functions in object literals:</p>
<pre class="brush: js">var objects = [{get a b(){return 1}},
               {a getter:function b(){return 1}},
               {"a" getter:function b(){return 1}}];

for (var i=0; i&lt;objects.length; ++i)
    print(objects[i].__lookupGetter__("a")) // prints "function b(){return 1}" for every getter.
</pre>
<p>This JavaScript shell session illustrates how getters and setters can extend the Date prototype to add a year property to all instances of the predefined <code>Date</code> class. It uses the <code>Date</code> class's existing <code>getFullYear</code> and <code>setFullYear</code> methods to support the year property's getter and setter.</p>
<p>These statements define a getter and setter for the year property:</p>
<pre>js&gt; var d = Date.prototype;
js&gt; d.__defineGetter__("year", function() { return this.getFullYear(); });
js&gt; d.__defineSetter__("year", function(y) { this.setFullYear(y); });
</pre>
<p>These statements use the getter and setter in a <code>Date</code> object:</p>
<pre>js&gt; var now = new Date;
js&gt; print(now.year);
2000
js&gt; now.year = 2001;
987617605170
js&gt; print(now);
Wed Apr 18 11:13:25 GMT-0700 (Pacific Daylight Time) 2001
</pre>
<div class="tip">During development of JavaScript 1.5, there was a brief period in which expressions including <code>getter =</code> or <code>setter =</code> were used to define new getters or setters on existing objects. This syntax is highly deprecated now, will cause a warning in current JS 1.5 engines, and will become a syntax error in the future. It should be avoided.</div>
<h3 name="Summary">Summary</h3>
<p>In principle, getters and setters can be either</p>
<ul> <li>defined using <a href="/en/Core_JavaScript_1.5_Guide/Creating_New_Objects/Using_Object_Initializers" title="en/Core_JavaScript_1.5_Guide/Creating_New_Objects/Using_Object_Initializers"> object initializers</a>, or</li> <li>added later to any object at any time using a getter or setter adding method.</li>
</ul>
<p>When defining getters and setters using <a href="/en/Core_JavaScript_1.5_Guide/Creating_New_Objects/Using_Object_Initializers" title="en/Core_JavaScript_1.5_Guide/Creating_New_Objects/Using_Object_Initializers"> object initializers</a> all you need to do is to prefix a getter method with <code>get</code> and a setter method with <code>set</code>. Of course, the getter method must not expect a parameter, while the setter method expects exactly one parameter (the new value to set). For instance:</p>
<pre class="brush: js">o = {
  a:7,
  <strong>get</strong> b() { return this.a+1; },
  <strong>set</strong> c(x) { this.a = x/2; }
};
</pre>
<p>Getters and setters can also be added to an object at any time after creation using two special methods called <code>__defineGetter__</code> and <code>__defineSetter__</code>. Both methods expect the name of the getter or setter as their first parameter, in form of a string. The second parameter is the function to call as the getter or setter. For instance (following the previous example):</p>
<pre class="brush: js">o.__defineGetter__("b", function() { return this.a+1; });
o.__defineSetter__("c", function(x) { this.a = x/2; });
</pre>
<p>Which of the two forms to choose depends on your programming style and task at hand. If you already go for the object initializer when defining a prototype you will probably most of the time choose the first form. This form is more compact and natural. However, if you need to add getters and setters later – because you did not write the prototype or particular object – then the second form is the only possible form. The second form probably best represents the dynamic nature of JavaScript – but it can make the code hard to read and understand.</p>
<div class="tip">
<p>Prior to Firefox 3.0, getter and setter are not supported for DOM Elements. Older versions of Firefox silently fail. If exceptions are needed for those, changing the prototype of HTMLElement <code>(HTMLElement.prototype.__define{{ mediawiki.external('SG') }}etter__)</code> and throwing an exception is a workaround.</p>
With Firefox 3.0, defining getter or setter on an already-defined property will throw an exception. The property has to be deleted beforehand, what is not the case for older versions of Firefox.</div>
<h3>See also</h3>
<ul> <li><a href="/en/Core_JavaScript_1.5_Reference/Global_Objects/Object/defineGetter" title="en/Core_JavaScript_1.5_Reference/Global_Objects/Object/defineGetter">__defineGetter__</a></li> <li><a href="/en/Core_JavaScript_1.5_Reference/Global_Objects/Object/defineSetter" title="en/Core_JavaScript_1.5_Reference/Global_Objects/Object/defineSetter">__defineSetter__</a></li> <li><a href="/en/Core_JavaScript_1.5_Reference/Operators/Special_Operators/get_Operator" title="en/Core_JavaScript_1.5_Reference/Operators/Special_Operators/get_Operator">get</a></li> <li><a href="/en/Core_JavaScript_1.5_Reference/Operators/Special_Operators/set_Operator" title="en/Core_JavaScript_1.5_Reference/Operators/Special_Operators/set_Operator">set</a></li>
</ul>
<p>{{ PreviousNext("Core_JavaScript_1.5_Guide:Creating_New_Objects:Using_this_for_Object_References", "Core_JavaScript_1.5_Guide:Creating_New_Objects:Deleting_Properties") }}</p>
<p>{{ languages( { "zh-tw": "zh_tw/Core_JavaScript_1.5_教學/新物件的建立/Getter_和_Setter_的定義", "es": "es/Gu\u00eda_JavaScript_1.5/Crear_nuevos_objetos/Definiendo_las_funciones_get_y_set", "fr": "fr/Guide_JavaScript_1.5/Cr\u00e9ation_d\'objets/D\u00e9finition_d\'accesseurs_et_de_mutateurs", "ja": "ja/Core_JavaScript_1.5_Guide/Creating_New_Objects/Defining_Getters_and_Setters", "ko": "ko/Core_JavaScript_1.5_Guide/Creating_New_Objects/Defining_Getters_and_Setters", "pl": "pl/Przewodnik_po_j\u0119zyku_JavaScript_1.5/Tworzenie_nowych_obiekt\u00f3w/Definiowanie_metod_pobierania_i_ustawiania" } ) }}</p>
Revert to this revision