Sharp variables in JavaScript

  • Revision slug: JavaScript/Sharp_variables_in_JavaScript
  • Revision title: Sharp variables in JavaScript
  • Revision id: 42781
  • Created:
  • Creator: ziyunfei
  • Is current revision? No
  • Comment 28 words added

Revision Content

A sharp variable is a syntax in object initializers that allows serialization of objects that have cyclic references or multiple references to the same object.

{{ js_obsolete_header("1.8.5+") }} {{ warning("Sharp variables are a non-standard syntax for creating or serializing cyclic data graphs supported only by Mozilla's SpiderMonkey JS engine. Do not use them in non-Mozilla code, and even in Mozilla code consider the cleaner style of either multiple statements or a let-expression for constructing cyclic values. This feature was removed in bug 566700, Firefox 12.") }}

Form

Sharp variables have the form of a sharp sign (#) immediately followed by one or more digits.  The number represented by the digits serves as the variable's unique identifier, but leading 0s are ignored.

Scope

Sharp variables are only in scope in the statement in which they are defined.

Usage

To create a sharp variable, simply assign an object to it in a line of code using an equal sign.  You cannot assign primitives (including strings) to sharp variables.  Make sure you don't put in any spaces before the equal sign though.

#1={}       // This doesn't do much since the sharp variable is out of scope immediately after
a = #2= {}  // Slightly more useful since we retain a reference to the new object

To reference the sharp variable, simply append another sharp (#) to the end of the variable name.  This acts as a reference to initial variable.  You can use this to create objects in a single line of code that would otherwise take multiple lines of code.

Examples

Multiple references

var a = {foo:#1=[], bar:#1#}
a.foo.push("Hello")
a.bar.push("there!")
print(a.foo[1])      // "there!"

You can avoid using sharp variables by breaking the declaration up into multiple lines.

var a = {foo:[], bar:undefined}
a.bar = a.foo

a.foo.push("Hello")
a.bar.push("there!")
print(a.foo[1])      // "there!"

Cyclic references

Sharp variables can be used to create a circularly linked list in one line of code.

var a = #1={val:1, next:{val:2, next:#1#}}

a.val                 // 1
a.next.val            // 2
a.next.next.val       // 1

a.next.next == a      // true

Again, you can eliminate the need for sharp variables by using two lines instead of one for the declaration.

var a = {val:1, next:{val:2, next:undefined}}
a.next.next = a;

a.val                 // 1
a.next.val            // 2
a.next.next.val       // 1

a.next.next == a      // true

Multiple sharp variables

var a = #1={val:#2=[], next:{val:[], next:{val:#02#, next:#1#}}}  // Leading 0s don't matter

a.val.push(1)
a.next.val.push(2)

a.val[0]                 // 1
a.next.val[0]            // 2
a.next.next.val[0]       // 1
a.next.next.next.val[0]  // 1

a == a.next.next         // false
a == a.next.next.next    // true

See also

JavaScript, Variables, Literals

{{ languages( { "zh-cn": "zh-cn/JavaScript/Reference/Global_Objects/String/Trim"} ) }}

Revision Source

<p>A sharp variable is a syntax in object initializers that allows serialization of objects that have cyclic references or multiple references to the same object.</p>
<p>{{ js_obsolete_header("1.8.5+") }} {{ warning("Sharp variables are a non-standard syntax for creating or serializing cyclic data graphs supported only by Mozilla's SpiderMonkey JS engine. Do not use them in non-Mozilla code, and even in Mozilla code consider the cleaner style of either multiple statements or a let-expression for constructing cyclic values. This feature was removed in bug 566700, Firefox 12.") }}</p>
<h2>Form</h2>
<p>Sharp variables have the form of a sharp sign (#) immediately followed by one or more digits.  The number represented by the digits serves as the variable's unique identifier, but leading 0s are ignored.</p>
<h2>Scope</h2>
<p>Sharp variables are only in scope in the statement in which they are defined.</p>
<h2>Usage</h2>
<p>To create a sharp variable, simply assign an object to it in a line of code using an equal sign.  You cannot assign primitives (including strings) to sharp variables.  Make sure you don't put in any spaces before the equal sign though.</p>
<pre>#1={}       // This doesn't do much since the sharp variable is out of scope immediately after
a = #2= {}  // Slightly more useful since we retain a reference to the new object
</pre>
<p>To reference the sharp variable, simply append another sharp (#) to the end of the variable name.  This acts as a reference to initial variable.  You can use this to create objects in a single line of code that would otherwise take multiple lines of code.</p>
<h2>Examples</h2>
<h3>Multiple references</h3>
<pre class="eval">var a = {foo:#1=[], bar:#1#}
a.foo.push("Hello")
a.bar.push("there!")
print(a.foo[1])      // "there!"
</pre>
<p>You can avoid using sharp variables by breaking the declaration up into multiple lines.</p>
<pre>var a = {foo:[], bar:undefined}
a.bar = a.foo

a.foo.push("Hello")
a.bar.push("there!")
print(a.foo[1])      // "there!"
</pre>
<h3>Cyclic references</h3>
<p>Sharp variables can be used to create a circularly linked list in one line of code.</p>
<pre class="eval">var a = #1={val:1, next:{val:2, next:#1#}}

a.val                 // 1
a.next.val            // 2
a.next.next.val       // 1

a.next.next == a      // true
</pre>
<p>Again, you can eliminate the need for sharp variables by using two lines instead of one for the declaration.</p>
<pre>var a = {val:1, next:{val:2, next:undefined}}
a.next.next = a;

a.val                 // 1
a.next.val            // 2
a.next.next.val       // 1

a.next.next == a      // true
</pre>
<h3>Multiple sharp variables</h3>
<pre>var a = #1={val:#2=[], next:{val:[], next:{val:#02#, next:#1#}}}  // Leading 0s don't matter

a.val.push(1)
a.next.val.push(2)

a.val[0]                 // 1
a.next.val[0]            // 2
a.next.next.val[0]       // 1
a.next.next.next.val[0]  // 1

a == a.next.next         // false
a == a.next.next.next    // true
</pre>
<h2>See also</h2>
<p><a href="/en/JavaScript" title="en/JavaScript">JavaScript</a>, <a href="/en/JavaScript/Guide/Obsolete_Pages/Variables" title="en/Core_JavaScript_1.5_Guide/Variables">Variables</a>, <a href="/en/JavaScript/Guide/Obsolete_Pages/Literals" title="en/Core_JavaScript_1.5_Guide/Literals">Literals</a></p> {{ languages( { "zh-cn": "zh-cn/JavaScript/Reference/Global_Objects/String/Trim"} ) }}
Revert to this revision