aboutsummaryrefslogtreecommitdiff
path: root/files/zh-cn/web/javascript/reference/global_objects/isnan/index.html
blob: fac7d747147b439191c044a252c80bb0d5c49290 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
---
title: isNaN()
slug: Web/JavaScript/Reference/Global_Objects/isNaN
tags:
  - JavaScript
  - Method
  - Reference
translation_of: Web/JavaScript/Reference/Global_Objects/isNaN
---
<div>{{jsSidebar("Objects")}}</div>

<p><code><strong>isNaN()</strong></code> 函数用来确定一个值是否为{{jsxref("NaN")}} 。注:<code>isNaN</code>函数内包含一些非常有趣的<a href="#Description">规则</a>;你也可以使用 ECMAScript 2015 中定义的 {{jsxref("Number.isNaN()")}} 来判断。</p>

<p>{{EmbedInteractiveExample("pages/js/globalprops-isnan.html")}}</p>

<h2 id="Syntax" name="Syntax">语法</h2>

<pre class="syntaxbox"><code>isNaN(value)</code></pre>

<h3 id="Parameters" name="Parameters">参数</h3>

<dl>
 <dt><code>value</code></dt>
 <dd>要被检测的值。</dd>
</dl>

<h3 id="返回值">返回值</h3>

<p>如果给定值为 {{jsxref("NaN")}}则返回值为<code>true</code>;否则为<code>false</code></p>

<h2 id="Description" name="Description">描述</h2>

<h3 id="The_necessity_of_an_isNaN_function" name="The_necessity_of_an_isNaN_function"><code>isNaN</code> 函数的必要性</h3>

<p>与 JavaScript 中其他的值不同,{{jsxref("Global_Objects/NaN", "NaN")}}不能通过相等操作符(== 和 ===)来判断 ,因为 <code>NaN == NaN</code><code>NaN === NaN</code> 都会返回 <code>false</code>。 因此,<code>isNaN</code> 就很有必要了。</p>

<h3 id="Origin_of_NaN_values" name="Origin_of_NaN_values"><code>NaN值</code>的产生</h3>

<p>当算术运算返回一个未定义的或无法表示的值时,<code>NaN</code>就产生了。但是,<code>NaN</code>并不一定用于表示某些值超出表示范围的情况。将某些不能强制转换为数值的非数值转换为数值的时候,也会得到<code>NaN</code></p>

<p>例如,0 除以0会返回<code>NaN </code>—— 但是其他数除以0则不会返回<code>NaN</code></p>

<h3 id="令人费解的怪异行为">令人费解的怪异行为</h3>

<p>如果<code>isNaN</code>函数的参数不是<code>Number</code>类型, <code>isNaN</code>函数会首先尝试将这个参数转换为数值,然后才会对转换后的结果是否是{{jsxref("NaN")}}进行判断。因此,对于能被强制转换为有效的非NaN数值来说(空字符串和布尔值分别会被强制转换为数值0和1),返回<code>false</code>值也许会让人感觉莫名其妙。比如说,空字符串就明显“不是数值(not a number)”。这种怪异行为起源于:"不是数值(not a number)"在基于IEEE-754数值的浮点计算体制中代表了一种特定的含义。<code>isNaN</code>函数其实等同于回答了这样一个问题:被测试的值在被强制转换成数值时会不会返回IEEE-754​中所谓的“不是数值(not a number)”。</p>

<p>下一个版本的ECMAScript (ES2015)包含{{jsxref("Number.isNaN()")}}函数。通过<code>Number.isNaN(x)</code>来检测变量<code>x</code>是否是一个<code>NaN</code>将会是一种可靠的做法。然而,在缺少<code>Number.isNaN</code>函数的情况下, 通过表达式<code>(x != x)</code> 来检测<code>变量x</code>是否是<code>NaN</code>会更加可靠。</p>

<p>一个<code>isNaN</code>的 polyfill 可以理解为(这个polyfill利用了<code>NaN</code>自身永不相等于自身这一特征 ):</p>

<pre class="brush: js line-numbers  language-js"><code class="language-js">var isNaN = function(value) {
    var n = Number(value);
    return n !== n;
};</code></pre>

<h2 id="Examples" name="Examples">示例</h2>

<pre class="brush: js">isNaN(NaN);       // true
isNaN(undefined); // true
isNaN({});        // true

isNaN(true);      // false
isNaN(null);      // false
isNaN(37);        // false

// strings
isNaN("37");      // false: 可以被转换成数值37
isNaN("37.37");   // false: 可以被转换成数值37.37
isNaN("37,5");    // true
isNaN('123ABC');  // true:  parseInt("123ABC")的结果是 123, 但是Number("123ABC")结果是 NaN
isNaN("");        // false: 空字符串被转换成0
isNaN(" ");       // false: 包含空格的字符串被转换成0

