<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                企業??AI智能體構建引擎,智能編排和調試,一鍵部署,支持知識庫和私有化部署方案 廣告
                # 類型 ## 相等與比較 JavaScript 有兩種方式判斷兩個值是否相等。 ### 等于操作符 等于操作符由兩個等號組成:`==` JavaScript 是_弱類型_語言,這就意味著,等于操作符會為了比較兩個值而進行**強制類型轉換**。 ``` "" == "0" // false 0 == "" // true 0 == "0" // true false == "false" // false false == "0" // true false == undefined // false false == null // false null == undefined // true " \t\r\n" == 0 // true ``` 上面的表格展示了強制類型轉換,這也是使用 `==` 被廣泛認為是不好編程習慣的主要原因, 由于它的復雜轉換規則,會導致難以跟蹤的問題。 此外,強制類型轉換也會帶來性能消耗,比如一個字符串為了和一個數字進行比較,必須事先被強制轉換為數字。 ### 嚴格等于操作符 嚴格等于操作符由**三**個等號組成:`===` 不像普通的等于操作符,嚴格等于操作符**不會**進行強制類型轉換。 ``` "" === "0" // false 0 === "" // false 0 === "0" // false false === "false" // false false === "0" // false false === undefined // false false === null // false null === undefined // false " \t\r\n" === 0 // false ``` 上面的結果更加清晰并有利于代碼的分析。如果兩個操作數類型不同就肯定不相等也有助于性能的提升。 ### 比較對象 雖然 `==` 和 `===` 操作符都是等于操作符,但是當其中有一個操作數為對象時,行為就不同了。 ``` {} === {}; // false new String('foo') === 'foo'; // false new Number(10) === 10; // false var foo = {}; foo === foo; // true ``` 這里等于操作符比較的**不是**值是否相等,而是是否屬于同一個**身份**;也就是說,只有對象的同一個實例才被認為是相等的。 這有點像 Python 中的 `is` 和 C 中的指針比較。 **注意:**為了更直觀的看到`==`和`===`的區別,可以參見[JavaScript Equality Table](http://dorey.github.io/JavaScript-Equality-Table/) ### 結論 強烈推薦使用**嚴格等于操作符**。如果類型需要轉換,應該在比較之前[顯式](#types.casting)的轉換, 而不是使用語言本身復雜的強制轉換規則。 ## `typeof` 操作符 `typeof` 操作符(和 [`instanceof`](#types.instanceof) 一起)或許是 JavaScript 中最大的設計缺陷, 因為幾乎不可能從它們那里得到想要的結果。 盡管 `instanceof` 還有一些極少數的應用場景,`typeof` 只有一個實際的應用(**[譯者注](http://cnblogs.com/sanshi/):**這個實際應用是用來檢測一個對象是否已經定義或者是否已經賦值), 而這個應用卻**不是**用來檢查對象的類型。 **注意:** 由于 `typeof` 也可以像函數的語法被調用,比如 `typeof(obj)`,但這并不是一個函數調用。 那兩個小括號只是用來計算一個表達式的值,這個返回值會作為 `typeof` 操作符的一個操作數。 實際上**不存在**名為 `typeof` 的函數。 ### JavaScript 類型表格 ``` Value Class Type ------------------------------------- "foo" String string new String("foo") String object 1.2 Number number new Number(1.2) Number object true Boolean boolean new Boolean(true) Boolean object new Date() Date object new Error() Error object [1,2,3] Array object new Array(1, 2, 3) Array object new Function("") Function function /abc/g RegExp object (function in Nitro/V8) new RegExp("meow") RegExp object (function in Nitro/V8) {} Object object new Object() Object object ``` 上面表格中,_Type_ 一列表示 `typeof` 操作符的運算結果。可以看到,這個值在大多數情況下都返回 "object"。 _Class_ 一列表示對象的內部屬性 `[[Class]]` 的值。 **JavaScript 標準文檔中定義:** `[[Class]]` 的值只可能是下面字符串中的一個: `Arguments`, `Array`, `Boolean`, `Date`, `Error`, `Function`, `JSON`, `Math`, `Number`, `Object`, `RegExp`, `String`. 為了獲取對象的 `[[Class]]`,我們需要使用定義在 `Object.prototype` 上的方法 `toString`。 ### 對象的類定義 JavaScript 標準文檔只給出了一種獲取 `[[Class]]` 值的方法,那就是使用 `Object.prototype.toString`。 ``` function is(type, obj) { var clas = Object.prototype.toString.call(obj).slice(8, -1); return obj !== undefined && obj !== null && clas === type; } is('String', 'test'); // true is('String', new String('test')); // true ``` 上面例子中,`Object.prototype.toString` 方法被調用,[this](#function.this) 被設置為了需要獲取 `[[Class]]` 值的對象。 **[譯者注](http://cnblogs.com/sanshi/):**`Object.prototype.toString` 返回一種標準格式字符串,所以上例可以通過 `slice` 截取指定位置的字符串,如下所示: ``` Object.prototype.toString.call([]) // "[object Array]" Object.prototype.toString.call({}) // "[object Object]" Object.prototype.toString.call(2) // "[object Number]" ``` **ES5 提示:** 在 ECMAScript 5 中,為了方便,對 `null` 和 `undefined` 調用 `Object.prototype.toString` 方法, 其返回值由 `Object` 變成了 `Null` 和 `Undefined`。 **[譯者注](http://cnblogs.com/sanshi/):**這種變化可以從 IE8 和 Firefox 4 中看出區別,如下所示: ``` // IE8 Object.prototype.toString.call(null) // "[object Object]" Object.prototype.toString.call(undefined) // "[object Object]" // Firefox 4 Object.prototype.toString.call(null) // "[object Null]" Object.prototype.toString.call(undefined) // "[object Undefined]" ``` ### 測試為定義變量 ``` typeof foo !== 'undefined' ``` 上面代碼會檢測 `foo` 是否已經定義;如果沒有定義而直接使用會導致 `ReferenceError` 的異常。 這是 `typeof` 唯一有用的地方。 ### 結論 為了檢測一個對象的類型,強烈推薦使用 `Object.prototype.toString` 方法; 因為這是唯一一個可依賴的方式。正如上面表格所示,`typeof` 的一些返回值在標準文檔中并未定義, 因此不同的引擎實現可能不同。 除非為了檢測一個變量是否已經定義,我們應盡量避免使用 `typeof` 操作符。 ## `instanceof` 操作符 `instanceof` 操作符用來比較兩個操作數的構造函數。只有在比較自定義的對象時才有意義。 如果用來比較內置類型,將會和 [`typeof` 操作符](#types.typeof) 一樣用處不大。 ### 比較自定義對象 ``` function Foo() {} function Bar() {} Bar.prototype = new Foo(); new Bar() instanceof Bar; // true new Bar() instanceof Foo; // true // 如果僅僅設置 Bar.prototype 為函數 Foo 本身,而不是 Foo 構造函數的一個實例 Bar.prototype = Foo; new Bar() instanceof Foo; // false ``` ### `instanceof` 比較內置類型 ``` new String('foo') instanceof String; // true new String('foo') instanceof Object; // true 'foo' instanceof String; // false 'foo' instanceof Object; // false ``` 有一點需要注意,`instanceof` 用來比較屬于不同 JavaScript 上下文的對象(比如,瀏覽器中不同的文檔結構)時將會出錯, 因為它們的構造函數不會是同一個對象。 ### 結論 `instanceof` 操作符應該**僅僅**用來比較來自同一個 JavaScript 上下文的自定義對象。 正如 [`typeof`](#types.typeof) 操作符一樣,任何其它的用法都應該是避免的。 ## 類型轉換 JavaScript 是_弱類型_語言,所以會在**任何**可能的情況下應用_強制類型轉換_。 ``` // 下面的比較結果是:true new Number(10) == 10; // Number.toString() 返回的字符串被再次轉換為數字 10 == '10'; // 字符串被轉換為數字 10 == '+10 '; // 同上 10 == '010'; // 同上 isNaN(null) == false; // null 被轉換為數字 0 // 0 當然不是一個 NaN(譯者注:否定之否定) // 下面的比較結果是:false 10 == 010; 10 == '-10'; ``` **ES5 提示:** 以 `0` 開頭的數字字面值會被作為八進制數字解析。 而在 ECMAScript 5 嚴格模式下,這個特性被**移除**了。 為了避免上面復雜的強制類型轉換,**強烈**推薦使用[嚴格的等于操作符](#types.equality)。 雖然這可以避免大部分的問題,但 JavaScript 的弱類型系統仍然會導致一些其它問題。 ### 內置類型的構造函數 內置類型(比如 `Number` 和 `String`)的構造函數在被調用時,使用或者不使用 `new` 的結果完全不同。 ``` new Number(10) === 10; // False, 對象與數字的比較 Number(10) === 10; // True, 數字與數字的比較 new Number(10) + 0 === 10; // True, 由于隱式的類型轉換 ``` 使用內置類型 `Number` 作為構造函數將會創建一個新的 `Number` 對象, 而在不使用 `new` 關鍵字的 `Number` 函數更像是一個數字轉換器。 另外,在比較中引入對象的字面值將會導致更加復雜的強制類型轉換。 最好的選擇是把要比較的值**顯式**的轉換為三種可能的類型之一。 ### 轉換為字符串 ``` '' + 10 === '10'; // true ``` 將一個值加上空字符串可以輕松轉換為字符串類型。 ### 轉換為數字 ``` +'10' === 10; // true ``` 使用**一元**的加號操作符,可以把字符串轉換為數字。 **[譯者注](http://cnblogs.com/sanshi/):**字符串轉換為數字的常用方法: ``` +'010' === 10 Number('010') === 10 parseInt('010', 10) === 10 // 用來轉換為整數 +'010.2' === 10.2 Number('010.2') === 10.2 parseInt('010.2', 10) === 10 ``` ### 轉換為布爾型 通過使用 **否** 操作符兩次,可以把一個值轉換為布爾型。 ``` !!'foo'; // true !!''; // false !!'0'; // true !!'1'; // true !!'-1' // true !!{}; // true !!true; // true ```
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看