Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <p><code>String</code>, called as a function, converts its argument to a <code>string</code>. <code>String</code>, called as a constructor, creates an object whose prototype is the <code>String</code> function. (Check <a href="https://stackoverflow.com/a/11977606/15055">James's Answer</a> for the relevant ECMAScript specification section.)</p> <p>This is indeed confusing.</p> <p>The two equality operators actually do very different things. From the <a href="http://www.ecma-international.org/ecma-262/5.1/Ecma-262.pdf" rel="nofollow noreferrer">ECMA-262, v 5.1 document</a>, <code>===</code> does:</p> <blockquote> <ol> <li>If <code>Type(x)</code> is different from <code>Type(y)</code>, return <code>false</code>. </li> <li>If <code>Type(x)</code> is <code>Undefined</code>, return <code>true</code>. </li> <li>If <code>Type(x)</code> is <code>Null</code>, return <code>true</code>.</li> <li>If <code>Type(x)</code> is <code>Number</code>, then<br> a. If <code>x</code> is <code>NaN</code>, return <code>false</code>.<br> b. If <code>y</code> is <code>NaN</code>, return <code>false</code>.<br> c. If <code>x</code> is the same <code>Number</code> value as <code>y</code>, return <code>true</code>.<br> d. If <code>x</code> is <code>+0</code> and <code>y</code> is <code>-0</code>, return <code>true</code>.<br> e. If <code>x</code> is <code>-0</code> and <code>y</code> is <code>+0</code>, return <code>true</code>.<br> f. Return <code>false</code>.</li> <li>If <code>Type(x)</code> is <code>String</code>, then return <code>true</code> if <code>x</code> and <code>y</code> are exactly the same sequence of characters (same length and same characters in corresponding positions); otherwise, return <code>false</code>.</li> <li>If <code>Type(x)</code> is <code>Boolean</code>, return <code>true</code> if <code>x</code> and <code>y</code> are both <code>true</code> or both <code>false</code>; otherwise, return <code>false</code>.</li> <li>Return <code>true</code> if <code>x</code> and <code>y</code> refer to the same object. Otherwise, return <code>false</code>.</li> </ol> </blockquote> <p>Whereas <code>==</code> does:</p> <blockquote> <ol> <li>If <code>Type(x)</code> is the same as <code>Type(y)</code>, then<br> a. If <code>Type(x)</code> is <code>Undefined</code>, return <code>true</code>.<br> b. If <code>Type(x)</code> is <code>Null</code>, return <code>true</code>.<br> c. If <code>Type(x)</code> is <code>Number</code>, then<br> &nbsp;&nbsp; i. If <code>x</code> is <code>NaN</code>, return <code>false</code>.<br> &nbsp;&nbsp; ii. If <code>y</code> is <code>NaN</code>, return <code>false</code>.<br> &nbsp;&nbsp; iii. If <code>x</code> is the same <code>Number</code> value as <code>y</code>, return <code>true</code>.<br> &nbsp;&nbsp; iv. If <code>x</code> is <code>+0</code> and <code>y</code> is <code>-0</code>, return <code>true</code>.<br> &nbsp;&nbsp; v. If <code>x</code> is <code>-0</code> and <code>y</code> is <code>+0</code>, return <code>true</code>.<br> &nbsp;&nbsp; vi. Return <code>false</code>.<br> d. If <code>Type(x)</code> is <code>String</code>, then return <code>true</code> if <code>x</code> and <code>y</code> are exactly the same sequence of characters (same length and same characters in corresponding positions). Otherwise, return <code>false</code>.<br> e. If <code>Type(x)</code> is <code>Boolean</code>, return <code>true</code> if <code>x</code> and <code>y</code> are both <code>true</code> or both <code>false</code>. Otherwise, return <code>false</code>.<br> f. Return <code>true</code> if <code>x</code> and <code>y</code> refer to the same object. Otherwise, return <code>false</code>.</li> <li>If <code>x</code> is null and <code>y</code> is undefined, return <code>true</code>. </li> <li>If <code>x</code> is undefined and <code>y</code> is null, return <code>true</code>. </li> <li>If <code>Type(x)</code> is <code>Number</code> and <code>Type(y)</code> is <code>String</code>, return the result of the comparison<br> <code>x == ToNumber(y)</code>. </li> <li>If <code>Type(x)</code> is <code>String</code> and <code>Type(y)</code> is <code>Number</code>, return the result of the comparison<br> <code>ToNumber(x) == y</code>. </li> <li>If <code>Type(x)</code> is <code>Boolean</code>, return the result of the comparison <code>ToNumber(x) == y</code>. </li> <li>If <code>Type(y)</code> is <code>Boolean</code>, return the result of the comparison <code>x == ToNumber(y)</code>. </li> <li>If <code>Type(x)</code> is either <code>String</code> or <code>Number</code> and <code>Type(y)</code> is <code>Object</code>, return the result of the comparison <code>x == ToPrimitive(y)</code>. </li> <li>If <code>Type(x)</code> is <code>Object</code> and <code>Type(y)</code> is either <code>String</code> or <code>Number</code>, return the result of the comparison <code>ToPrimitive(x) == y</code>. </li> <li>Return <code>false</code>.</li> </ol> </blockquote> <p>Note that in the spec, the <code>Type</code> of a primitive string object is <code>String</code>, whereas the type of any object (including the <code>String</code> object) is <code>Object</code>.</p> <p>With <code>===</code> the relevant line is <code>#1</code>: the <code>Type</code> of the objects are different, so <code>false</code> is returned.</p> <p>With <code>==</code> the relevant line is <code>#8</code>: <code>x</code> is a <code>String</code> (<code>"Hello world!"</code>) and <code>y</code> is an <code>Object</code> (The <code>String</code> object containing the string <code>"Hello world!"</code>). Thus the comparison <code>x == ToPrimitive(y)</code> is made. <code>ToPrimitive</code> ends up calling the <code>valueOf</code> method of the object, or if that method doesn't exist, the <code>toString</code> method. In this case, a <code>String</code> <em>object</em>'s <code>valueOf</code> method returns the primitive <code>string</code> the object contains. Thus the equality operation is done again, this time between two primitive <code>string</code>s which contain the same text, which returns <code>true</code> thanks to <code>#1.d</code>.</p> <p>JavaScript is a bit messy under the hood...</p> <hr> <p>EDIT: Notice that if two objects are compared, no conversions apply, but rather, rule <code>#1.f</code> applies. Thus, thanks to the spec, I was able to correctly predict the output of the following code:</p> <pre><code>&gt; new String("hi") == new String("hi") false </code></pre> <hr> <p>EDIT: Just thought I'd add that these distinctions are even further blurred by more implicit type conversion. For example, the following works:</p> <pre><code>&gt; ("hi").toString() "hi" </code></pre> <p>but that's not because <code>"hi"</code> is an object (like in Python):</p> <pre><code>&gt; typeof "hi" "string" </code></pre> <p>But rather, because the <a href="http://ecma-international.org/ecma-262/5.1/#sec-11.2.1" rel="nofollow noreferrer"><code>.</code> operator</a> <a href="http://ecma-international.org/ecma-262/5.1/#sec-8.7.1" rel="nofollow noreferrer">does a conversion</a> from the primitive <code>string</code> type to the string <code>Object</code> type (creating a new string object) whose <code>toString</code> method is then called.</p>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. VO
      singulars
      1. This table or related slice is empty.
    2. VO
      singulars
      1. This table or related slice is empty.
    3. VO
      singulars
      1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload