<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Where&#039;s Walden? &#187; accessor</title>
	<atom:link href="http://whereswalden.com/tag/accessor/feed/" rel="self" type="application/rss+xml" />
	<link>http://whereswalden.com</link>
	<description>Mozilla, politics, economics, law, backpacking, cycling, and other random desiderata</description>
	<lastBuildDate>Wed, 25 Jan 2012 18:17:19 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.1</generator>
		<item>
		<title>Incompatible ES5 change: literal getter and setter functions must now have exactly zero or one arguments</title>
		<link>http://whereswalden.com/2010/08/22/incompatible-es5-change-literal-getter-and-setter-functions-must-now-have-exactly-zero-or-one-arguments/</link>
		<comments>http://whereswalden.com/2010/08/22/incompatible-es5-change-literal-getter-and-setter-functions-must-now-have-exactly-zero-or-one-arguments/#comments</comments>
		<pubDate>Sun, 22 Aug 2010 16:47:18 +0000</pubDate>
		<dc:creator>Jeff</dc:creator>
				<category><![CDATA[General]]></category>
		<category><![CDATA[accessor]]></category>
		<category><![CDATA[ecma-262]]></category>
		<category><![CDATA[ecmascript]]></category>
		<category><![CDATA[es5]]></category>
		<category><![CDATA[firefox]]></category>
		<category><![CDATA[getter]]></category>
		<category><![CDATA[javascript]]></category>
		<category><![CDATA[js]]></category>
		<category><![CDATA[mozilla]]></category>
		<category><![CDATA[programming language]]></category>
		<category><![CDATA[setter]]></category>
		<category><![CDATA[spidermonkey]]></category>
		<category><![CDATA[syntax]]></category>

		<guid isPermaLink="false">http://whereswalden.com/?p=2141</guid>
		<description><![CDATA[ECMAScript accessor syntax in SpiderMonkey For quite some time SpiderMonkey and Mozilla-based browsers have supported user-defined getter and setter functions (collectively, accessors), both programmatically and syntactically. The syntaxes for accessors were once legion, but SpiderMonkey has pared them back almost to the syntax recently codified in ES5 (and added new syntax where required by ES5). [...]]]></description>
			<content:encoded><![CDATA[<h2>ECMAScript accessor syntax in SpiderMonkey</h2>
<p>For quite some time SpiderMonkey and Mozilla-based browsers have supported user-defined getter and setter functions (collectively, <dfn>accessors</dfn>), both programmatically and syntactically.  The syntaxes for accessors were once <a href="http://whereswalden.com/2010/04/16/more-spidermonkey-changes-ancient-esoteric-very-rarely-used-syntax-for-creating-getters-and-setters-is-being-removed/">legion</a>, but SpiderMonkey has pared them back almost to the syntax recently codified in <abbr title="ECMAScript 5th edition">ES5</abbr> (and added new syntax where required by ES5).</p>
<pre data-language="javascript" class="code">
// All valid in ES5
var a = { get x() { } };
var b = { get "y"() { } };
var c = { get 2() { } };

var e = { set x(v) { } };
var f = { set "y"(v) { } };
var g = { set 2(v) { } };
</pre>
<p>SpiderMonkey has historically parsed literal accessors using a slightly-tweaked version of its function parsing code.  Therefore, <a href="http://whereswalden.com/2010/04/16/more-spidermonkey-changes-ancient-esoteric-very-rarely-used-syntax-for-creating-getters-and-setters-is-being-removed/">as previously explained</a> SpiderMonkey would accept essentially anything which could follow <code>function</code> in a function expression as valid accessor syntax in object literals.</p>
<h2>ES5 requires accessors have exact numbers of arguments</h2>
<p>A consequence of parsing accessors using generalized function parsing is that SpiderMonkey accepted some nonsensicalities, such as no-argument setters or multiple-argument getters or setters:</p>
<pre data-language="javascript" class="code">
var o1 = { get p(a, b, c, d, e, f, g) { /* why have any arguments? */ } };
var o2 = { set p() { /* to what value? */ } };
var o3 = { set p(a, b, c) { /* why more than one? */ } };
</pre>
<p>ES5 accessor syntax sensibly deems such constructs errors: a conforming ES5 implementation would reject all of the above statements.</p>
<h2>SpiderMonkey is changing to follow ES5: getters require no arguments, setters require one argument</h2>
<p>SpiderMonkey has now been changed to follow ES5.  There seemed little to no gain in continuing to support bizarre numbers of arguments when the spec counseled otherwise, and any code which does end up broken is easily fixed.</p>
<p>As always, you can experiment with a version of Firefox with these changes to accessor syntax by downloading a nightly from <a href="http://nightly.mozilla.org/">nightly.mozilla.org</a>.  (Don’t forget to <a href="http://support.mozilla.com/en-US/kb/Managing+profiles">use the profile manager</a> if you want to keep the settings you use with your primary Firefox installation pristine.)</p>
]]></content:encoded>
			<wfw:commentRss>http://whereswalden.com/2010/08/22/incompatible-es5-change-literal-getter-and-setter-functions-must-now-have-exactly-zero-or-one-arguments/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>More SpiderMonkey changes: ancient, esoteric, very rarely used syntax for creating getters and setters is being removed</title>
		<link>http://whereswalden.com/2010/04/16/more-spidermonkey-changes-ancient-esoteric-very-rarely-used-syntax-for-creating-getters-and-setters-is-being-removed/</link>
		<comments>http://whereswalden.com/2010/04/16/more-spidermonkey-changes-ancient-esoteric-very-rarely-used-syntax-for-creating-getters-and-setters-is-being-removed/#comments</comments>
		<pubDate>Fri, 16 Apr 2010 21:17:42 +0000</pubDate>
		<dc:creator>Jeff</dc:creator>
				<category><![CDATA[General]]></category>
		<category><![CDATA[accessor]]></category>
		<category><![CDATA[ecma-262]]></category>
		<category><![CDATA[ecmascript]]></category>
		<category><![CDATA[es5]]></category>
		<category><![CDATA[getter]]></category>
		<category><![CDATA[js]]></category>
		<category><![CDATA[mozilla]]></category>
		<category><![CDATA[setter]]></category>
		<category><![CDATA[spidermonkey]]></category>

		<guid isPermaLink="false">http://whereswalden.com/?p=1643</guid>
		<description><![CDATA[tl;dr We&#8217;ve removed support for a handful of obsolete getter/setter syntaxes in SpiderMonkey and Mozilla. This does not include { get property() { return "value"; }, set property(v) { } }, which is widely used and which is part of the latest standard. If you don&#8217;t get any syntax errors with your code, you don&#8217;t [...]]]></description>
			<content:encoded><![CDATA[<h2><abbr title="too long, didn't read">tl;dr</abbr></h2>
<p>We&#8217;ve removed support for a handful of obsolete getter/setter syntaxes in SpiderMonkey and Mozilla.  This does <em>not</em> include <code>{ get property() { return "value"; }, set property(v) { } }</code>, which is widely used and which is part of the latest standard.  If you don&#8217;t get any syntax errors with your code, you don&#8217;t need to worry about this.  If you do, <a href="#getter-setter-updating-for-removals">skip to the end</a> for details on how to adjust your code to cope.  But really, you should read it all for the sheer joy of learning about all sorts of awful syntax you didn&#8217;t even know existed before it went away.  [Or at least empathize with us liberated SpiderMonkey hackers.  <img src='http://whereswalden.com/wp-includes/images/smilies/icon_biggrin.gif' alt=':-D' class='wp-smiley' /> ])</p>
<h2>Properties in JavaScript and ECMAScript 3</h2>
<p>The fundamental data structure in JavaScript is the <dfn>object</dfn>: a container mapping names to values through <dfn>properties</dfn>.  You can add, remove, or change the value associated with any property, so long as the property may be modified.  All user-defined properties are infinitely modifiable in any of these ways; only a few properties defined by ECMAScript (the standard on which JavaScript is based) are not fully modifiable.</p>
<pre class="code" data-language="javascript">
var obj1 = {};
obj.property = 17; // add
var obj2 = { property: 42 }; // add from birth
obj2.property = 17; // change it
delete obj2.property; // remove it
</pre>
<p>Properties which store values are useful, but what if you want properties which can <em>do</em> things when you interact with them?  What if you want to have properties which map strings to <em>lazily-computed</em> values?  Or what if you want setting a property to have side effects (as, for example, setting an array&#8217;s length to 0 removes all elements in it)?</p>
<h2>Properties with getters and setters in JavaScript</h2>
<p>If you want properties which have functionality beyond just holding a value, you need <dfn>getters</dfn> and <dfn>setters</dfn>, stored within <dfn>accessor properties</dfn>.  (Properties which hold values are called <dfn>data properties</dfn>.)  JavaScript has long included extensions to ECMAScript to create accessor properties, both syntactic:</p>
<pre class="code" data-language="javascript">
var o1 =
  {
    get property() { print("gotten!"); return "get"; },
    set property(v) { print("sotten!  " + v); }
  };
var v1 = o1.property; // prints "gotten!", v1 === "get"
o1.property = "new"; // prints "sotten!  new"
</pre>
<p>&#8230;and programmatic:</p>
<pre class="code" data-language="javascript">
var o2 = {};
o2.__defineGetter__("property", function() { print("gotten!"); return "get"; });
o2.__defineSetter__("property", function(v) { print("sotten!  " + v); });
var v2 = o2.property; // prints "gotten!", v2 === "get"
o2.property = "new"; // prints "sotten!  new"
</pre>
<p>Getters and setters are now part of <abbr title="ECMAScript 5th edition">ES5</abbr>.  The syntax demonstrated above is valid ES5; a different API, <a href="https://developer.mozilla.org/en/Core_JavaScript_1.5_Reference/Global_Objects/Object/defineProperty"><code>Object.defineProperty</code></a>, provides more flexible support for specifying getters and setters dynamically.  Developers using the old-school APIs should begin updating to use the new API as browsers make new releases supporting it.  Firefox in particular will include support for <code>Object.defineProperty</code> in its next major release, likely to occur in the latter half of the year.</p>
<h2>Examining antediluvian accessor syntax</h2>
<p>Unbeknownst to the vast majority of web developers, extension developers, and even Mozilla developers, in the past JavaScript has included other getter and setter syntaxes.</p>
<h3>Named ES5-like getters and setters</h3>
<p>If you look up the function that acts as the getter given ES5-standard getter syntax, what&#8217;s the name of that function?</p>
<pre class="code" data-language="javascript">
var o = { get property() { return "get"; } };
print(Object.getOwnPropertyDescriptor(o, "property").get.name);
</pre>
<p>There are a couple plausible answers here: &#8220;<code>anonymous</code>&#8220;, &#8220;<code>property</code>&#8221; (the property name), or &#8220;&#8221; (the empty string) might be reasonable.   JavaScript and ES5 arbitrarily create the getter or setter as a function whose name is the empty string.  What if you <em>wanted</em> to <em>name</em> that function?  (Bear with me for a moment and pretend this is a compelling need, and that adding a named getter or setter programmatically is absolutely unacceptable.)</p>
<p>Solely by accident of implementation, in the past SpiderMonkey has parsed the following syntax to assign names to getter and setter functions:</p>
<pre class="code" data-language="javascript">
var o = { get property getter() { return "get"; } };
// Prints "Name: getter" in past versions of SpiderMonkey (or would if
// Object.getOwnPropertyDescriptor existed; __lookupGetter__ is a
// simple workaround); previous line is syntax error elsewhere
print("Name: " + Object.getOwnPropertyDescriptor(o, "property").get.name);
</pre>
<p>SpiderMonkey internally implemented the parsing of literal getters and setters by parsing them as though the start of a function expression had just been parsed:</p>
<pre class="code" data-language="javascript">
// Faked-up parser state when parsing normal getters/setters
var o = { get property () { } };
                       &uarr;
function () { }
         &uarr;
</pre>
<p>Function expressions may be named or unnamed, but this wasn&#8217;t originally considered, so in the above example <code>getter</code> is treated as the name of the function created to correspond to the getter:</p>
<pre class="code" data-language="javascript">
// Faked-up parser state when parsing named-getter-function syntax
var o = { get property getter() { } };
                       &uarr;
function getter() { }
         &uarr;
</pre>
<p>No other <abbr title="JavaScript">JS</abbr> engine accepts this unintentional accessor-method name token.</p>
<h3>Getters and setters in object literals</h3>
<p>Possibly the best-known additional syntax is for specifying getters and setters in object literals.  This syntax was the original Netscape invention for getters and setters; in practice it was superseded by the newer, more function-looking syntax.  SpiderMonkey is again the only engine to implement it.</p>
<pre class="code" data-language="javascript">
function g() { print("gotten!"); return "get"; }
var o1 =
  {
    property getter: g,
    property setter: function(v) { print("sotten!  " + v); }
  };
var v1 = o1.property; // prints "gotten!", v1 === "get"
o1.property = "new"; // prints "sotten!"
</pre>
<p>This accessor property syntax has one large advantage over the more-common syntax previously demonstrated (and even over the unintentional named-accessor mistake shown in the previous section).  Where you see <code>property</code> in the object literal above, you could instead see a numeric literal, or a string literal &mdash; just as you might see either in any object literal without getters or setters, <abbr title="exempli gratia, for example" lang="la">e.g.</abbr> <code>{ 1: "value", "o": "hai" }</code>.  Historically, in <code>get property() { ... }</code>, <code>property</code> was required to be an identifier, thus excluding numbers and non-identifier accessor properties from representation.  The syntax here had the further advantage of allowing serialization to &#8220;source&#8221; (more accurately, a reasonable but not always equivalent facsimile) of objects containing non-identifier-named accessor properties, through another Netscape extension in JavaScript.</p>
<p>This syntax also has a few disadvantages.  Since the <code>getter</code> and <code>setter</code> contextual keywords follow the property name, the eye must scan past the property name to determine whether a portion of a literal represents a data property or an accessor property.  This special-case check also complicates parsing, because now the parser has to check for something beyond just a colon at such locations.  (To be sure, this problem exists with <code>get foo() { }</code>, but it&#8217;s restricted to the single leading token <code>get</code>, not to all leading tokens.)  Since the value assigned to the getter is parsed as an arbitrary expression, there&#8217;s no guarantee the value must be a function &mdash; that must be checked at runtime.</p>
<h3>Assigning getters and setters to properties</h3>
<p>This accessor syntax provides the same functionality as <code>Object.defineProperty(obj, propname, { get: fun, enumerable: true, configurable: true })</code> (<span lang="la">mutatis mutandis</span> for setters), except as part of the language syntax rather than as part of its standard library.  Again, no other engine has implemented this syntax.</p>
<pre class="code" data-language="javascript">
var o = {};
o.property getter = function() { print("gotten!"); return "get" };
o.property setter = function() { print("sotten!"); };
var v = o.property; // prints "gotten!", v === "get"
o.property = "new"; // prints "sotten!"
</pre>
<p>This syntax is also obscure: outside SpiderMonkey source and test files, only a single file in the Mozilla source code uses it.  Strangely, a trawl through <a href="https://addons.mozilla.org/"><abbr title="addons.mozilla.org">AMO</abbr></a> shows half a dozen extensions have managed to discover this syntax, despite its near-complete disuse in Mozilla itself.</p>
<h3>Assigning getters and setters to names rather than properties</h3>
<p>Syntactically, this is just a different flavor of the previous example:</p>
<pre class="code" data-language="javascript">
varname getter = function() { return "get"; };
var q = varname; // "get"
</pre>
<p>Semantically, however, it&#8217;s a rather different beast.  The problem is that not all names are alike in SpiderMonkey.  While ECMAScript specifies all name accesses in terms of objects (pure-JS objects in ES3, tighter spec-internal artifacts in ES5), most if not all JS engines out there optimize name access based on the type of the name.  Local and enclosing variable access may be some number of pointer jumps, comparisons, and an offset, rather than some sort of hash table lookup in a more general case.  Global variable access can in many circumstances skip lookups in enclosing scopes, going to the global object directly.  (Last and certainly least, variable access inside <code>with</code> almost necessarily must be essentially unoptimized and dog-slow.  Friends don&#8217;t let friends use <code>with</code>!)  These sorts of optimizations rely on names always being plain old values, not accessors (except in the global case, where the type of optimizations implemented are qualitatively quite different).  Slowing down local or enclosing variable accesses just to support this very rare case would be insane.</p>
<p>SpiderMonkey actually hasn&#8217;t supported this syntax for awhile.  I only mention it because SpiderMonkey includes code specifically to exclude it.  If this syntax is seen and <code>varname</code> can be resolved to a <code>var</code>, it&#8217;s a compile-time syntax error.  Otherwise, if <code>varname</code> resolves to a <code>var</code> at runtime (possible in the presence of <code>with</code> or <code>eval</code>), it&#8217;s a runtime <code>TypeError</code>.  Last, if it doesn&#8217;t, it &#8220;works&#8221; &mdash; and you are most likely <a href="http://squarefree.com/">Jesse</a>, combining syntax and features in obscure and evil ways solely to make SpiderMonkey developers&#8217; lives hard.  <img src='http://whereswalden.com/wp-includes/images/smilies/icon_wink.gif' alt=';-)' class='wp-smiley' />   In sufficiently old versions of Firefox where these restrictions weren&#8217;t in place, it&#8217;s entirely conceivable this syntax may have resulted in security vulnerabilities (one large factor in its removal from SpiderMonkey).</p>
<h3>Prefixed function expressions</h3>
<p>Perhaps the most bizarre getter/setter syntax is a modification of the syntax for function expressions and statements.  As with all the others, this syntax has only been implemented by SpiderMonkey.</p>
<pre class="code" data-language="javascript">
getter function foo() { return "foo getter"; };
var v = foo; // "foo getter"
var q = setter function bar(v) { };
</pre>
<p>When the prefixed function is a statement in the global scope, the syntax is equivalent to <code>Object.defineProperty(globalObject, "foo", { get: function foo() { /* ... */ }, enumerable: true, configurable: true })</code> (<span lang="la">mutatis mutandis</span> for <code>setter</code>).  If it&#8217;s a statement in a function scope or an expression that&#8217;s not a statement, the prefix serves no purpose that I can discern, except that it affects <code>Function.prototype.toString()</code>&#8216;s behavior by including the prefix in the returned string.</p>
<h2>None of these old getter/setter syntaxes provide value</h2>
<p>Now that ES5 has codified The One True Syntax and The One True Programmatic API, these older syntaxes bring little to the table.</p>
<ul>
<li>The mistaken ES5-like named accessor <code>get property funname() { }</code> syntax doesn&#8217;t satisfy a compelling need.</li>
<li><code>property getter:</code> in object literals provides one compelling feature: the ability to have non-identifier-named properties.  As ES5&#8242;s <code>get property() { }</code> syntax includes these further extensions beyond what engines have already implemented, this advantage no longer exists:
<pre class="code" data-language="javascript">
var o =
  {
    get name() { return "names valid"; },
    set break() { this.x = "keywords too"; },
    set 1() { this.y = "numeric literals also accepted"; },
    get "custom string"() { return "arbitrary string literals too!"; }
  };
</pre>
<p>(<code>property getter:</code> has a final advantage with respect to an ancient Netscape extension, but given that extension&#8217;s dubious future I will omit the details.  Suffice it to say the use case is highly esoteric, and reasonably graceful degradation is possible without <code>property getter:</code>.)</li>
<li><code>getter =</code> and <code>getter function</code> are fully subsumed by <code>Object.defineProperty</code>.</li>
<li><code>varname getter =</code> was already gone.</li>
</ul>
<p>In sum: these syntaxes make some things slightly easier, but they don&#8217;t provide anything you can&#8217;t do with ES5&#8242;s standardized accessor support.</p>
<h2>These syntaxes were the source of numerous bugs</h2>
<p>In addition to not being particularly useful, these syntaxes imposed notable costs on development.  Supporting so many different getter and setter syntaxes isn&#8217;t easy, and the relevant code paths are quite complicated, attempting to decide when which syntax is correct and when not (particularly as far as <a href="https://developer.mozilla.org/En/Core_JavaScript_1.5_Reference/Global_Objects/Object/toSource">object serialization</a> is concerned).  This has resulted in a multitude of accessor bugs usually found by <a href="https://www.squarefree.com/">Jesse</a>&#8216;s fuzz-testing and almost never by real-world scripts: bugs which, in C or C++, can often lead to memory-unsafety and, in the extreme, arbitrary code execution.  By my count SpiderMonkey has sixteen separate tests (corresponding to the same number of bugs) dedicated to edge cases and corner behaviors with these syntaxes: syntaxes no one uses, syntaxes superseded by newer and better ones, and syntaxes which no other JS engine currently supports, nor ever will support.</p>
<p>These syntaxes continue to impose costs on development.  Not all related bugs have been fixed, and changes to nearby code do have to take account of this syntax.  We have had at least one long-standing (but believed &#8220;mostly harmless&#8221;, in that a sanity-check fails but surrounding defensive code completely contains the problem) bug involving this syntax, which due to its relative harmlessness has gone unfixed for nearly three years (and, almost as bad, undiscovered for two of them).  Recent implementation work on ES5&#8242;s strict mode support required adjustments to the area of parsing object literals (for ES5&#8242;s strict mode rejection of duplicate property names), adjustments required to work around support for these syntaxes.</p>
<p>In short, <abbr title="There ain't no such thing as a free lunch">TANSTAAFL</abbr>.  We&#8217;ve paid a large cost to keep these syntaxes around, and we continue to pay to keep them around &mdash; sometimes directly, sometimes indirectly, but unavoidably if support is worthwhile.</p>
<h2>Support for all non-ES5 accessor syntaxes has been removed from SpiderMonkey</h2>
<p>But for the many reasons previously given, support for these obsolete syntaxes is not worthwhile, so we have removed them from SpiderMonkey.  <code>get property funname() { }</code> was an error from the start that no one will miss.  SpiderMonkey has recently implemented support for ES5 numeric- and string-literal accessor property names (support for keyword names already exists), so the remaining important use case for <code>property getter:</code> has been eliminated.  The <code>getter =</code> and <code>getter function</code> syntaxes never provided extra value, so they too have been removed without qualms.</p>
<p>To give an idea of the complexity eliminated by removing these syntaxes, the <a href="http://hg.mozilla.org/mozilla-central/rev/e47d2506e0ad">patch to remove them</a> added 116 lines of code but <em>removed</em> 313 lines of code.  Outside of code changes (that is, adjusting or removing tests which used these features), it added 133 lines but removed <em>1213</em> lines.  It&#8217;s always great <a href="http://blog.mozilla.com/tglek/2010/03/31/how-to-get-reviews-fast-delete-code/">deleting code</a> like this.  <img src='http://whereswalden.com/wp-includes/images/smilies/icon_smile.gif' alt=':-)' class='wp-smiley' /> </p>
<h2 id="getter-setter-updating-for-removals">Updating existing code to adapt to these removals</h2>
<p>One nice feature of removing syntax is that the failure mode when that syntax is encountered is blindingly obvious: the script will fail to parse.  Parse errors show up in the JavaScript console, so it&#8217;s easy to tell when this is the problem; SpiderMonkey&#8217;s excellent error messages should point directly at the offending location.</p>
<p>If by chance you do actually use any of these syntaxes, the necessary fixes are simple.  Suppose the existence of these helper functions:</p>
<pre class="code" data-language="javascript">
function accessorDescriptor(field, fun)
{
  var desc = { enumerable: true, configurable: true };
  desc[field] = fun;
  return desc;
}

function defineGetter(obj, prop, get)
{
  if (Object.defineProperty)
    return Object.defineProperty(obj, prop, accessorDescriptor("get", get));
  if (Object.prototype.__defineGetter__)
    return obj.__defineGetter__(prop, get);

  throw new Error("browser does not support getters");
}

function defineSetter(obj, prop, set)
{
  if (Object.defineProperty)
    return Object.defineProperty(obj, prop, accessorDescriptor("set", set));
  if (Object.prototype.__defineSetter__)
    return obj.__defineSetter__(prop, set);

  throw new Error("browser does not support setters");
}
</pre>
<p>Here&#8217;s how you can update each old syntax to work again:</p>
<dl>
<dt><code>get property funname() { }</code></dt>
<dd>
<pre class="code" data-language="javascript">
var o = defineGetter({}, "property", function funname() { });
</pre>
</dd>
<dt><code>property setter: fun</code></dt>
<dd>
<pre class="code" data-language="javascript">
var o = defineSetter({}, "property", fun);
</pre>
</dd>
<dt><code>obj.prop getter = fun</code></dt>
<dd>
<pre class="code" data-language="javascript">
defineGetter(obj, "prop", fun);
</pre>
</dd>
<dt><code>setter function prop() { }</code> (when at global scope; otherwise just remove the <code>setter</code> prefix)</dt>
<dd>
<pre class="code" data-language="javascript">
defineSetter(obj, "prop", fun);
</pre>
</dd>
</dl>
<p>You can experiment with a version of Firefox with support for these obsolete syntaxes removed by downloading a nightly from <a href="http://nightly.mozilla.org/">nightly.mozilla.org</a>.  (Don’t forget to <a href="http://support.mozilla.com/en-US/kb/Managing+profiles">use the profile manager</a> if you want to keep the settings you use with your primary Firefox installation pristine.)</p>
<h2>A brief word on <code>__defineGetter__</code> and <code>__defineSetter__</code></h2>
<p>As you may have noticed, all examples here use <code>Object.defineProperty</code> in preference to either <code>__defineGetter__</code> or <code>__defineSetter__</code>, using the latter two only as fallback when the former is absent.  While many browsers support these methods, not all do.  <code>Object.defineProperty</code> is the future, and it is the standard; Microsoft has even <a href="http://blogs.msdn.com/ie/archive/2009/01/13/responding-to-change-updated-getter-setter-syntax-in-ie8-rc-1.aspx">gone on the record</a> to say that they will not implement <code>__defineGetter__</code> or <code>__defineSetter__</code> in <abbr title="Internet Explorer">IE</abbr> given the existence of the standardized method (props to them for that choice, by the way).  For greatest forward compatibility with all browsers, you should use <code>Object.defineProperty</code> if it exists, and only fall back to <code>__define{G,S}etter__</code> if it does not.</p>
<p>In a distant future we would like to remove support for <code>__defineGetter__</code> and <code>__defineSetter__</code>, after ES5 adoption has taken off, so as not to distract from the standardized support.  The less new web developers have to know about legacy extensions superseded by standardized alternatives, the better.  This action is at least several years in the future, likely longer; being able to make the change will require preparation and adjustment in anticipation of that time.  Given upcoming releases of browsers supporting ES5 functionality, there&#8217;s no better time than the present to start gradually, and gracefully, adopting standardized methods over legacy alternatives.</p>
]]></content:encoded>
			<wfw:commentRss>http://whereswalden.com/2010/04/16/more-spidermonkey-changes-ancient-esoteric-very-rarely-used-syntax-for-creating-getters-and-setters-is-being-removed/feed/</wfw:commentRss>
		<slash:comments>17</slash:comments>
		</item>
	</channel>
</rss>