// dates
isNaN(new Date());                // false
isNaN(new Date().toString());     // true

isNaN("blabla")   // true: "blabla"不能转换成数值
                  // 转换成数值失败, 返回NaN
</pre>

<h3 id="有用的特殊行为">有用的特殊行为</h3>

<p>有许多方式来看待<code>isNaN()</code>:如果<code>isNaN(x)</code>返回false,那么x在任何算数表达式中都不会使表达式等于NaN;如果返回true,x会使所有算数表达式返回NaN。这就意味着,在JavaScript中,isNaN(x)==true等价于x-0=NaN(在JavaScript中 x-0 == NaN 总是返回false,所以你不用去测试它)。实际上, <code>isNaN(x)</code><code>isNaN(x - 0)</code>,<code>isNaN(Number(x))</code><code>Number.isNaN(x - 0)</code>,和<code>Number.isNaN(Number(x))</code> 的返回值都是一样的 并且在JavaScript中isNaN(x)是这些表达式中最短的表达。</p>

<p>举个例子,可以利用这个特殊行为来检测函数的参数是可运算的(可以像number一样进行加减乘除等运算)。如果不可运算,则可赋予这个参数一个默认的值或其他合适的内容。这样,就可以得到一个隐式转换参数值的函数,而这得益于Javascript的全功能性。</p>

<h2 id="例子">例子</h2>

<pre class="brush: js">function increment(x) {
  if (isNaN(x)) x = 0;
  return x + 1;
};

// The same effect with Number.isNaN():
function increment(x) {
  if (Number.isNaN(Number(x))) x = 0;
  return x + 1;
};

// In the following cases for the function's argument x,
// isNaN(x) is always false, although x is indeed not a
// number, but can be used as such in arithmetical
// expressions
increment("");            // 1: "" is converted to 0
increment(new String());  // 1: String object representing an empty string is converted to 0
increment([]);            // 1: [] is converted to 0
increment(new Array());   // 1: Array object representing an empty array is converted to 0
increment("0");           // 1: "0" is converted to 0
increment("1");           // 2: "1" is converted to 1
increment("0.1");         // 1.1: "0.1" is converted to 0.1
increment("Infinity");    // Infinity: "Infinity" is converted to Infinity
increment(null);          // 1: null is converted to 0
increment(false);         // 1: false is converted to 0
increment(true);          // 2: true is converted to 1
increment(new Date());    // returns current date/time in milliseconds plus 1

// In the following cases for the function's argument x,
// isNaN(x) is always false and x is indeed a number
increment(-1);            // 0
increment(-0.1);          // 0.9
increment(0);             // 1
increment(1);             // 2
increment(2);             // 3
// ... and so on ...
increment(Infinity);      // Infinity

// In the following cases for the function's argument x,
// isNaN(x) is always true and x is really not a number,
// thus the function replaces it by 0 and returns 1
increment(String);            // 1
increment(Array);             // 1
increment("blabla");          // 1
increment("-blabla");         // 1
increment(0/0);               // 1
increment("0/0");             // 1
increment(Infinity/Infinity); // 1
increment(NaN);               // 1
increment(undefined);         // 1
increment();                  // 1

// isNaN(x) is always the same as isNaN(Number(x)),
// but the presence of x is mandatory here!
isNaN(x) == isNaN(Number(x))  // true for every value of x, including x == undefined,
                              // because isNaN(undefined) == true and Number(undefined) returns NaN,
                              // but ...
isNaN() == isNaN(Number())    // false, because isNaN() == true and Number() == 0</pre>

<h2 id="规范">规范</h2>

<table class="standard-table">
 <tbody>
  <tr>
   <th scope="col">Specification</th>
   <th scope="col">Status</th>
   <th scope="col">Comment</th>
  </tr>
  <tr>
   <td>{{SpecName('ES1')}}</td>
   <td>{{Spec2('ES1')}}</td>
   <td>Initial definition.</td>
  </tr>
  <tr>
   <td>{{SpecName('ES5.1', '#sec-15.1.2.4', 'isNaN')}}</td>
   <td>{{Spec2('ES5.1')}}</td>
   <td></td>
  </tr>
  <tr>
   <td>{{SpecName('ES6', '#sec-isnan-number', 'isNaN')}}</td>
   <td>{{Spec2('ES6')}}</td>
   <td></td>
  </tr>
  <tr>
   <td>{{SpecName('ESDraft', '#sec-isnan-number', 'isNaN')}}</td>
   <td>{{Spec2('ESDraft')}}</td>
   <td></td>
  </tr>
 </tbody>
</table>

<h2 id="浏览器兼容性">浏览器兼容性</h2>



<p>{{Compat("javascript.builtins.isNaN")}}</p>

<h2 id="相关链接">相关链接</h2>

<ul>
 <li>{{jsxref("NaN")}}</li>
 <li>{{jsxref("Number.isNaN()")}}</li>
</ul>