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

                ThinkChat2.0新版上線,更智能更精彩,支持會話、畫圖、視頻、閱讀、搜索等,送10W Token,即刻開啟你的AI之旅 廣告
                ## 一、數據類型 JS分兩種數據類型: > **基本數據類型**:**Number、String、Boolean、Null、?Undefined、Symbol(ES6),**這些類型可以直接操作保存在變量中的實際值。 > >**引用數據類型**:**Object(在JS中除了基**本**數據類型以外的都是對象,數據是對象,函數是對象,正則表達式是對象)** ## 1、基本數據類型(六種)存放在棧中 >基本數據類型是指存放在**棧**中的**簡單數據段,數據大小確定,內存空間大小可以分配,**它們是直接按值存放的,所以可以直接**按值訪問** * 1、`Number`數值類型 `Number`類型包含整數和浮點數(浮點數數值必須包含一個小數點,且小數點后面至少有一個數字)兩種值 >注意:在js中浮點數的精度是17位,計算是二進制的計算數 據,所以得到的不是整數 ``` var num1 = 0.1; var num2 = 0.2; console.log(num1 + num2); //0.30000000000000004 ``` `NaN`:非數字類型,屬于數值型基本數據類型 >特點: 1):設計任何的NaN操縱都會返回NaN `console.log('ab'/10); ` // NaN 2) NaN不等于自身。 `console.log(NaN == NaN);// false;` 判斷是否是`Number`類型 >1、`isNaN`:判斷是否是一個非數字類型,傳入的非數字類型,返回`true`,否則返回`false` >注意:傳入的參數首先會被轉化為數值,如果參數類型為對象類型,先調用`valueOf()`方法,再確定該方法返回的值是否可以轉換為數值類型,如果不能,再調用`toString()`方法,再確定返回值 2、`typeof` `console.log(typeof 12)` //Number 數值類型的轉換: `Number()`:可以用于任何的數據類型 `parseInt`:提取 整數數值 `paseFloat`:提取浮點數值 * 2、`String` 字符串類型 >特點: 1、字符串的單引號和雙引號作用效果一樣 2、字符串有`length`屬性,可以取得字符串的長度 3、字符串的值是不可變的,所以很多的字符串的`api`不會改變原字符串值 >字符串轉換: `String()`:適用于任何的數據類型(null -> null undefined -> undefined) `toString()`:`null`和`undefined`沒有這個功能 `console.log(null.toString()); //error 報錯` * 3、`Boolean` 布爾類型 該類型只有兩個值:`true`、`false` ``` 轉換為`boolean`: `Boolean()` Boolean(undefined):false Boolean(null):false Boolean(非空對象包括空數組[]和空對象{}):true Boolean(非0): true || Boolean(0和NaN):false Boolean(非空包括空格字符串):true || Boolean(''):false [注意]true不一定等于1,false也不一定等于0 ``` 出現場景: (1)條件語句導致執行的隱士類轉換 (2)字面量或變量定義 ``` 類型轉換: Number(true): 1     ||   Number(false) : 0 String(true):'true'     ?||   String(false):'false' ``` * 4、`Null` 空對象指針類型 如果定了一個對象,初始化可以為null,因為null的基本類型是`Null`,在`if`語句中默認轉化為`false`,在和數值計算默認為`0` 出現場景:對象不存在 ``` 類型轉換: Booleam(null) false Number(num) 0 String(null) 'null' ``` `Number(null) // 0` * 5、`Undefined` 申明了變量但是沒有初始化,默認為`undefined`,在`if`語句中默認轉化為`false`, >`undefined`:表示‘缺少值’,就是應該有一個值,但是沒有定義,以下用法是典型的出現`undefined`情況 (1)變量被申明,等于`undefined` (2)調用函數時,應該提供的參數沒有提供,該參數等于`undefined` (3)對象沒有賦值的屬性,該屬性值為`undefined` (4)函數沒有返回值,默認返回`undefined` ``` 類型轉換: Boolean(undefined): ?false Number(undefined): ?NaN String(undefined):  'undefined' ``` * 6、`Symbol` `ES6`新增的一個基本數據類型,表示唯一性 ``` let id1 = Symbol('id'); let id2 = Symbol('id'); console.log(id1 == id2); //false ``` `Symbol`屬性類型不支持`for...in `和`Object.keys()` ``` let id = Symbol("id"); let obj = { [id]:'symbol' }; for(let option in obj){ console.log(obj[option]); //空 } ``` 但是也能有方法去訪問:`Object.getOwnPropertySymbols` 方法會返回一個數組,成員是當前對象的所有用作屬性名的 Symbol 值。 ``` console.log(Object.getOwnPropertySymbols(obj)) // [?Symbol(c)?] ``` * 介紹兩個`Symbol.for` 和 `Symbol.keyFor` (1)、`Symbol.for` :方法根據給到的鍵`key`來運行時的`symbol`注冊表中找到對應的`symbol`,如果找到了,則返回它,否則新增一個與該鍵關聯的`symbol`,并放入全局的`symbol`,這個Symbol值可以是被二次用到的 返回值: 返回由給定的 key 找到的 symbol,否則就是返回新創建的 symbol。 ``` Symbol.for("foo"); // 創建一個 symbol 并放入 symbol 注冊表中,鍵為 "foo" Symbol.for("foo"); // 從 symbol 注冊表中讀取鍵為"foo"的 symbol Symbol.for("bar") === Symbol.for("bar"); // true,證明了上面說的 Symbol("bar") === Symbol("bar"); // false,Symbol() 函數每次都會返回新的一個 symbol 為了防止沖突,最好給你要放入 symbol 注冊表中的 symbol 帶上鍵前綴。 Symbol.for("mdn.foo"); Symbol.for("mdn.bar"); ``` (2)、`Symbol.keyFor` 方法用來獲取 symbol 注冊表中與某個 symbol 關聯的鍵。 ``` var globalSym = Symbol.for("foo"); Symbol.keyFor(globalSym); // "foo" ``` ## 2、引用數據類型 引用數據類型也叫對象數據類型,包括`function`,`object`,`array`,`date`,`RegExp`等可以可以使用new創建的數據,又叫對象類型,他們是存放在**堆**(heap)**內存**中的數據 特點: > * 引用類型的值可以改變 > * 引用數據類型可以添加屬性和方法 > * 引用數據類型的賦值是對象引用 > * 引用類型的比較是引用的比較 > * 引用類型是同時保存在棧區中和堆區中的,引用類型的存儲需要在內存的棧區和堆區中共同完成,棧區保存變量標識符和指向堆內存的地址 注意:在引用類型賦值時對象的引用,所以從一個變量向另一個變量賦值引用類型的值時,同樣會將存在在變量中的對象的值賦值一份到新的變量分配的空間,引用類型保存在變量中的時對象在堆存在的地址,所以與基本數據類型的簡單賦值不同,這個值的副本實際上時一個指針,而這個指針指向儲存在堆內存的一個對象,那么賦值操作后,兩個變量都保存了同一個對象的地址,而這個地址都指向同一個對象,因此改變其中任何一個變量,都會影響 ![](https://img.kancloud.cn/94/9b/949bd62bd70cb9e38b83d5e7aeeb390e_774x312.png) 在ECMAScript中,Object類型是所有它的實例的基礎 `Object`的每個實例都具有下列的屬性和方法: * constructor:構造函數 * hasOwnProperty(proertyName) 用于檢查給定的屬性在當前對象實例(而不是實例的原型)中是否存在。 * isPropertyOf(Object) 用于檢查其原型鏈的對象是否存在于指定對象的實例中,是則返回true,否則返回false。 ``` var a = {} function Person() {} var p1 = new Person() // 繼承自原來的原型,但現在已經無法訪問 var Person.prototype = a var p2 = new Person() // 繼承a console.log(a.isPrototypeOf(p1)) // false a是不是p1的原型 console.log(a.isPrototypeOf(p2)) // true a是不是p2的原型 console.log(Object.prototype.isPrototypeOf(p1)) // true console.log(Object.prototype.isPrototypeOf(p2)) // true ``` * propertyIsEnumerable(propertyName) 用于檢查給定的屬性是否可以用 for-in 語句進行枚舉。 * toLocaleString() 返回對象的字符串表示,該字符串與執行環境的地區對應。 * toString() 返回對象的字符串表示。 * valueOf() 返回對象的字符串、數值、布爾值表示。通常與toString()方法的返回值相同。 ![](https://img.kancloud.cn/84/ca/84ca4284a2076a450c57bc9e40328a5e_442x397.png) 拓展:聲明對象的幾種方式 ``` <script> //內置函數 var obj1=new Object(); obj1.name="zhuyu"; obj1.age=21; obj1.uni=function(){ console.log(this.name+this.age); } console.log(obj1); obj1.uni(); //字面量 var obj2={ name:"zhuyu2", age:21, uni2:function(){ console.log(this.name+this.age) } } console.log(obj2); obj2.uni2(); // 自定義函數 function Obj(name,age){ this.name=name; this.age=age; this.uni3=function(){ console.log(this.name+this.age) } } var obj3=new Obj("zhuyu3",21); console.log(obj3); obj3.uni3(); // Es6類 class Obj2{ constructor(name,age){ this.name=name; this.age=age; } uni4(){ console.log(this.name+this.age) } } var obj4=new Obj2("zhuyu4",21); console.log(obj4); obj4.uni4(); //使用Object.create() var person={ image:"true", uni5:function(){ console.log(`名字是${this.name},年齡是${this.age}`); } } var obj5=Object.create(person); obj5.name="zhuyu5"; obj5.age=21; obj5.image=false; obj5.uni5(); console.log(obj5) </script> ``` ## 3、基本數據類型和引用數據類型的區別 **總結基本數據類型和引用數據類型區別** **1、聲明變量時內存分配不同**  *原始類型:在棧中,因為占據空間是固定的,可以將他們存在較小的內存中-棧中,這樣便于迅速查詢變量的值 ![](https://img.kancloud.cn/46/e4/46e42d38099492fdbbd8ff61e3c52399_544x222.png)  *引用類型:存在堆中,棧中存儲的變量,只是用來查找堆中的引用地址。 ![](https://img.kancloud.cn/13/d9/13d9c998c52de5f3410f1ba5186bd5f9_577x513.png) ![](https://img.kancloud.cn/d8/cb/d8cb74eeab07843c29ffb6f0ecd5ef8d_800x643.png)  ? ?這是因為:引用值的大小會改變,所以不能把它放在棧中,否則會降低變量查尋的速度。相反,放在變量的棧空間中的值是該對象存儲在堆中的地址。地址的大小是固定的,所以把它存儲在棧中對變量性能無任何負面影響 **2、不同的內存分配帶來不同的訪問機制** ? ??在javascript中是不允許直接訪問保存在堆內存中的對象的,所以在訪問一個對象時,首先得到的是這個對象在堆內存中的地址,然后再按照這個地址去獲得這個對象中的值,這就是傳說中的**按引用訪問**。 ? ? 而原始類型的值則是可以直接訪問到的。 **3、復制變量時的不同** ?1)原始值:在將一個保存著原始值的變量復制給另一個變量時,會將原始值的副本賦值給新變量,**此后這兩個變量是完全獨立的,他們只是擁有相同的value而已。** 2)引用值:在將一個保存著對象內存地址的變量復制給另一個變量時,會把這個內存地址賦值給新變量,     也就是說這兩個變量都指向了堆內存中的同一個對象,他們中任何一個作出的改變都會反映在另一個身上。     (這里要理解的一點就是,復制對象時并不會在堆內存中新生成一個一模一樣的對象,只是多了一個保存指向這個對象指針的變量罷了)。**多了一個指針** 淺拷貝: ![](https://img.kancloud.cn/ac/df/acdf1e6b5fba88c52d6abc11bc303782_440x290.png) 深拷貝: ![](https://img.kancloud.cn/73/1c/731c901e7c5fe3ddc1531d41774ae695_440x290.png) **4、**參數傳遞的不同(**把實參復制給形參的過程**)**** 首先我們應該明確一點:ECMAScript中所有函數的參數都是按值來傳遞的。   但是為什么涉及到原始類型與引用類型的值時仍然有區別呢?還不就是因為內存分配時的差別。     1)原始值:只是把變量里的值傳遞給參數,之后參數和這個變量互不影響。   2)引用值:對象變量它里面的值是這個對象在堆內存中的內存地址,這一點你要時刻銘記在心!     因此它傳遞的值也就是這個內存地址,這也就是為什么函數內部對這個參數的修改會體現在外部的原因了,因為它們都指向同一個對象。 ## 4、檢測類型 * 法一:`typeof` >最基本的判斷方式,該操作符返回一個表示數據類型的字符串,`number`、`string`、`boolean`、`object`、`function`、`undefined`、`symbol` 1. 'undefined'? ? ? ? ? ? ? --未定義的變量或值 2. 'boolean'? ? ? ? ? ? ? ? ?--布爾類型的變量或值 3. 'string'? ? ? ? ? ? ? ? ? ? ?--字符串類型的變量或值 4. 'number'? ? ? ? ? ? ? ? ??--數字類型的變量或值 5. 'object'? ? ? ? ? ? ? ? ? ? --對象類型的變量或值,或者null(這個是js歷史遺留問題,將null作為object類型處理) 6. 'function'? ? ? ? ? ? ? ? ?--函數類型的變量或值 ? ? ? ? ``` console.log(typeof a);? ? //'undefined' ? ??console.log(typeof(true));? //'boolean' ? ? console.log(typeof '123');? //'string' ? ? console.log(typeof 123);? ?//'number' ? ??console.log(typeof NaN);? ?//'number' ? ? console.log(typeof null);? //'object'? ?? ? ? var obj = new String(); ? ? console.log(typeof(obj));? ? //'object' ? ? var? fn = function(){}; ? ? console.log(typeof(fn));? //'function' ? ??console.log(typeof(class c{}));? //'function' ``` * 法二:`instanceof` >**運算符用來測試一個對象在其原型鏈中是否存在一個構造函數的?`prototype`?屬性** 語法:`object instanceof constructor` (1)基礎類型 ``` let num = 1 num instanceof Number // false num = new Number(1) num instanceof Number // true ``` 這兩個都是一樣的數值,為什么不一樣? 因為instanceof 檢測的是:檢測目標的`__proto__`與構造函數`prototype`,相同返回true,不同返回false,對于`string`、`boolean`是一樣的 注意: ``` new String(1) // String?{"1"} String(1) // "1" ``` (2) 繼承關系的用法 ``` // 判斷 foo 是否是 Foo 類的實例 , 并且是否是其父類型的實例 function Aoo(){} function Foo(){} Foo.prototype = new Aoo();//JavaScript 原型繼承 var foo = new Foo(); console.log(foo instanceof Foo)//true console.log(foo instanceof Aoo)//true ``` (3) 復雜類型 ``` let arr = [] arr instanceof Array // true arr instanceof Object // true Array.isArray(arr) // true ``` 注意: `(new Number(1)) instanceof Object // true` (4) 其他類型 ``` let reg = new RegExp(//) reg instanceof RegExp // true reg instanceof Object // true let date = new Date() date instanceof Date // true date instanceof Object // true ``` 但是`Fuction`不一樣 ``` function A() {} let a = new A() a instanceof Function // false a instanceof Object // true A instanceof Function // true ``` -->分析`a`為什么不是? >* a是new出來,所以是經過構造,因此已經是對象,不再是函數,所以false。 >* a是經過構造的對象,返回ture沒問題。 > * 如上所述,A是個函數,因此沒什么概念上的問題。但是要知道`A.__proto__`即`Function.prototype`是`? () { [native code] }`,這是與object以后處于原型鏈上層的存在,而且與object平級: ``` let obj = {} obj.__proto__ // {constructor: ?, __defineGetter__: ?, __defineSetter__: ?, hasOwnProperty: ?, __lookupGetter__: ?,?…} obj.__proto__.prototype // undefined let A = function() {} A.__proto__ // ? () { [native code] } A.__proto__.prototype // undefined ``` ![](https://img.kancloud.cn/93/43/9343106669debaf28f0dbf11206c40b6_1080x417.png)
                  <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>

                              哎呀哎呀视频在线观看