<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>

                合規國際互聯網加速 OSASE為企業客戶提供高速穩定SD-WAN國際加速解決方案。 廣告
                ## 11 值 > 原文: [http://exploringjs.com/impatient-js/ch_values.html](http://exploringjs.com/impatient-js/ch_values.html) > > 貢獻者:[lq920320](https://github.com/lq920320) 在本章中,我們將研究 JavaScript 具有哪些值。 ![](https://img.kancloud.cn/83/6f/836f0345de4fda5b9b81d7038ebb276d.svg) **支持工具:`===`** 在本章中,我們偶爾會使用嚴格相等運算符。如果`a`和`b`相等,`a === b`結果為`true`。具體含義在[12.4 嚴格相等](/docs/15.md#124平等與)詳細解釋。 ### 11.1 什么是類型? 在本章中,我將類型視為值的集合。例如,類型 `boolean` 是集 {`false`,`true`} 。 ### 11.2 JavaScript 的類型層次結構 ![Figure 6: A partial hierarchy of JavaScript’s types. Missing are the classes for errors, the classes associated with primitive types, and more. The diagram hints at the fact that not all objects are instances of Object.](https://img.kancloud.cn/50/5e/505e0abfbb0e1099651698da61e9b156.svg) 圖 6: JavaScript 類型的部分層次結構。缺少的是錯誤類,與基元類型相關的類等等。此圖暗示了并非所有的對象都是 `Object` 的實例。 圖 [6](#fig:type_hierarchy) 顯示了 JavaScript 的類型層次結構。我們從該圖中學到了什么? - JavaScript 區分兩種值:原始值和對象。我們很快就會看到有什么區別。 - 該圖區分了類 `Object` 的對象和實例。 `Object` 的每個實例也是一個對象,但反之亦然。但是,實際上你在實踐中遇到的所有對象都是 `Object` 的實例。例如,通過對象字面值創建的對象。關于該主題的更多細節在[26.4.3.4 對象并非 `Object` 的實例](/docs/32.md#26434-不是object實例的對象)中進行解釋。 ### 11.3 語言規范的類型 ECMAScript 規范已知的總共 7 種類型。這些類型的名稱是(我使用 TypeScript 的名稱,而不是規范的名稱): - `undefined`:唯一元素`undefined`。 - `null`:唯一元素`null`。 - `boolean`:包含`false`和`true`元素。 - `number`:所有數字的類型(例如`-123`,`3.141`)。 - `string`:所有字符串的類型(例如`'abc'`)。 - `symbol`:所有符號的類型(例如`Symbol('My Symbol')`)。 - `object`:所有對象的類型(與`Object`不同,類`Object`及其子類的所有實例的類型)。 ### 11.4 原始值與對象 規范對值進行了重要區分: - *原始值*是`undefined`,`null`,`boolean`,`number`,`string`,`symbol`類型的元素。 - 所有其他值都是*對象*。 與 Java 相比(啟發了 JavaScript 語言),原始值不是二等公民。它們和對象之間的區別更加微妙。簡而言之,它是: - 原始值:是 JavaScript 中的原子數據塊。 - 它們是*值傳遞的*:當原始值分配給變量或傳遞給函數時,它們的內容被復制。 - 它們*按值*進行比較:比較兩個原始值時,比較它們的內容。 - 對象:是復合數據。 - 它們是*通過標識*(我的術語)傳遞:當對象被分配給變量或傳遞給函數時,它們的*標識*(想一下指針)被復制。 - 它們是*通過標識*(我的術語)進行比較的:當比較兩個對象時,他們的標識進行比較。 除此之外,原始值和對象非常相似:它們都具有*屬性*(鍵值條目),并且可以在相同的位置使用。 接下來,我們將更深入地研究原始值和對象。 #### 11.4.1 原始值(簡稱:基元) ##### 11.4.1.1 原始值是不可改變的 您無法更改,添加或刪除基元的屬性: ```js let str = 'abc'; assert.equal(str.length, 3); assert.throws( () => { str.length = 1 }, /^TypeError: Cannot assign to read only property 'length'/ ); ``` ##### 11.4.1.2 原始值的*值傳遞* 基元是*值傳遞的*:變量(包括參數)存儲基元的內容。將原始值分配給變量或將其作為參數傳遞給函數時,會復制其內容。 ```js let x = 123; let y = x; assert.equal(y, 123); ``` ##### 11.4.1.3 原始值*按值*進行比較 基元*按值*進行比較:當比較兩個原始值時,我們比較它們的內容。 ```js assert.equal(123 === 123, true); assert.equal('abc' === 'abc', true); ``` 要了解這種比較方式有什么特別之處,請繼續閱讀并找出對象的比較方式。 #### 11.4.2 對象 對象的內容將會在[第25章 “單個對象”](/docs/31.md#25單個對象)以及接下來的介紹更多細節。這里我們主要集中于其與原始值有哪些不同。 讓我們首先探討創建對象的兩種常見方法: - 對象值: ```js const obj = { first: 'Jane', last: 'Doe', }; ``` 對象的值以花括號`{}`開頭和結尾。它創建了一個具有兩個屬性的對象。第一個屬性具有鍵`'first'`(字符串)和值`'Jane'`。第二個屬性具有鍵`'last'`和值`'Doe'`。有關對象字值的更多信息,請參閱[25.2.1 對象值:屬性](/docs/31.md#2521對象字面值屬性)的章節。 - 數組值: ```js const arr = ['foo', 'bar']; ``` Array 值以方括號`[]`開頭和結尾。它創建了一個帶有兩個*元素*的數組:`'foo'`和`'bar'`。有關數組值的更多信息,請參閱[28.2.1 創建、讀取、寫入數組](/docs/35.md#2821數組創建閱讀寫作)。 ##### 11.4.2.1 默認情況下,對象是可變的 默認情況下,您可以自由更改,添加和刪除對象的屬性: ```js const obj = {}; obj.foo = 'abc'; // 添加一個屬性 assert.equal(obj.foo, 'abc'); obj.foo = 'def'; // 改變某個屬性的值 assert.equal(obj.foo, 'def'); ``` ##### 11.4.2.2 對象是*通過標識傳遞* 對象是*通過標識傳遞*(我的術語):變量(包括參數)存儲對象的*標識*。 對象的標識就像是*堆*(想一下 JavaScript 引擎的共享主內存)上的對象實際數據的指針(或透明引用)。 將對象分配給變量或將其作為參數傳遞給函數時,會復制其標識。每個對象字面值在堆上創建一個新對象并返回其標識。 ```js const a = {}; // fresh empty object // Pass the identity in `a` to `b`: const b = a; // Now `a` and `b` point to the same object // (they “share” that object): assert.equal(a === b, true); // Changing `a` also changes `b`: a.foo = 123; assert.equal(b.foo, 123); ``` JavaScript 使用*垃圾回收*自動管理內存: ```js let obj = { prop: 'value' }; obj = {}; ``` 現在`obj`的舊值`{ prop: 'value' }`是*垃圾*(不再使用)。在某個時間點(如果有足夠的可用內存,可能永遠不會), JavaScript 會自動將它進行*垃圾回收*(從內存中刪除)。 > ![](https://img.kancloud.cn/7b/17/7b17729df07100ffa1c582a9b46ac13a.svg) **詳情:通過身份傳遞** > > “通過標識傳遞”意味著對象(透明引用)的標識按值傳遞。這種方法也稱為[“通過共享傳遞”](https://en.wikipedia.org/wiki/Evaluation_strategy#Call_by_sharing)。 ##### 11.4.2.3 通過標識比較對象 *通過標識*(我的術語)比較對象:如果兩個變量包含相同的對象標識,則它們僅相等。如果它們引用具有相同內容的不同對象,則它們不相等。 ```js const obj = {}; // fresh empty object assert.equal(obj === obj, true); // same identity assert.equal({} === {}, false); // different identities, same content ``` ### 11.5 運算符`typeof`和`instanceof`:值的類型是什么? `typeof`和`instanceof`這兩個運算符可以確定給定值`x`的類型: ```js if (typeof x === 'string') ··· if (x instanceof Array) ··· ``` 他們有什么不同? - `typeof` 區分規范的 7 種類型(減去一個遺漏,加上一個補充)。 - `instanceof` 測試哪個類創建了給定值。 > ![](https://img.kancloud.cn/9c/53/9c5358c6578dee8dea3427be5bbd7f12.svg) **經驗法則:`typeof`用于原始值,`instanceof`用于對象** #### 11.5.1 `typeof` 表 2: `typeof` 操作符的結果集 | `x` | `typeof x` | | --- | --- | | `undefined` | `'undefined'` | | `null` | `'object'` | | 布爾值 | `'boolean'` | | 數字 | `'number'` | | 字符串 | `'string'` | | 符號 | `'symbol'` | | 函數 | `'function'` | | 所有其他對象 | `'object'` | 表 [2](#tbl:typeof-results) 列出`typeof`的所有結果。它們大致對應于語言規范的 7 種類型。唉,有兩個不同之處,它們是語言怪癖: - `typeof null` 返回 `'object'` 而不是`'null'`。那是一個錯誤。不幸的是,它無法修復。 TC39 嘗試這樣做,但它在網絡上打破了太多代碼。 - 函數的`typeof`應該是`'object'`(函數是對象)。為功能引入單獨的類別令人困惑。 > ![](https://img.kancloud.cn/3e/d5/3ed5755d562179ae6c199264f5e21157.svg) **練習:`typeof`** 的兩個練習 > > - `exercises/operators/typeof_exrc.js` > - 額外:`exercises/operators/is_object_test.js` #### 11.5.2 `instanceof` 該運算符回答了問題:是否有一個類`C`創建了值`x`? ```js x instanceof C ``` 例如: ```js > (function() {}) instanceof Function true > ({}) instanceof Object true > [] instanceof Array true ``` 原始值不是任何實例: ```js > 123 instanceof Number false > '' instanceof String false > '' instanceof Object false ``` > ![](https://img.kancloud.cn/3e/d5/3ed5755d562179ae6c199264f5e21157.svg) **練習:`instanceof`** > > `exercises/operators/instanceof_exrc.js` ### 11.6 類和構造函數 JavaScript 的對象原始工廠是*構造函數*:如果通過 `new` 操作符調用它們,則返回自身的“實例”的普通函數。 ES6 引入了構造函數最好的語法,*類*。 在本書中,我可以互換地使用術語*構造函數*和*類*。 類可以看作是將規范的單一類型 `object` 劃分為子類型——它們給出了比規范中有限的 7 種類型更多的類型。每個類都是由它創建的對象的類型。 #### 11.6.1 與基本類型關聯的構造函數 每個基本類型(`undefined`和`null`的規范內部類型除外)都有一個關聯的*構造函數*(想一下類): - 構造函數`Boolean`與布爾值相關聯。 - 構造函數`Number`與數字相關聯。 - 構造函數`String`與字符串相關聯。 - 構造函數`Symbol`與符號相關聯。 每個函數都扮演著幾個角色。例如,`Number`: - 可以將其用作函數并將值轉換為數字: ```js assert.equal(Number('123'), 123); ``` - `Number.prototype`提供數字的屬性。例如,方法`.toString()`: ```js assert.equal((123).toString, Number.prototype.toString); ``` - `Number`是數字工具函數的命名空間/容器對象。例如: ```js assert.equal(Number.isInteger(123), true); ``` - 最后,你還可以將`Number`用作類并創建數字對象。這些對象與實數不同,應該避免。 ```js assert.notEqual(new Number(123), 123); assert.equal(new Number(123).valueOf(), 123); ``` ##### 11.6.1.1 包裝原始值 與基本類型相關的構造函數也稱為*包裝類型*,因為它們提供了將原始值轉換為對象的規范方法。在此過程中,原始值被“包裝”在對象中。 ```js const prim = true; assert.equal(typeof prim, 'boolean'); assert.equal(prim instanceof Boolean, false); const wrapped = Object(prim); assert.equal(typeof wrapped, 'object'); assert.equal(wrapped instanceof Boolean, true); assert.equal(wrapped.valueOf(), prim); // unwrap ``` 包裝在實踐中很少有用,但它在語言規范內部使用,以提供原語屬性。 ### 11.7 在類型之間轉換 在 JavaScript 中,有兩種方法可以將值轉換為其他類型: - 顯式轉換:通過`String()`等功能。 - *強制*(自動轉換):當操作接收到無法使用的操作數/參數時發生。 #### 11.7.1 類型之間的顯式轉換 與基本類型關聯的(構造)函數顯式地將值轉換為該類型: ```js > Boolean(0) false > Number('123') 123 > String(123) '123' ``` 你還可以使用`Object()`將值轉換為對象: ```js > typeof Object(123) 'object' ``` #### 11.7.2 強制(類型之間的自動轉換) 對于許多操作,如果操作數/參數的類型不匹配,JavaScript 會自動轉換它們。這種自動轉換稱為*強制*。 例如,乘法運算符將其操作數強制轉換為數字: ```js > '7' * '3' 21 ``` 許多內置函數也強制執行。例如,`parseInt()`將其參數強制轉換為字符串(解析在第一個不是數字的字符處停止): ```js > parseInt(123.45) 123 ``` > ![](https://img.kancloud.cn/3e/d5/3ed5755d562179ae6c199264f5e21157.svg) **練習:將值轉換為基元** > > `exercises/values/conversion_exrc.js` >![](https://img.kancloud.cn/ff/a8/ffa8e16628cad59b09c786b836722faa.svg) **測驗** > > 參見[測驗應用程序](/docs/11.md#91測驗)。
                  <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>

                              哎呀哎呀视频在线观看